Cloudinary Python SDK

repository·master·Indexed 42 days ago

https://github.com/cloudinary/pycloudinary

A server-side library for Python and Django applications to upload, transform, optimize, and manage images and videos. Version 1.46.2 provides tools for asset administration, signed operations, and generating optimized delivery URLs or HTML tags via CloudinaryImage and CloudinaryVideo.

Tokens
34.7K
Snippets
95
Records
133
Agent score
54%

What's inside Cloudinary

  1. Explore Cloudinary Python sample projects

    master

    The samples/ directory contains several reference implementations for different use cases using the Cloudinary Python SDK:

    • Basic sample: A synchronous script demonstrating uploading local files and remote URLs, along with various transformations and options.
    • Photo Album: A Django-based web application for uploading photos, managing a database of references, listing metadata, and displaying images with cloud-based transformations.
    • Basic Flask sample: A simple Flask application that performs image uploads and generates transformations of the uploaded images.
    • Basic Google App Engine sample: A GAE application for image uploads and transformations. Note: This requires cloudinary > 1.0.18.
    • SpookyShots: A specialized application that uses Cloudinary to transform pet images into Halloween-themed creations.
  2. How Cloudinary configuration behavior works

    master

    Understanding how the SDK manages configuration is critical for avoiding unexpected behavior:

    • Process-Global Scope: cloudinary.config() sets configuration for the entire process. If you need to override a value for a single specific call (e.g., a different cloud name), pass that value as a keyword argument directly to the method you are calling (like upload or admin_api).
    • Precedence Rules: Individual CLOUDINARY_* environment variables (like CLOUDINARY_CLOUD_NAME) take precedence over CLOUDINARY_URL. If any individual variable is set, the SDK will ignore CLOUDINARY_URL entirely. Do not use both styles simultaneously.
    • Django Integration: In Django projects, the CLOUDINARY dictionary in your settings.py is read before environment variables.
    • Account Operations: For account-level provisioning operations, the SDK uses CLOUDINARY_ACCOUNT_URL (account://<key>:<secret>@<account_id>) instead of the standard Cloudinary URL.
    • Safe Access: Accessing unset configuration keys via cloudinary.config() returns None rather than raising an error.
  3. Use structured metadata for typed asset labeling

    master

    Structured metadata allows you to attach typed, validated fields (like SKU, campaign, or category) to assets. Unlike Tags (flat strings) or Context (unvalidated key/value pairs), structured metadata uses a schema defined at the account level.

    Key Concepts

    • Schema-based: Fields are defined once on the account with a specific type and optional validation.
    • Contractual: Use the external_id as the constant key in your application. Renaming a field's label does not change its external_id.
    • Validation: Values are rejected if they do not match the defined type or if the external_id is not registered.
  4. Understand the Cloudinary Python SDK security boundary

    master

    The cloudinary Python SDK is a server-side library. It requires your api_secret to function, which must never be exposed in client-side or frontend code.

    If you need to allow a browser to upload files directly to Cloudinary, your server must use this SDK to generate short-lived signatures and pass them to the frontend. Do not attempt to use this SDK in frontend environments.

  5. Manage large video upload results

    master

    When using upload_large, the final chunk returns the full asset payload. Earlier chunks return a short "parts uploaded" acknowledgement.

    Recommended Fields to Store:

    • asset_id: Always store this. It is a permanent identifier that never changes, whereas public_id can change if the asset is renamed or moved.

    Video-Specific Metadata: Video uploads include additional fields in the result dictionary that are useful for deciding which renditions to generate:

    • duration: Length in seconds.
    • bit_rate
    • frame_rate
    • audio: Sub-dictionary with codec details.
    • video: Sub-dictionary with codec details.

    Note: eager transformation entries appear in the result only if eager_async=False.

  6. When to use the Cloudinary Python SDK

    master

    Use this SDK for Python server-side code (including Django) to perform tasks such as:

    • Uploading media
    • Performing signed operations
    • Asset administration and search
    • Moderation
    • Generating delivery URLs

    Do not use this SDK for:

  7. Restrict client uploads using Upload Presets

    master

    To prevent clients from uploading arbitrary files or choosing their own destinations, use Upload Presets instead of signing raw parameters. A preset allows you to pre-define constraints like folder, allowed_formats, and transformation settings on the Cloudinary dashboard or via the API.

    When signing, you only sign the upload_preset parameter. This ensures the client can only perform the specific type of upload you have configured.

    import cloudinary.api
    
    # 1. Create the preset with restrictions
    cloudinary.api.create_upload_preset(
        name="user-avatars",
        unsigned=False,
        folder="avatars",
        allowed_formats="jpg,png,webp",
        transformation=[{"width": 512, "height": 512, "crop": "fill", "gravity": "face"}],
    )
    
    # 2. Sign the request using only the preset name
    params_to_sign = {
        "timestamp": int(time.time()), 
        "upload_preset": "user-avatars"
    }
  8. Manage asset identifiers: asset_id vs public_id

    master

    When handling upload results, it is critical to understand the difference between these two identifiers:

    • asset_id: A unique, immutable identifier. It never changes, even if the asset is renamed or moved. You should store this in your database to reliably look up assets later using cloudinary.api.resource_by_asset_id(asset_id).
    • public_id: A human-readable identifier that can change if the asset is renamed or moved. While useful for constructing URLs, it is not a permanent reference.

    Recommended storage pattern:

    # Store both, but rely on asset_id for permanent references
    record = {"asset_id": result["asset_id"], "public_id": result["public_id"]}
  9. Choosing between Search and Admin APIs

    master

    When managing assets, you must choose the correct API based on your goal to avoid confusion:

    • Search (cloudinary.Search): Use this for querying. It allows you to find assets matching specific criteria across fields, tags, folders, and dates (e.g., "Find all images tagged 'catalog'").
    • Admin (cloudinary.api): Use this for direct manipulation. It is intended for reading, updating, organizing, or deleting specific assets or listing assets by a single axis like a folder or tag (e.g., "Update the tags on this specific asset").
  10. How the Cloudinary Python SDK reports errors

    master

    The SDK maps HTTP status codes to specific exceptions found in cloudinary.exceptions. Most errors subclass cloudinary.exceptions.Error, allowing you to catch all Cloudinary-related failures with a single handler.

    Important distinctions:

    • Configuration errors: Issues like missing api_key or malformed CLOUDINARY_URL raise standard Python ValueError exceptions, not cloudinary.exceptions.Error. These occur before a network request is made.
    • Delivery failures: Building a URL is a local operation and does not raise exceptions. If a generated URL returns a 404 or 403 when requested in a browser, check the x-cld-error response header from the CDN to diagnose the issue.
    • Transient 423 errors: An asset being processed (e.g., a large video) may return a 423 status. This is not mapped to a specific subclass in the SDK and will surface as a plain Exception. Use a retry strategy with backoff.
    import cloudinary.exceptions
    
    try:
        result = cloudinary.uploader.upload("photo.jpg")
    except cloudinary.exceptions.NotFound:
        # handle the specific case
        pass
    except cloudinary.exceptions.Error as error:
        # catch all other Cloudinary API errors
        print("Cloudinary call failed: {0}".format(error))
  11. Capabilities not included in the Python SDK

    master

    The Python SDK focuses on the Image and Video APIs. The following capabilities are available via other Cloudinary services or APIs and are not implemented in this package:

  12. Setup Cloudinary in Django

    master

    To use Cloudinary's Django-specific features like template tags and bundled static files, add "cloudinary" to your INSTALLED_APPS.

    Configure your credentials using the CLOUDINARY dictionary in settings.py. Note that this dictionary is read before environment variables; if you provide a partial dictionary, it will mask a working CLOUDINARY_URL environment variable.

    Alternatively, you can set the CLOUDINARY_URL environment variable (recommended).

    # settings.py
    INSTALLED_APPS = [
        # ...
        "cloudinary",
    ]
    
    # Credentials configuration
    CLOUDINARY = {
        "cloud_name": "my-cloud",
        "api_key": "123456789012345",
        "api_secret": os.environ["CLOUDINARY_API_SECRET"],
        "secure": True,
    }