libthumbor is a Python library for composing, signing, and parsing
thumbor image URLs.
It helps applications generate thumbor-compatible URLs safely, keep signing logic in one place, and reuse the same URL-building rules across services.
- Generate signed thumbor URLs with
CryptoURL - Compose transformation paths with
Url.generate_options() - Parse decrypted thumbor paths with
Url.parse_decrypted() - Validate signatures with the bundled signer implementation
- Use the included Django view for simple URL generation endpoints
- Python 3.10+
pip install libthumborFor local development, use:
make setupGenerate a signed thumbor URL:
from libthumbor import CryptoURL
crypto = CryptoURL(key="my-security-key")
url = crypto.generate(
width=300,
height=200,
smart=True,
image_url="images.example.com/photo.jpg",
)
print(url)The generated URL follows thumbor's signed URL format:
/<signature>/300x200/smart/images.example.com/photo.jpg
Generate an unsafe URL when signing is intentionally disabled:
from libthumbor.crypto import CryptoURL
crypto = CryptoURL(key="my-security-key")
url = crypto.generate(
unsafe=True,
width=300,
height=200,
image_url="images.example.com/photo.jpg",
)
print(url)Output structure:
unsafe/300x200/images.example.com/photo.jpg
If you want only the thumbor transformation path, use Url.generate_options():
from libthumbor import Url
path = Url.generate_options(
width=300,
height=200,
smart=True,
fit_in=True,
halign="left",
valign="top",
filters="brightness(10):contrast(5)",
)
print(path)Output:
fit-in/300x200/left/top/smart/filters:brightness(10):contrast(5)
Url.parse_decrypted() parses a thumbor path without the leading signature:
from libthumbor import Url
data = Url.parse_decrypted(
"meta/10x20:200x300/adaptive-full-fit-in/-400x-300/"
"left/top/smart/filters:brightness(100)/images.example.com/photo.jpg"
)
print(data["width"])
print(data["height"])
print(data["smart"])
print(data["image"])The library supports the transformation pieces covered by the test suite and thumbor-compatible URL composer:
width,heightcrop=((left, top), (right, bottom))fit_in,full_fit_inadaptive_fit_in,adaptive_full_fit_inflip,flophalignwithleft,center,rightvalignwithtop,middle,bottomsmarttrimfiltersmetaunsafe
The package also exposes the bundled signer implementation:
from libthumbor import Signer
signer = Signer("my-security-key")
signature = signer.signature("300x200/image.jpg").decode("ascii")This is useful when you need lower-level signing or signature validation
outside CryptoURL.
libthumbor ships with a simple Django view that returns a generated thumbor
URL as plain text.
Settings:
THUMBOR_SECURITY_KEY = "my-security-key"
THUMBOR_SERVER = "http://localhost:8888/"URL config:
from django.urls import include, path
urlpatterns = [
path("", include("libthumbor.django.urls")),
]Example request:
GET /gen_url/?image_url=images.example.com/photo.jpg&width=300&height=200
Install dependencies:
make setupInstall the local git hooks:
make pre-commit-installRun the main validation flow:
make testRun individual checks:
make unit
make coverage
make black
make flake8
make isort-check
make pylint
make pre-commit- The project targets Python 3.10 and newer.
- URL signing is compatibility-sensitive. Changes in signing or URL composition should be reviewed carefully.
- If you change URL semantics, verify that previously generated signed URLs still behave as expected.
MIT