API Reference

This section provides detailed documentation for all classes, methods, and functions in django-cloudflareimages-toolkit.

CloudflareImagesService Class

class django_cloudflareimages_toolkit.services.CloudflareImagesService[source]

Bases: object

Service class for Cloudflare Images API operations.

__init__()[source]
property account_id: str
property api_token: str
property base_url: str
property session: Session
get_direct_upload_url(user=None, custom_id: str | None = None, metadata: dict[str, Any] | None = None, require_signed_urls: bool | None = None, expiry_minutes: int | None = None) dict[str, str][source]

Get a one-time upload URL for direct creator upload.

This is an alias for create_direct_upload_url that returns a dict to match the documentation examples.

create_direct_upload_url(user=None, custom_id: str | None = None, metadata: dict[str, Any] | None = None, require_signed_urls: bool | None = None, expiry_minutes: int | None = None) CloudflareImage[source]

Create a one-time upload URL for direct creator upload.

Parameters:
  • user – Django user instance (optional)

  • custom_id – Custom ID for the image (optional)

  • metadata – Additional metadata to store with the image

  • require_signed_urls – Whether to require signed URLs

  • expiry_minutes – Minutes until the upload URL expires

Returns:

CloudflareImage instance with upload URL

Raises:

CloudflareImagesError – If the API request fails

check_image_status(image: CloudflareImage) dict[str, Any][source]

Check the status of an image upload.

Parameters:

image – CloudflareImage instance

Returns:

Dictionary containing the image status data

Raises:

CloudflareImagesError – If the API request fails

list_images(page: int = 1, per_page: int = 1000) dict[str, Any][source]

List images from Cloudflare Images.

Parameters:
  • page – Page number for pagination (default: 1)

  • per_page – Number of images per page (default: 1000, max: 10000)

Returns:

Dictionary with pagination info and list of images

Raises:

CloudflareImagesError – If the API request fails

get_image(image_id: str) dict[str, Any][source]

Get details for a specific image.

Parameters:

image_id – Cloudflare image ID

Returns:

Dictionary with image details

Raises:

CloudflareImagesError – If the API request fails

update_image(image_id: str, metadata: dict[str, Any] | None = None, require_signed_urls: bool | None = None) dict[str, Any][source]

Update image metadata and settings.

Parameters:
  • image_id – Cloudflare image ID

  • metadata – New metadata for the image

  • require_signed_urls – Whether to require signed URLs

Returns:

Dictionary with updated image details

Raises:

CloudflareImagesError – If the API request fails

delete_image(image: CloudflareImage) bool[source]

Delete an image from Cloudflare Images.

Parameters:

image – CloudflareImage instance

Returns:

True if deletion was successful

Raises:

CloudflareImagesError – If the API request fails

validate_webhook_signature(payload: bytes, signature: str) bool[source]

Validate webhook signature from Cloudflare.

Parameters:
  • payload – Raw webhook payload

  • signature – Signature from webhook headers (should be in format ‘sha256=…’)

Returns:

True if signature is valid

process_webhook(payload: dict[str, Any]) CloudflareImage | None[source]

Process webhook payload from Cloudflare.

Parameters:

payload – Webhook payload data

Returns:

Updated CloudflareImage instance if found

The main service class for interacting with Cloudflare Images API.

get_direct_upload_url Method

CloudflareImagesService.get_direct_upload_url(user=None, custom_id: str | None = None, metadata: dict[str, Any] | None = None, require_signed_urls: bool | None = None, expiry_minutes: int | None = None) dict[str, str][source]

Get a one-time upload URL for direct creator upload.

This is an alias for create_direct_upload_url that returns a dict to match the documentation examples.

Parameters:

  • metadata (dict, optional): Custom metadata to attach to the image

  • require_signed_urls (bool, optional): Whether to require signed URLs for access

Returns: dict with ‘id’ and ‘uploadURL’ keys

Raises:

  • CloudflareImagesAPIError: When the API request fails

  • ConfigurationError: When configuration is missing or invalid

Example:

from django_cloudflareimages_toolkit.services import CloudflareImagesService

