---
source: https://carbone.io/documentation/developer/api-sdks/python.html
title: "Generate documents and reports with Python SDK"
description: "Generate report with Python"
generated_at: "2026-07-13"
---

# Python SDK

Generate report with Python

Python SDK to generate reports through the [Carbone Cloud API](/documentation/quickstart/getting-started/generate-a-document.md) in a few lines of code.

The source code is available on Github: [https://github.com/carboneio/carbone-sdk-python](https://github.com/carboneio/carbone-sdk-python)

## Install

```sh
$ pip install carbone-sdk
```

## Quickstart

Try the following code to generate a report in a few seconds. Insert an API key, provide the template, and the data as a stringified JSON, that's it.

```python
import carbone_sdk

csdk = carbone_sdk.CarboneSDK("ACCESS-TOKEN")

template_path = "./path/to/template.odt"
json_data = {
  # Add the data here
  "data": {}
}

# Render and return the report as bytes and a unique report name (for example "01EEYYHV0ENQE07JCKW8BD2QRP.odt")
report_bytes, unique_report_name = csdk.render(template_path, json_data)

# Create the file
fd = open(unique_report_name, "wb")
fd.write(report_bytes)
fd.close()
```

## Constructor

```python
import carbone_sdk

# Carbone access token passed as parameter
csdk = carbone_sdk.CarboneSDK("ACCESS-TOKEN")
# Carbone access token passed as environment variable "CARBONE_TOKEN"
csdk = carbone_sdk.CarboneSDK()

# Set API URL for Carbone On-Premise for example (default: "https://api.carbone.io")
csdk.set_api_url("https://api.carbone.io")
```

Constructor to create a new instance of CarboneSDK. The access token can be passed as an argument or by the environment variable "CARBONE\_TOKEN". To set a new environment variable, use the command:

```bash
$ export CARBONE_TOKEN=your-secret-token
```

Check if it is set by running:

```bash
$ printenv | grep "CARBONE_TOKEN"
```

## Generate a report

```python
def render(self, file_or_template_id = None, json_data = None, payload = "")
```

The render function takes `file_or_template_id` the path of your local file OR a template ID, `json_data` a stringified JSON, and an optional `payload`.

It returns the report as a `bytes` and a unique report name as a `string`. Carbone engine deletes files that have not been used for a while. By using this method, if your file has been deleted, the SDK will automatically upload it again and return you the result.

When a **template file path** is passed as an argument, the function verifies if the template has been uploaded to render the report. If not, it calls [add\_template](#upload-a-template) to upload the template to the server and generate a new template ID. Then it calls [render\_report](#generate-a-report) to generate the report. If the path does not exist, an error is returned.

When a **template ID** is passed as an argument, the function renders with [render\_report](#generate-a-report) then you get the rendered file. If the template ID does not exist, an error is returned.

**Example**

```python
import carbone_sdk

csdk = carbone_sdk.CarboneSDK("your_access_token")

template_path = "./templates/invoice.docx"
json_data = {
  # Add the data here
  "data": {
    "firstname": "John",
    "lastname": "Wick",
    "price": 1000
  },
  "convertTo": "pdf"
}

# Render and return the report as bytes and a unique report name
try:
  report_bytes, unique_report_name = csdk.render(template_path, json_data)
except Exception as err:
  print("Something went wrong: {0}".format(err))

# Create the invoice report
fd = open(unique_report_name, "wb")
fd.write(report_bytes)
fd.close()
```

## Upload a template

```python
def add_template(self, template_file_name = None, payload = "")
```

Adds the template to the API and returns the response (that contains a `template_id`). You can add multiple times the same template and get a different template ID thanks to the optional `payload`.

**Example**

```python
import carbone_sdk

csdk = carbone_sdk.CarboneSDK("your_access_token")

try:
  resp = csdk.add_template('./tests/template.test.odt')
  print("Template ID: " + resp['data']['templateId'])
except Exception as err:
  print("Something went wrong: {0}".format(err))
```

## Download a template

```python
def get_template(self, template_id = None)
```

Pass a `template ID` to the function and it returns the template as `bytes`. The template ID must exist; otherwise, an error is returned by the server.

```python
import carbone_sdk

csdk = carbone_sdk.CarboneSDK("your_access_token")

try:
  f = csdk.get_template("cb03f7676ef0fbe5d7824a64676166ac2c7c789d9e6da5b7c0c46794911ee7a7")
  fd = open("template.odt", "wb")
  fd.write(f)
  fd.close()
except Exception as err:
  print("Something went wrong: {0}".format(err))
```

## Delete a template

```python
def delete_template(self, template_id = None)
```

**Example**

```python
import carbone_sdk

csdk = carbone_sdk.CarboneSDK("your_access_token")

try:
  resp = csdk.delete_template("template_id")
  print(resp)
except Exception as err:
  print("Something went wrong: {0}".format(err))
```

## Generate a template ID

```python
def generate_template_id(self, template_file_name = None, payload = "")
```

The Template ID is predictable and idempotent, pass the template path and it will return the `template_id`. You can get a different template ID thanks to the optional `payload`.

## API Token

```python
def set_access_token(self, api_token = None)
```

It sets the Carbone access token.

## Carbone API version

```python
def set_api_version(self, api_version = None)
```

It sets the Carbone version requested. By default, it is calling the version `2` of Carbone.

_Note:_ You can only set a major version of carbone.

## Related topics

- [Rust SDK](/documentation/developer/api-sdks/rust.md)
- [PHP SDK](/documentation/developer/api-sdks/php.md)
- [NodeJS SDK](/documentation/developer/api-sdks/nodejs.md)
- [Javascript SDK](/documentation/developer/api-sdks/javascript.md)
- [Java SDK](/documentation/developer/api-sdks/java.md)
- [Go SDK](/documentation/developer/api-sdks/go.md)
