Cloudflare Images CLI with Python
2025-07-14 workflow programming
This is for my blog post on optimizing image delivery and management using Cloudflare Images.
Why Cloudflare Images?
Global CDN + storage + optimization in one API.
Serve multiple image sizes without duplicates.
Quickstart with cloudflare-images-cli
npm install -g cloudflare-images-cli
Initialize with your Account ID and API Token (must have Account.Images:Read and Account.Images:Edit):
cf-images init
Common commands:
cf-images list-images
cf-images upload /path/to/image.jpg
cf-images delete <image_id>
Limitations
Cloudflare Images URLs use generated IDs, not original filenames.
To serve images by filename, use custom IDs on upload or URL rewriting (via Workers).
Python Wrapper for Cloudflare Images API
To automate workflows, I built a stateful Python client that:
Loads credentials securely with python-decouple.
Fetches all images on init to build a filename → URL cache.
Allows checking if an image exists by filename.
Uploads images and updates cache automatically.
Retrieves public URLs by filename.
Key methods:
image_exists(filename) → bool
get_image_url(filename) → str
upload_image(filepath) → dict
delete_image(image_id) → dict
Why this wrapper?
Minimizes API calls with local caching.
Simple interface for common operations.
Securely handles credentials.
Easy to integrate into Python apps or scripts.
Here's a simple text-based diagram illustrating the workflow of the Python wrapper interacting with Cloudflare Images CDN:
+--------------------+ +---------------------+
| Python Script | | Cloudflare Images |
| (Your App/Script) | | (API/CDN) |
+--------------------+ +---------------------+
| ^
| 1. Init: Load creds & fetch |
| all images to build cache |
v |
+--------------------+ |
| Local Cache | <---------------------| (Minimize calls)
| (filename → URL) | |
+--------------------+ |
| |
| 2. Check exists? (cache first) |
| If not, query API |
| |
| 3. Upload if needed → Update cache
| |
v v
+--------------------+ +---------------------+
| Retrieve URL | | Store/Serve Image |
| Serve in App | | (Global CDN) |
+--------------------+ +---------------------+
Example Usage
cf = CloudflareImages()
if not cf.image_exists("my-photo.jpg"):
cf.upload_image("./my-photo.jpg")
print(cf.get_image_url("my-photo.jpg"))