service = CloudflareImagesService()
upload_data = service.get_direct_upload_url(
    metadata={'category': 'profile', 'user_id': '123'}
)
print(f"Upload URL: {upload_data['uploadURL']}")

list_images Method

CloudflareImagesService.list_images(page: int = 1, per_page: int = 1000) dict[str, Any][source]

List images from Cloudflare Images.

Parameters:
  • page – Page number for pagination (default: 1)

  • per_page – Number of images per page (default: 1000, max: 10000)

Returns:

Dictionary with pagination info and list of images

Raises:

CloudflareImagesError – If the API request fails

Parameters:

  • page (int, optional): Page number for pagination (default: 1)

  • per_page (int, optional): Number of images per page (default: 1000, max: 10000)

Returns: dict with pagination info and list of images

Example:

images = service.list_images(page=1, per_page=20)
for image in images['result']['images']:
    print(f"Image ID: {image['id']}")

get_image Method

CloudflareImagesService.get_image(image_id: str) dict[str, Any][source]

Get details for a specific image.

Parameters:

image_id – Cloudflare image ID

Returns:

Dictionary with image details

Raises:

CloudflareImagesError – If the API request fails

Parameters:

  • image_id (str, required): Cloudflare image ID

Returns: dict with image details

Example:

image_details = service.get_image('your-image-id')
print(f"Image URL: {image_details['result']['variants'][0]}")

delete_image Method

CloudflareImagesService.delete_image(image: CloudflareImage) bool[source]

Delete an image from Cloudflare Images.

Parameters:

image – CloudflareImage instance

Returns:

True if deletion was successful

Raises:

CloudflareImagesError – If the API request fails

Parameters:

  • image_id (str, required): Cloudflare image ID

Returns: dict with success status

Example:

result = service.delete_image('your-image-id')
if result['success']:
    print("Image deleted successfully")

update_image Method

CloudflareImagesService.update_image(image_id: str, metadata: dict[str, Any] | None = None, require_signed_urls: bool | None = None) dict[str, Any][source]

Update image metadata and settings.

Parameters:
  • image_id – Cloudflare image ID

  • metadata – New metadata for the image

  • require_signed_urls – Whether to require signed URLs

Returns:

Dictionary with updated image details

Raises:

CloudflareImagesError – If the API request fails

Parameters:

  • image_id (str, required): Cloudflare image ID

  • metadata (dict, optional): New metadata for the image

  • require_signed_urls (bool, optional): Whether to require signed URLs

Returns: dict with updated image details

Example:

updated = service.update_image(
    'your-image-id',
    metadata={'updated': True, 'category': 'featured'}
)

CloudflareImage Model

class django_cloudflareimages_toolkit.models.CloudflareImage(*args, **kwargs)[source]

Bases: Model

Model to track Cloudflare image uploads.

id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

cloudflare_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

user

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

filename

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

original_filename

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

content_type

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

file_size

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

upload_url

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

status

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

require_signed_urls

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

metadata

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

created_at

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

updated_at

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

uploaded_at

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

expires_at

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

width

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

height

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

format

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

variants

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

cloudflare_metadata

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

property is_expired: bool

Check if the upload URL has expired.

property is_uploaded: bool

Check if the image has been successfully uploaded.

property public_url: str | None

Get the public variant URL for the uploaded image.

property thumbnail_url: str | None

Get the thumbnail variant URL for the uploaded image.

get_variant_url(variant_name: str) str | None[source]

Get the URL for a specific variant by name.

Cloudflare returns variants as full URLs like: https://imagedelivery.net/<hash>/<id>/<variant_name>

Parameters:

variant_name – The variant name to look for (e.g., ‘public’, ‘thumbnail’)

Returns:

The full variant URL if found, None otherwise

property is_ready: bool

Check if the image is ready for use (uploaded and processed).

get_url(variant: str = 'public') str | None[source]

Get the URL for a specific variant of the image.

Parameters:

variant – The variant name (e.g., ‘public’, ‘thumbnail’, ‘avatar’)

