cloudflare-python icon indicating copy to clipboard operation
cloudflare-python copied to clipboard

Create Image Upload is broken for Sync and Async

Open alex-goswag opened this issue 10 months ago • 3 comments

Confirm this is a Python library issue and not an underlying Cloudflare API issue.

  • [x] This is an issue with the Python library

Describe the bug

The Cloudflare Image Create function is broken.

There is an example below, this has also been discussed on StackOverflow

https://stackoverflow.com/questions/79032782/error-5455-when-uploading-to-cloudflare-images-using-python-library

I cant see any test coverage for this use case.

https://github.com/cloudflare/cloudflare-python/blob/fc6ca90779cd230dc06445ba42e4c540da186ce0/tests/api_resources/images/test_v1.py#L28

To Reproduce

This is a working example using Python Requests

import requests
with open(
    "water bottle.webp", "rb"
) as f:
    data = f.read()

# try requests
files = {
    "file": (
        "water bottle.webp",
        data,
        "image/webp",
    )
}

response = requests.post(
    url=f"https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/images/v1",
    headers={
        "Authorization": f"Bearer ..."
    },
    files=files,
)
print(response.status_code)
print(response.json())

This is a broken example using the Cloudflare Sync function

with open(
    "water bottle.webp", "rb"
) as f:
    data = f.read()

from cloudflare import Cloudflare

client = Cloudflare(
    api_token='...'
)

# Create a tuple: (filename, binary data, content type)
file_tuple = ("water bottle.webp", data,   "image/webp",)

cloudflare_image = await client.images.v1.create(
    account_id=CLOUDFLARE_ACCOUNT_ID,
    file=file_tuple,
)
print(cloudflare_image)

The output is

cloudflare.BadRequestError: Error code: 400 - {'result': None, 'success': False, 'errors': [{'code': 5400, 'message': 'Bad request: Error parsing form fields'}], 'messages': []}

This is a broken example using the Async Cloudflare function

from cloudflare import AsyncCloudflare

client = AsyncCloudflare(
    api_token='...'
)

# Create a tuple: (filename, binary data, content type)
file_tuple = ("water bottle.webp", data,   "image/webp",)

cloudflare_image = await client.images.v1.create(
    account_id=CLOUDFLARE_ACCOUNT_ID,
    file=file_tuple,
)
print(cloudflare_image)

The output is

cloudflare.BadRequestError: Error code: 400 - {'result': None, 'success': False, 'errors': [{'code': 5400, 'message': 'Bad request: Error parsing form fields'}], 'messages': []}

Code snippets


OS

macOS

Python version

3.12.9

Library version

v4.1.0

alex-goswag avatar Mar 24 '25 12:03 alex-goswag

I got the same issue with the following code:

client = Cloudflare(
api_token=CLOUDFLARE_IMAGES_API_TOKEN, 
)
direct_upload = client.images.v2.direct_uploads.create(
    account_id=CLOUDFLARE_ACCOUNT_ID,
    metadata={
        "user_id": user_id,
    },
    require_signed_urls=False,
)

laleye avatar May 03 '25 00:05 laleye

Hi, I looked into the issue and it seems like the problem is due to the use of outdated imports from the collections module. Starting from Python 3.10+, classes like Mapping, MutableMapping, etc., have been moved to collections.abc, and in Python 3.12, the old import path has been fully removed.

To fix the issue, we can update the imports in the codebase from:

from collections import Mapping

to:

from collections.abc import Mapping

I’d be happy to help submit a PR for this if needed. Let me know!

codewithdhruba01 avatar May 08 '25 04:05 codewithdhruba01

We've opened a thread internally to investigate.

jhutchings1 avatar Jun 30 '25 21:06 jhutchings1