# Boto3 Python SDK

[<mark style="color:blue;">Boto3</mark>](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html) is the official AWS SDK for Python. It lets you create, update, and configure <code class="expression">space.vars.ionos\_cloud\_object\_storage</code> objects within your Python scripts.

## Configuration

* Install the latest Boto3 release via `pip`: `pip install boto3`.

{% hint style="warning" %}
**Note:** Amazon extended the interface of the `PutObject` operation and made it the default in the AWS SDK for Python (Boto3) from version `1.36.0` onwards. However, the <code class="expression">space.vars.ionos\_cloud\_object\_storage</code> service does not yet support this change.

To avoid an error that occurs (InvalidTrailer) when calling the `PutObject` operation: "Invalid trailing header names in x-amz-trailer," you have two options:

* Use AWS boto3 client version `1.35.99` or lower instead of boto3 version `1.36.0` or above.
* Add environment variables `AWS_REQUEST_CHECKSUM_CALCULATION=when_required` and `AWS_RESPONSE_CHECKSUM_VALIDATION=when_required` for your script or set them globally.

For more information, see [<mark style="color:blue;">FAQs</mark>](https://docs.ionos.com/cloud/backup-and-storage/object-storage-faqs#what-happens-when-using-python-aws-boto3-client-version-1360-or-above).
{% endhint %}

There are several ways to provide credentials, such as passing them as parameters to the `boto.client()` method, via environment variables, or with a generic credential file `(~/.aws/credentials)`. For more information, see [<mark style="color:blue;">Credentials</mark>](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html).

### Example of passing credentials as parameters when creating a Session object

To get the Access Key and Secret Key, see [<mark style="color:blue;">Generate a Key</mark>](https://docs.ionos.com/cloud/backup-and-storage/ionos-object-storage/get-started/generate-key).

{% hint style="info" %}
**Note:**

* Your credentials are not tied to a specific region or bucket.
* For information on the supported <code class="expression">space.vars.ionos\_cloud\_object\_storage</code> service endpoints, see [<mark style="color:blue;">Endpoints</mark>](https://docs.ionos.com/cloud/backup-and-storage/ionos-object-storage/endpoints).
  {% endhint %}

```python
import boto3
import logging
from botocore.exceptions import ClientError
from botocore.client import Config

config = Config(
   signature_version = 's3v4'
)

s3_client = boto3.client('s3',
                         endpoint_url='https://s3.eu-central-2.ionoscloud.com',
                         aws_access_key_id='YOUR_ACCESS_KEY',
                         aws_secret_access_key='YOUR_SECRET_KEY',
                         config=config)
```

### Example

* List buckets:

  ```python
  response = s3_client.list_buckets()
  for bucket in response['Buckets']:
      print(bucket['Name'])
  ```
* Create bucket `my-bucket` at the region `eu-central-1`:

  ```python
  try:
    s3_client.create_bucket(Bucket='my-bucket', CreateBucketConfiguration={'LocationConstraint': 'eu-central-2'})
  except ClientError as e:
          logging.error(e)
  ```
* Upload **filename.txt** to the bucket `my-bucket`:

  ```python
  try:
          s3_client.upload_file(
              Filename='filename.txt',
              Bucket='my-bucket',
              Key='my-prefix/filename.txt')
  except ClientError as e:
          logging.error(e)
  ```

  For more information, see AWS SDK documentation on [Uploading files](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-uploading-files.html).
* Download the file `filename.txt` from the `my-bucket`:

  ```python
  s3_client.download_file('my-bucket',
                       'filename.txt',
                       '/local_path/filename.txt')
  ```
* List objects of the bucket `my-bucket`

  ```python
  response = s3_client.list_objects(Bucket='my-bucket')
  for obj in response['Contents']:
      print(obj['Key'])
  ```
* Copy the `filename.txt` from the bucket `my-source-bucket` to the bucket `my-dest-bucket` and add the prefix `uploaded/`. We use the `resource()` method instead of the `client()` method here. It provides a higher level of abstraction than the low-level calls made by service clients.

  ```python
  config = Config(
     signature_version = 's3v4'
  )

  s3_resource = boto3.resource('s3',
                      endpoint_url='https://s3.eu-central-2.ionoscloud.com',
                      aws_access_key_id='YOUR_ACCESS_KEY',
                      aws_secret_access_key='YOUR_SECRET_KEY',
                      config=config)

  copy_source = {
      'Bucket': 'my-source-bucket',
      'Key': 'filename.txt'
  }

  bucket = s3_resource.Bucket('my-dest-bucket')
  try: 
          bucket.copy(copy_source, 'uploaded/filename.txt')
  except ClientError as e:
          logging.error(e)   
  ```

For more examples, refer to [<mark style="color:blue;">Boto3 Documentation</mark>](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html), such as:

* [<mark style="color:blue;">Generating presigned URLs</mark>](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-presigned-urls.html)
* [<mark style="color:blue;">Set a bucket policy</mark>](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-example-bucket-policies.html)
* [<mark style="color:blue;">Set a bucket CORS configuration</mark>](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-example-configuring-buckets.html)

For more information on Boto3 and Python, see [<mark style="color:blue;">Realpython.com – Python, Boto3, and AWS S3: Demystified</mark>](https://realpython.com/python-boto3-aws-s3/).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ionos.com/cloud/backup-and-storage/ionos-object-storage/s3-tools/boto3-python-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