Returns:

The URL for the specified variant, or None if not found

get_signed_url(variant: str = 'public', expiry: int = 3600) str | None[source]

Get a signed URL for a specific variant of the image.

Parameters:
  • variant – The variant name (e.g., ‘public’, ‘thumbnail’, ‘avatar’)

  • expiry – Expiry time in seconds (default: 3600 = 1 hour)

Returns:

A signed URL for the specified variant, or None if not available

Note

This method requires the image to have require_signed_urls=True and proper Cloudflare API integration for signing URLs.

update_from_cloudflare_response(response_data: dict[str, Any]) None[source]

Update model fields from Cloudflare API response.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

exception NotUpdated

Bases: ObjectNotUpdated, DatabaseError

get_next_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=True, **kwargs)
get_next_by_expires_at(*, field=<django.db.models.fields.DateTimeField: expires_at>, is_next=True, **kwargs)
get_next_by_updated_at(*, field=<django.db.models.fields.DateTimeField: updated_at>, is_next=True, **kwargs)
get_previous_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=False, **kwargs)
get_previous_by_expires_at(*, field=<django.db.models.fields.DateTimeField: expires_at>, is_next=False, **kwargs)
get_previous_by_updated_at(*, field=<django.db.models.fields.DateTimeField: updated_at>, is_next=False, **kwargs)
get_status_display(*, field=<django.db.models.fields.CharField: status>)
logs

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_reverse_many_to_one_manager() defined below.

objects = <django.db.models.manager.Manager object>
user_id

Django model for tracking Cloudflare Images.

Fields:

  • cloudflare_id (CharField): Unique Cloudflare image ID (max 255 characters)

  • filename (CharField): Original filename (max 255 characters)

  • uploaded_at (DateTimeField): Timestamp when image was uploaded

  • file_size (PositiveIntegerField): File size in bytes (optional)

  • width (PositiveIntegerField): Image width in pixels (optional)

  • height (PositiveIntegerField): Image height in pixels (optional)

  • format (CharField): Image format (jpeg, png, gif, webp) (max 10 characters)

  • variants (JSONField): Available image variants

  • metadata (JSONField): Custom metadata

  • is_ready (BooleanField): Whether image processing is complete

  • upload_url (URLField): Direct upload URL (temporary)

  • upload_expires_at (DateTimeField): When upload URL expires

Methods:

get_url Method

CloudflareImage.get_url(variant: str = 'public') str | None[source]

Get the URL for a specific variant of the image.

Parameters:

variant – The variant name (e.g., ‘public’, ‘thumbnail’, ‘avatar’)

Returns:

The URL for the specified variant, or None if not found

Parameters:

  • variant (str, optional): Image variant name (default: ‘public’)

Returns: str - Full image URL

Example:

image = CloudflareImage.objects.get(cloudflare_id='your-id')
original_url = image.get_url()
thumbnail_url = image.get_url('thumbnail')

get_variant_url Method

CloudflareImage.get_variant_url(variant_name: str) str | None[source]

Get the URL for a specific variant by name.

Cloudflare returns variants as full URLs like: https://imagedelivery.net/<hash>/<id>/<variant_name>

Parameters:

variant_name – The variant name to look for (e.g., ‘public’, ‘thumbnail’)

Returns:

The full variant URL if found, None otherwise

Parameters:

  • variant_name (str, required): Name of the variant to retrieve

Returns: str or None - Full variant URL if found, None otherwise

Retrieves a specific variant URL from the image’s variants list. This method searches through the stored variants (which may be a list of URLs or a dict) to find and return the URL matching the requested variant name.

Example:

image = CloudflareImage.objects.get(cloudflare_id='your-id')

# Get specific variant URLs
public_url = image.get_variant_url('public')
thumbnail_url = image.get_variant_url('thumbnail')

# Returns None if variant doesn't exist
custom_url = image.get_variant_url('nonexistent')  # None

get_signed_url Method

CloudflareImage.get_signed_url(variant: str = 'public', expiry: int = 3600) str | None[source]

Get a signed URL for a specific variant of the image.

