SQLAlchemy field for signed URLs from private object storage
Project description
sqlalchemy-signed-url
sqlalchemy-signed-url is a small utility library that helps you work with private object storage (S3, GCS, etc.) at the SQLAlchemy field level.
The core idea is simple:
- Store only object keys in the database
- Generate signed URLs (presigned URLs) only at read/serialization time
- Keep upload and write operations explicit and outside the ORM
This library provides a clean, repeatable pattern for doing exactly that.
Motivation
In systems that use private object storage, the following pattern is very common:
- Files live in a private bucket/container
- The database stores a full storage URI, not a public-facing URL.
- Clients receive a short-lived signed URL when data is returned
- Upload and download logic is handled explicitly in the application layer
In practice, this logic often ends up:
- Scattered across serializers and service layers, or
- Reimplemented slightly differently for each model
Over time, this makes consistency and maintenance difficult.
sqlalchemy-signed-url moves this pattern to the model field level, so it can be declared once and reused everywhere.
Example
1. Configure storage (once)
from sqlalchemy_signed_url import ObjectStorage
from sqlalchemy_signed_url.signers.s3 import S3PresignedURLSigner
# Let the signer create its own boto3 client
ObjectStorage.initialize(
signer=S3PresignedURLSigner(bucket="my-bucket", region_name="us-east-1"),
)
# If you already have a preconfigured boto3 S3 client,
# the signer will use it as-is and ignore region_name.
ObjectStorage.initialize(
signer=S3PresignedURLSigner(bucket="my-bucket", client=preconfigured_client)
)
2. Declare a model
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy_signed_url import SignedURLField
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
profile_image = SignedURLField(base_path="users/profile")
3. Save (assign raw key)
# The field automatically provides:
# - <field>_key → raw key accessor
# - <field>_location → (bucket, object_key) for uploading
# - <field>_signed_url → on-demand presigned URL
# Assign a raw key to the model (no upload yet)
user = User(profile_image_key="avatar.png")
# Get upload destination from the model
bucket, key = user.profile_image_location
# Upload the file yourself
s3_client.upload_file("local/path/avatar.png", bucket, key)
# Save the key to the database
session.add(user)
session.commit()
4. Read
user.profile_image
# "s3://my-bucket/users/profile/avatar.png"
user.profile_image_key
# "avatar.png"
user.profile_image_signed_url
# presigned URL
Status
✅ Implemented
- S3-based presigned URL generation (read-only)
- Instance-level caching of presigned URLs
- Cache per ORM instance
- Invalidate cache when
<field>_keychanges
- Allow injecting storage client
🚧 Planned
-
Support additional storage providers
- Google Cloud Storage (GCS)
- Microsoft Azure Blob Storage
- Other S3-compatible storages
-
Presigned URL for uploads
- Generate upload URLs (e.g.
PUT,POST) - Separate read/write URL configuration
- Optional constraints (content-type, max size, etc.)
- Generate upload URLs (e.g.
-
Validate Alembic compatibility
- Confirm autogenerate behavior with
SignedURLField
- Confirm autogenerate behavior with
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 sqlalchemy_signed_url-0.1.0.tar.gz.
File metadata
- Download URL: sqlalchemy_signed_url-0.1.0.tar.gz
- Upload date:
- Size: 7.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28702d25b12f8b00ec738da0d08fccf8129b3af348e5efebd3bb93618805681c
|
|
| MD5 |
58a664fedb66a20f0cfecb49a09aa366
|
|
| BLAKE2b-256 |
1f5e38fec5843237bdc0067510ec6e4becf83ae22f844639bddb11cd724e925c
|
File details
Details for the file sqlalchemy_signed_url-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sqlalchemy_signed_url-0.1.0-py3-none-any.whl
- Upload date:
- Size: 6.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
370ce9af8ef503163cc14802ccb232f143129f67e528c78b22db82316a64e017
|
|
| MD5 |
ec40afd0474b4490b18dc1280e1cbaf8
|
|
| BLAKE2b-256 |
ad90c95b3bf563744a8e8842d8a885754c58215cd1a2cee3c1528b3af84492eb
|