Skip to main content

Tortoise ImageField

Tortoise ImageField is an image storage solution for Tortoise ORM that supports file uploads, Base64 encoding, and external URLs. It allows storing images locally or in AWS S3 + CloudFront, and includes caching, cropping, and WebP conversion for optimized performance.

✨ Features

  • Supports multiple input formats: File Uploads, Base64, and external URLs.
  • Storage options: Local filesystem or AWS S3 with CloudFront.
  • Automatic caching and WebP conversion to optimize image delivery.
  • Built-in cropping support to generate resized images on demand.
  • Automatic filename renaming and slugify based on a selected model field.
  • Asynchronous interaction with S3 for efficient uploads, deletions, and retrievals.
  • Fully asynchronous image processing for non-blocking operations and better scalability.

📌 Installation

pip install tortoise-imagefield

🚀 Quick Start

Define a Model with ImageField

from tortoise import fields, Model
from tortoise_imagefield import ImageField, StorageTypes


class Item(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=255)
    image = ImageField()  # Store locally
    s3_image = ImageField(storage_type=StorageTypes.S3_AWS)  # Store in AWS S3
    image_ugc = ImageField(directory_name="ugc", field_for_name="name")

🛠 ImageField Parameters

Parameter Description Default
storage_type Defines the storage backend (StorageTypes.LOCAL or StorageTypes.S3_AWS). StorageTypes.LOCAL
directory_name Custom directory name for storing images. If not set, defaults to {class_name}_images. {class_name}_images
field_for_name Specifies a model field that will be used to generate a slugified filename. None

Automatically Added Methods in Models

When using ImageField, the following helper methods are dynamically added to your model, based on the field name.

🔹 Generated Methods

Method Name Description Parameters
get_{field_name}_webp Returns the WebP-optimized cached image URL. width: int – Desired width
height: int – Desired height
position: str = "center" – Cropping position ("center", "top", "left")
return_path: bool = False – If True, returns the local path instead of the URL.
get_{field_name}_url Returns the original uploaded image URL. No parameters
get_{field_name}_path Returns the original file path (for local storage) or S3 key (for AWS S3). No parameters

Image Processing

Crop & Convert to WebP (Cached)

item = await Item.get(id=1)
cached_image_webp = await item.get_image_webp(200, 200)
cached_s3_image_webp = await item.get_image_webp(100, 100)

🔹 Example Usage

Assume the model has an ImageField named image:

item = await Item.get(id=1)

# Get WebP-optimized URL (resized to 200x200)
webp_url = await item.get_image_webp(200, 200)
print(webp_url)  # Example: "https://cdn.example.com/images/image_200x200.webp"

# Get the original image URL
original_url = await item.get_image_url()
print(original_url)  # Example: "https://s3.example.com/uploads/image.jpg"

# Get the file path (local) or S3 key
image_path = await item.get_image_path()
print(image_path)  # Example: "/uploads/image.jpg" or "s3://bucket-name/uploads/image.jpg"

Upload an Image

Upload via File Upload

await Item.create(name="Test Item", image=file)

Upload via Base64 string

await Item.create(name="Test Item", image="data:image/png;base64,iVBORw...")

Upload via External URL

await Item.create(name="Test Item", image="https://example.com/image.jpg")

Upload via Fast API

@app.post("/upload/")
async def upload_image(
        name: str = Form(...),
        image: UploadFile = File(...),
        s3_image: UploadFile = File(...)):
    """Handles image upload and saves it to the database with Upload File."""
    item = await Item.create(name=name, image=image, s3_image=s3_image)
    return {"id": item.id,
            "name": item.name,
            "image_url": await item.get_image_webp(200, 200),
            "s3_image_url": await item.get_s3_image_webp(250, 250)
            }


@app.post("/items/")
async def create_item(request: Request):
    """Handles image upload and saves it to the database with base64 or URL."""
    data = await request.json()
    item = await Item.create(**data)
    return {"id": item.id,
            "name": item.name,
            "image_url": await item.get_image_webp(200, 200),
            "s3_image_url": await item.get_s3_image_webp(150)
            }

🔧 Configuration via .env and Manual Settings

📂 .env File Configuration

You can configure storage settings using an .env file:

DATABASE_URL = sqlite://db.sqlite3
IMAGES_UPLOAD_DIR = uploads
IMAGES_UPLOAD_URL = uploads
S3_BUCKET =
S3_REGION =
S3_ACCESS_KEY =
S3_SECRET_KEY =
S3_CDN_DOMAIN =
S3_ACL_TYPE = private #default


# or change to "public-read"
from tortoise_imagefield.config import Config, S3AclType

cfg = Config()
cfg.s3_acl_type = S3AclType.PUBLIC_READ.value

# change s3 files cashing to RedisCache (default SimpleMemoryCache)
from aiocache import RedisCache
cfg.s3_cache = RedisCache # with settings

The package uses public access for S3, as it is intended to be a simple storage solution for public images.

📖 For a complete guide, see S3 Configuration.

Make sure to load these variables in your application:

from dotenv import load_dotenv
import os

load_dotenv()

print(os.getenv("S3_BUCKET"))  # Prints the configured S3 bucket

⚙️ Manual Configuration via Config

You can also configure the library manually:

from tortoise_imagefield import Config

cfg = Config()
cfg.image_dir = "app/uploads"
cfg.image_url = "static"

Config Class:

class Config:
    image_url: str
    image_dir: str
    s3_bucket: Optional[str]
    s3_region: Optional[str]
    s3_access_key: Optional[str]
    s3_secret_key: Optional[str]
    s3_cdn_domain: Optional[str]

📜 License

This project is licensed under the MIT License.

🚀 Now you're ready to optimize image handling with Tortoise ORM!

Metadata

Release files for tortoise-imagefield 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tortoise-imagefield 0.2.0
File Size Uploaded
tortoise_imagefield-0.2.0.tar.gz 26.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tortoise-imagefield 0.2.0
File Interpreter ABI Platform
tortoise_imagefield-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 52.3 kB

Release files / tortoise_imagefield-0.2.0.tar.gz

Download URL tortoise_imagefield-0.2.0.tar.gz
Size 26.5 kB
Tags Source
SHA-256 checksum
How to use checksums
3efa448189eea1030739d2c1ef3f657614303cfd1327bf7cae237c5092c76f09
BLAKE2b-256 checksum
How to use checksums
4c8fcc3bbbafd9605180d976398cde43194a14aaf00d85c73833828880558e23
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Release files / tortoise_imagefield-0.2.0-py3-none-any.whl

Download URL tortoise_imagefield-0.2.0-py3-none-any.whl
Size 25.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bf640eb8f23b6f8724e9ab39deb8a0a6349af121ee433288cb4dad28f13589fa
BLAKE2b-256 checksum
How to use checksums
3fd66222ec8130617332d99ae20001dcc88183c4cdda49f3c05a1754de9fedf3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page