Parameters:
  • variant – The variant name (e.g., ‘public’, ‘thumbnail’, ‘avatar’)

  • expiry – Expiry time in seconds (default: 3600 = 1 hour)

Returns:

A signed URL for the specified variant, or None if not available

Note

This method requires the image to have require_signed_urls=True and proper Cloudflare API integration for signing URLs.

Parameters:

  • variant (str, optional): Image variant name

  • expiry (int, optional): URL expiry time in seconds

Returns: str - Signed image URL

Example:

# Get signed URL that expires in 1 hour
signed_url = image.get_signed_url('thumbnail', expiry=3600)

is_expired Property

CloudflareImage.is_expired

Check if the upload URL has expired.

Returns: bool - True if upload URL has expired

Example:

if image.is_expired:
    print("Upload URL has expired")

CloudflareImageField

class django_cloudflareimages_toolkit.fields.CloudflareImageField(variants: list[str] | None = None, metadata: dict[str, Any] | None = None, require_signed_urls: bool = False, max_file_size: int | None = None, allowed_formats: list[str] | None = None, **kwargs)[source]

Bases: Field

A Django model field for storing Cloudflare Images.

This field stores the Cloudflare image ID and provides easy access to image URLs, variants, and metadata. It integrates with the CloudflareImage model and service layer.

description = 'Cloudflare Image'
__init__(variants: list[str] | None = None, metadata: dict[str, Any] | None = None, require_signed_urls: bool = False, max_file_size: int | None = None, allowed_formats: list[str] | None = None, **kwargs)[source]

Initialize the CloudflareImageField.

Parameters:
  • variants – List of variant names to create for uploaded images

  • metadata – Default metadata to attach to uploaded images

  • require_signed_urls – Whether to require signed URLs for image access

  • max_file_size – Maximum file size in bytes (None for no limit)

  • allowed_formats – List of allowed image formats (jpeg, png, gif, webp)

  • **kwargs – Additional field options

get_internal_type() str[source]

Return the internal field type for Django.

to_python(value: Any) CloudflareImageFieldValue | None[source]

Convert the database value to a Python object.

Parameters:

value – The value from the database (Cloudflare image ID)

Returns:

CloudflareImageFieldValue instance or None

from_db_value(value: Any, expression, connection) CloudflareImageFieldValue | None[source]

Convert database value to Python object.

get_prep_value(value: Any) str | None[source]

Convert Python object to database value.

Parameters:

value – CloudflareImageFieldValue instance or string

Returns:

Cloudflare image ID string or None

formfield(**kwargs) Field[source]

Return the form field for this model field.

validate(value: Any, model_instance) None[source]

Validate the field value.

deconstruct() tuple[source]

Return field definition for migrations.

Django model field for Cloudflare Images integration.

Parameters:

  • variants (list, optional): List of variant names to create

  • metadata (dict, optional): Default metadata for uploads

  • require_signed_urls (bool, optional): Whether to require signed URLs

  • max_file_size (int, optional): Maximum file size in bytes

  • allowed_formats (list, optional): List of allowed image formats

Example:

from django.db import models
from django_cloudflareimages_toolkit.fields import CloudflareImageField

class Product(models.Model):
    name = models.CharField(max_length=100)
    image = CloudflareImageField(
        variants=['thumbnail', 'large'],
        metadata={'category': 'product'},
        max_file_size=5 * 1024 * 1024,  # 5MB
        allowed_formats=['jpeg', 'png']
    )

CloudflareImageWidget

class django_cloudflareimages_toolkit.widgets.CloudflareImageWidget(variants: list[str] | None = None, metadata: dict[str, Any] | None = None, require_signed_urls: bool = False, max_file_size: int | None = None, allowed_formats: list[str] | None = None, attrs: dict[str, Any] | None = None)[source]

Bases: TextInput

A widget for handling Cloudflare image uploads.

This widget provides a file input interface that handles direct uploads to Cloudflare Images and stores the resulting image ID in the form field.

