Asynchronous Tortoise ORM field for handling image uploads with cropping, caching, and support for AWS S3 or local storage.
Project description
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!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tortoise_imagefield-0.2.0.tar.gz.
File metadata
- Download URL: tortoise_imagefield-0.2.0.tar.gz
- Upload date:
- Size: 26.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3efa448189eea1030739d2c1ef3f657614303cfd1327bf7cae237c5092c76f09
|
|
| MD5 |
ed397c784112f1173a44ef4e16b02190
|
|
| BLAKE2b-256 |
4c8fcc3bbbafd9605180d976398cde43194a14aaf00d85c73833828880558e23
|
File details
Details for the file tortoise_imagefield-0.2.0-py3-none-any.whl.
File metadata
- Download URL: tortoise_imagefield-0.2.0-py3-none-any.whl
- Upload date:
- Size: 25.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bf640eb8f23b6f8724e9ab39deb8a0a6349af121ee433288cb4dad28f13589fa
|
|
| MD5 |
69be23ba7aa4e47e8b10508d73ae2f93
|
|
| BLAKE2b-256 |
3fd66222ec8130617332d99ae20001dcc88183c4cdda49f3c05a1754de9fedf3
|