title: boto3: How to interract with DigitalOcean S3 Spaces when CDN is enabled
body: <p>I'm working with DigitalOcean Spaces (S3 storage protocol) which has enabled <a href="https://www.digitalocean.com/docs/spaces/how-to/enable-cdn/" rel="nofollow noreferrer">CDN</a>.</p>
  <p>Any file on s3 can be accessed via direct URL in the given form:</p>
  <pre><code>https://my-bucket.fra1.digitaloceanspaces.com/&lt;file_key&gt;
  </code></pre>
  <p>If CDN <strong>is enabled</strong>, the file can be accessed via additional CDN URL:</p>
  <pre><code>https://my-bucket.fra1.cdn.digitaloceanspaces.com/&lt;file_key&gt;
  </code></pre>
  <p>where <code>fra1</code> is a <strong>region_name</strong>.</p>
  <p>When I'm using <code>boto3</code> SDK for Python, the file URL is the following (generated by boto3):</p>
  <pre><code>https://fra1.digitaloceanspaces.com/my-bucket/&lt;file_key&gt;
  # just note that bucket name is no more a domain part!
  </code></pre>
  <p>This format also works fine.</p>
  <p>But, if CDN is enabled - file url causes an error:</p>
  <pre><code>EndpointConnectionError: Could not connect to the endpoint URL:  https://fra1.cdn.digitaloceanspaces.com/my-bucket/&lt;file_key&gt;
  </code></pre>
  <p>assuming the endpoint_url was changed from</p>
  <p><code>default_endpoint=https://fra1.digitaloceanspaces.com</code></p>
  <p>to</p>
  <p><code>default_endpoint=https://fra1.cdn.digitaloceanspaces.com</code></p>
  <p>How to connect to CDN with proper URL without getting an error?
  And why boto3 uses different URL format? Is any workaround can be applied in this case?</p>
  <p><strong>code:</strong></p>
  <pre><code>s3_client = boto3.client('s3',
                              region_name=s3_configs['default_region'],
                              endpoint_url=s3_configs['default_endpoint'],
                              aws_access_key_id=s3_configs['bucket_access_key'],
                              aws_secret_access_key=s3_configs['bucket_secret_key'])
  
  s3_client.download_file(bucket_name,key,local_filepath)
  </code></pre>
  <p>boto3 <a href="https://www.digitalocean.com/docs/spaces/resources/s3-sdk-examples/" rel="nofollow noreferrer">guide</a> for DigitalOcean Spaces.</p>
  <p><strong>Here is what I've also tried but It didn't work:</strong></p>
  <ul>
  <li>Generate <a href="https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-presigned-urls.html" rel="nofollow noreferrer">presigned url's</a></li>
  </ul>
  <p><strong>UPDATE</strong>
  Based on @Amit Singh's answer:</p>
  <p>As I mentioned before, I've already tried this trick with presigned URLs.
  I've got Urls like this</p>
  <pre><code>https://fra1.digitaloceanspaces.com/&lt;my-bucket&gt;/interiors/uploaded/images/07IRgHJ2PFhVqVrJDCIpzhghqe4TwK1cSSUXaC4T.jpeg?&lt;presigned-url-params&gt;
  </code></pre>
  <p>The bucket name appears after endpoint. I had to move It to domain-level manually:</p>
  <pre><code>https://&lt;my-bucket&gt;.fra1.cdn.digitaloceanspaces.com/interiors/uploaded/images/07IRgHJ2PFhVqVrJDCIpzhghqe4TwK1cSSUXaC4T.jpeg?&lt;presigned-url-params&gt;
  </code></pre>
  <p>With this URL I can now connect to Digital ocean, but another arror occures:</p>
  <pre><code>This XML file does not appear to have any style information associated with it. The document tree is shown below.
  &lt;Error&gt;
  &lt;Code&gt;SignatureDoesNotMatch&lt;/Code&gt;
  &lt;RequestId&gt;tx00000000000008dfdbc88-006005347c-604235a-fra1a&lt;/RequestId&gt;
  &lt;HostId&gt;604235a-fra1a-fra1&lt;/HostId&gt;
  &lt;/Error&gt;
  </code></pre>
  <p>As a workaround I've tired to use signature <code>s3v4</code>:</p>
  <pre><code>    s3_client = boto3.client('s3',
                                   region_name=configs['default_region'],
                                   endpoint_url=configs['default_endpoint'],
                                   aws_access_key_id=configs['bucket_access_key'],
                                   aws_secret_access_key=configs['bucket_secret_key'],
                                   config= boto3.session.Config(signature_version='s3v4'))
  </code></pre>
  <p>but It still fails.</p>