template_name = 'django_cloudflareimages_toolkit/widgets/cloudflare_image_widget.html'
__init__(variants: list[str] | None = None, metadata: dict[str, Any] | None = None, require_signed_urls: bool = False, max_file_size: int | None = None, allowed_formats: list[str] | None = None, attrs: dict[str, Any] | None = None)[source]

Initialize the widget.

Parameters:
  • variants – List of image variants to create

  • metadata – Default metadata for uploads

  • require_signed_urls – Whether to require signed URLs

  • max_file_size – Maximum file size in bytes

  • allowed_formats – List of allowed image formats

  • attrs – Additional HTML attributes

format_value(value)[source]

Format the field value for display.

render(name: str, value: Any, attrs: dict[str, Any] | None = None, renderer=None) SafeString[source]

Render the widget HTML.

Parameters:
  • name – Field name

  • value – Current field value

  • attrs – HTML attributes

  • renderer – Template renderer

Returns:

Rendered HTML string

class Media[source]

Bases: object

Define media files for the widget.

css = {'all': ('django_cloudflareimages_toolkit/css/cloudflare_image_widget.css',)}
js = ('django_cloudflareimages_toolkit/js/cloudflare_image_widget.js',)
property media

Django form widget for handling Cloudflare image uploads with JavaScript-based upload functionality.

Django Admin Integration

class django_cloudflareimages_toolkit.admin.CloudflareImageAdmin(model, admin_site)[source]

Bases: ModelAdmin

Admin interface for CloudflareImage model.

list_display = ('cloudflare_id_display', 'user_display', 'status_display', 'filename_display', 'file_size_display', 'created_at', 'expires_at', 'is_expired_display', 'thumbnail_preview', 'actions_display')
list_filter = ('status', 'require_signed_urls', 'created_at', 'uploaded_at', 'expires_at', ('user', <class 'django.contrib.admin.filters.RelatedOnlyFieldListFilter'>))
search_fields = ('cloudflare_id', 'filename', 'original_filename', 'user__username', 'user__email')
readonly_fields = ('id', 'cloudflare_id', 'upload_url_display', 'status', 'created_at', 'updated_at', 'uploaded_at', 'expires_at', 'width', 'height', 'format', 'variants_display', 'cloudflare_metadata_display', 'is_expired_display', 'is_uploaded_display', 'is_ready_display', 'public_url_display', 'thumbnail_url_display', 'image_preview', 'transformation_examples')
fields = ('id', 'cloudflare_id', 'user', 'filename', 'original_filename', 'content_type', 'file_size', 'width', 'height', 'format', 'upload_url_display', 'status', 'require_signed_urls', 'metadata', 'created_at', 'updated_at', 'uploaded_at', 'expires_at', 'variants_display', 'cloudflare_metadata_display', 'is_expired_display', 'is_uploaded_display', 'is_ready_display', 'public_url_display', 'thumbnail_url_display', 'image_preview', 'transformation_examples')
inlines = [<class 'django_cloudflareimages_toolkit.admin.ImageUploadLogInline'>]
actions = ['check_status_action', 'mark_as_expired', 'delete_from_cloudflare_action', 'refresh_all_status']
list_per_page = 25
date_hierarchy = 'created_at'
get_queryset(request)[source]

Optimize queryset with select_related.

cloudflare_id_display(obj)[source]

Display Cloudflare ID with copy button.

user_display(obj)[source]

Display user with link to user admin.

status_display(obj)[source]

Display status with color coding.

filename_display(obj)[source]

Display filename with truncation.

file_size_display(obj)[source]

Display file size in human readable format.

is_expired_display(obj)[source]

Display expiry status with icon.

thumbnail_preview(obj)[source]

Display thumbnail preview if available.

actions_display(obj)[source]

Display action buttons.

upload_url_display(obj)[source]

Display upload URL with security.

variants_display(obj)[source]

Display available variants.

cloudflare_metadata_display(obj)[source]

Display Cloudflare metadata.

is_uploaded_display(obj)[source]

Display upload status.

is_ready_display(obj)[source]

Display ready status.

public_url_display(obj)[source]

Display public URL with link.

