# 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/sections-test/guides/storage-and-backup/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/sections-test/guides/storage-and-backup/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/sections-test/guides/storage-and-backup/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/).