thumbnail_url_display(obj)[source]

Display thumbnail URL with link.

image_preview(obj)[source]

Display larger image preview.

transformation_examples(obj)[source]

Display transformation examples.

check_status_action(request, queryset)[source]

Check status for selected images.

mark_as_expired(request, queryset)[source]

Mark selected images as expired.

delete_from_cloudflare_action(request, queryset)[source]

Delete selected images from Cloudflare.

refresh_all_status(request, queryset)[source]

Refresh status for all non-final status images.

class Media[source]

Bases: object

js = ('admin/js/cloudflare_images_admin.js',)
css = {'all': ('admin/css/cloudflare_images_admin.css',)}
property media

Django admin interface for managing Cloudflare Images.

Features:

  • List view with image previews and metadata

  • Search functionality by filename and Cloudflare ID

  • Filtering by upload status, format, and date

  • Bulk delete operations

  • Image detail view with full metadata

Admin Actions:

  • delete_selected_images: Delete images from both Django and Cloudflare

  • refresh_image_metadata: Refresh metadata from Cloudflare API

  • generate_upload_urls: Generate new upload URLs for failed uploads

Example Customization:

from django.contrib import admin
from django_cloudflareimages_toolkit.admin import CloudflareImageAdmin
from django_cloudflareimages_toolkit.models import CloudflareImage

@admin.register(CloudflareImage)
class CustomCloudflareImageAdmin(CloudflareImageAdmin):
    list_display = ['filename', 'uploaded_at', 'file_size', 'is_ready', 'image_preview']
    list_filter = ['is_ready', 'format', 'uploaded_at']

Webhook Views

class django_cloudflareimages_toolkit.views.WebhookView(**kwargs)[source]

Bases: APIView

API view for handling Cloudflare webhooks.

permission_classes = []
post(request: HttpRequest) HttpResponse[source]

Handle incoming webhook from Cloudflare.

Status codes returned:
  • 200 — payload processed and matched an existing image

  • 400 — payload failed JSON parse OR schema validation

  • 401 — webhook_secret is configured but the request was

    unauthenticated (missing or invalid signature)

  • 404 — payload was valid but referenced an unknown image

  • 500 — unexpected error while processing a validated payload

Note that 401 is only emitted when a CLOUDFLARE_IMAGES.WEBHOOK_SECRET is configured. Deployments without a secret accept any well-formed payload — callers that want enforcement MUST set the secret.

dispatch(request, *args, **kwargs)

.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.

Handles Cloudflare Images webhook notifications. CSRF-exempt at the view layer; security is enforced via HMAC signature verification when CLOUDFLARE_IMAGES["WEBHOOK_SECRET"] is configured. See Webhook Configuration for the full status-code matrix.

URL Pattern:

from django_cloudflareimages_toolkit.views import WebhookView

path('webhook/', WebhookView.as_view(), name='webhook')

Webhook Events:

  • upload.complete: Image upload and processing completed

  • upload.failed: Image upload failed

  • image.deleted: Image was deleted

Example:

# urls.py
from django.urls import path, include

urlpatterns = [
    path('cloudflare-images/', include('django_cloudflareimages_toolkit.urls')),
]

Management Commands

cleanup_expired_images Command

class django_cloudflareimages_toolkit.management.commands.cleanup_expired_images.Command(stdout=None, stderr=None, no_color=False, force_color=False)[source]

Command to clean up expired image upload URLs.

help = 'Clean up expired image upload URLs and mark them as expired'
add_arguments(parser)[source]

Add command arguments.

handle(*args, **options)[source]

Handle the command execution.

Cleans up expired upload URLs and unused images.

Options:

  • --days (int): Number of days to consider for cleanup (default: 1)

  • --dry-run: Show what would be deleted without actually deleting

  • --force: Skip confirmation prompts

Example:

# Clean up images older than 7 days
python manage.py cleanup_expired_images --days 7

# Dry run to see what would be deleted
python manage.py cleanup_expired_images --dry-run

App Configuration

class django_cloudflareimages_toolkit.apps.CloudflareImagesConfig(app_name, app_module)[source]

Bases: AppConfig

App configuration for django_cloudflareimages_toolkit.

default_auto_field = 'django.db.models.BigAutoField'
name = 'django_cloudflareimages_toolkit'
verbose_name = 'Cloudflare Images Toolkit'
ready()[source]

Initialize the app when Django starts.

Django app configuration class.

Attributes:

  • default_auto_field: Specifies BigAutoField as default primary key

  • name: App name for Django’s app registry

  • verbose_name: Human-readable app name

Exception Classes

CloudflareImagesAPIError

exception django_cloudflareimages_toolkit.exceptions.CloudflareImagesAPIError(message: str, status_code: int | None = None, response_data: dict | None = None)[source]

Exception raised when the Cloudflare Images API request fails.

This exception is raised when: - API returns an error status code - Network request fails - Invalid API response format - Authentication failures

Raised when Cloudflare Images API requests fail.

Common Causes:

  • Network connectivity issues

  • Invalid API credentials

  • Rate limiting

  • Server errors

  • Invalid image data

Example:

try:
    service = CloudflareImagesService()
    upload_data = service.get_direct_upload_url()
except CloudflareImagesAPIError as e:
    print(f"API error: {e}")

ConfigurationError

exception django_cloudflareimages_toolkit.exceptions.ConfigurationError(message: str, status_code: int | None = None, response_data: dict | None = None)[source]

Exception raised when configuration is missing or invalid.

This exception is raised when: - Required settings are missing (CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN) - Invalid configuration values - Missing environment variables

Raised when configuration is missing or invalid.

Common Causes:

  • Missing required settings

  • Invalid account credentials

  • Malformed configuration data

Example:

try:
    service = CloudflareImagesService()
except ConfigurationError as e:
    print(f"Configuration error: {e}")

ValidationError

exception django_cloudflareimages_toolkit.exceptions.ValidationError(message: str, status_code: int | None = None, response_data: dict | None = None)[source]

Exception raised when validation fails.

This exception is raised when: - Invalid file types or sizes - Invalid metadata format - Field validation errors - Image processing validation failures

Raised when image data validation fails.

Common Causes:

  • Invalid image format

  • File size exceeds limits

  • Missing required metadata

Example:

try:
    field = CloudflareImageField(allowed_formats=['jpeg'])
    # Validation occurs during model save
except ValidationError as e:
    print(f"Validation error: {e}")

Utility APIs

There is no separate utils module. The utility-style operations live as methods on the service singleton and the CloudflareImage model, plus the standalone CloudflareImageTransform class for URL construction.

Image URL Generation

URL generation is a method on the model, not a freestanding function. Use get_url() for the default variant or get_variant_url() to select one.

image = CloudflareImage.objects.get(cloudflare_id='abc123')
url = image.get_variant_url('thumbnail')

For transformation URLs (resize, crop, format, watermark) without a CloudflareImage instance, use the standalone builder CloudflareImageTransform:

from django_cloudflareimages_toolkit.transformations import (
    CloudflareImageTransform,
)

url = (
    CloudflareImageTransform()
    .width(400)
    .height(300)
    .format("auto")
    .quality(85)
    .url(account_hash="your-hash", image_id="abc123", variant="public")
)

See Patterns & Recipes for a watermarking recipe that composes CloudflareImageTransform.draw() with viewer-specific parameters.

Signed URL Generation

Signed URLs are produced by get_signed_url() when require_signed_urls=True on the model row:

image = CloudflareImage.objects.get(cloudflare_id='abc123')
signed_url = image.get_signed_url(variant="public", expiry=3600)

Returns None if the image isn’t uploaded yet or signed URLs are disabled for that row.

Configuration Helpers

Read settings via the cloudflare_settings proxy instead of indexing settings.CLOUDFLARE_IMAGES directly. The proxy validates required keys (ACCOUNT_ID, API_TOKEN) on access and exposes documented defaults for everything else.

from django_cloudflareimages_toolkit.settings import cloudflare_settings

print(cloudflare_settings.account_id)
print(cloudflare_settings.default_expiry_minutes)
secret = cloudflare_settings.webhook_secret  # may be None

Webhook Signature Verification

Signature verification is wired into WebhookView and runs automatically when a secret is configured. If you need to verify a signature outside the bundled view (e.g. inside a Celery task or a custom endpoint), call the service directly:

from django_cloudflareimages_toolkit.services import cloudflare_service

ok = cloudflare_service.validate_webhook_signature(
    request.body, signature_header
)

Returns True only when the HMAC matches. Callers that need strict enforcement should check the secret first or use WebhookView, which encodes the right policy.

Constants and Settings

Default Settings:

# Default configuration keys
CLOUDFLARE_IMAGES_DEFAULTS = {
    'DEFAULT_VARIANT': 'public',
    'UPLOAD_TIMEOUT': 300,
    'CLEANUP_EXPIRED_HOURS': 24,
    'MAX_FILE_SIZE': 10 * 1024 * 1024,  # 10MB
    'ALLOWED_FORMATS': ['jpeg', 'png', 'gif', 'webp'],
    'REQUIRE_SIGNED_URLS': False,
}

API Endpoints:

CLOUDFLARE_IMAGES_API_BASE = 'https://api.cloudflare.com/client/v4'
CLOUDFLARE_IMAGES_DELIVERY_BASE = 'https://imagedelivery.net'

Migration Support

The package includes Django migrations for database schema management:

Initial Migration (0001_initial.py):

  • Creates CloudflareImage model table

  • Sets up indexes for performance

  • Creates constraints for data integrity

Migration Commands:

# Apply migrations
python manage.py migrate django_cloudflareimages_toolkit

# Create new migration (if you modify models)
python manage.py makemigrations django_cloudflareimages_toolkit

Testing Utilities

Mock Service

For testing purposes, you can mock the CloudflareImagesService:

from unittest.mock import patch, MagicMock
from django.test import TestCase

class MyTestCase(TestCase):
    @patch('django_cloudflareimages_toolkit.services.CloudflareImagesService')
    def test_image_upload(self, mock_service):
        mock_instance = MagicMock()
        mock_service.return_value = mock_instance
        mock_instance.get_direct_upload_url.return_value = {
            'id': 'test-id',
            'uploadURL': 'https://test-upload-url.com'
        }

        # Your test code here

Test Image Factory

Create test images for testing:

from django_cloudflareimages_toolkit.models import CloudflareImage

def create_test_image(**kwargs):
    defaults = {
        'cloudflare_id': 'test-image-id',
        'filename': 'test.jpg',
        'is_ready': True,
        'file_size': 1024,
        'width': 800,
        'height': 600,
        'format': 'jpeg'
    }
    defaults.update(kwargs)
    return CloudflareImage.objects.create(**defaults)

Version Information

django_cloudflareimages_toolkit.__version__ = '1.0.14'

str(object=’’) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.

Current package version string.

Example:

import django_cloudflareimages_toolkit
print(f"Package version: {django_cloudflareimages_toolkit.__version__}")

Logging

The package uses Python’s standard logging module with the logger name django_cloudflareimages_toolkit.

Log Levels:

  • DEBUG: Detailed API request/response information

  • INFO: Successful operations and image processing updates

  • WARNING: Recoverable errors and fallback usage

  • ERROR: Failed operations and API errors

  • CRITICAL: System-level failures

Example Configuration:

import logging

# Configure logging for the package
logging.getLogger('django_cloudflareimages_toolkit').setLevel(logging.INFO)

# Example log output
logger = logging.getLogger('django_cloudflareimages_toolkit')
logger.info("Image uploaded successfully: %s", image_id)

Type Hints

The package includes comprehensive type hints for better IDE support and type checking:

from typing import Dict, List, Optional, Union
from django_cloudflareimages_toolkit.services import CloudflareImagesService

service: CloudflareImagesService = CloudflareImagesService()
upload_data: Dict[str, str] = service.get_direct_upload_url()
images: Dict[str, Union[List, Dict]] = service.list_images()