Skip to main content

Blazing-fast thumbnail generator from image/video URLs (pyvips primary + Pillow fallback)

Project description

thumbnail-generator

thumbnail-generator is a tiny, modern toolkit for creating thumbnails directly from remote image URLs. It streams the source file, transforms it entirely in memory, and returns ready-to-serve bytes. The library powers a Python API, an async helper, and a Typer-based CLI. Pillow is used out of the box; drop in pyvips for big speed wins with constant memory usage.


Project Highlights

  • Stream thumbnails straight from HTTPS URLs without writing to disk.
  • Automatic EXIF orientation correction and high-quality downsampling.
  • Unified crop modes: fit, fill, pad, and smart (smart switches to libvips smartcrop when available).
  • Multiple output formats (JPEG, WEBP, AVIF, PNG) with adjustable quality.
  • Async helper for event-driven crawlers.
  • CLI command for quick batch jobs or scripting.
  • Optional libvips backend (5–10× faster than Pillow on large images).

Current scope:

  • Image thumbnails are production ready (Pillow fallback + libvips optional).
  • Async helper delegates to the active backend (libvips or Pillow).
  • Video thumbnail extraction is not yet implemented; a stub is exported so the public API stays stable.

Requirements

  • Python 3.9 or newer (repository is tested with Python 3.12).
  • Linux, macOS, or Windows.
  • Optional: system libvips if you plan to use the high-performance backend.
    • Ubuntu/Debian: sudo apt install libvips
    • macOS: brew install vips
    • Windows: install the prebuilt libvips bundle from libvips releases and add it to PATH.

Note on Anaconda: when using libvips, keep Python and the native libraries from the same toolchain. Mixing a conda-based Python with system libvips often results in loader errors. Creating a virtual environment from /usr/bin/python3 (Linux/macOS) or using a clean conda environment that installs libvips from conda-forge solves this.


Installation

PyPI (recommended)

pip install thumbnail-generator

Add the high-performance backend:

pip install thumbnail-generator[vips]

The CLI depends on Typer and is bundled automatically from version 0.1.1 onward. If you are on 0.1.0, run pip install typer once or upgrade: pip install --upgrade thumbnail-generator.

From Source

git clone https://github.com/chrisppa/thumbnail-generator.git
cd thumbnail-generator

python3 -m venv venv          # /usr/bin/python3 on Linux
source venv/bin/activate      # .\venv\Scripts\activate on Windows
pip install -U pip

pip install -e .              # Pillow backend
pip install -e .[vips]        # Optional libvips backend

Keep the virtual environment active whenever you run the CLI or tests:

source venv/bin/activate

Usage

CLI

thumbnail-generator https://images.unsplash.com/photo-1682687220742-aba13b6e50ba \
  --size 800x800 \
  --crop smart \
  --format WEBP \
  --output hero.webp

Options (via thumbnail-generator --help):

  • --output – destination file path (default thumb.jpg).
  • --size<width>x<height> integers (default 400x400).
  • --crop – one of fit, fill, smart, pad.
  • --formatJPEG, WEBP, AVIF, PNG.
  • --quality – integer 1–100 (backend-specific defaults to 90).

When pyvips is available the CLI reports Saved … using vips backend, otherwise Pillow is used automatically.

Python API

from thumbnail_generator import thumbnail_from_url, CropMode

buf = thumbnail_from_url(
    "https://example.com/large.jpeg",
    size=(500, 300),
    crop=CropMode.FILL,
    format="WEBP",
    quality=85,
)

with open("thumb.webp", "wb") as fp:
    fp.write(buf.getvalue())

Async API

import asyncio
from thumbnail_generator import athumbnail_from_url

async def main():
    buf = await athumbnail_from_url(
        "https://example.com/scene.jpg",
        size=(320, 320),
    )
    with open("async-thumb.jpg", "wb") as fp:
        fp.write(buf.getbuffer())

asyncio.run(main())

The async helper uses the currently active backend under the hood.

Video API (planned)

thumbnail_generator.video_thumbnail_from_url() currently raises NotImplementedError. The stub exists so the import surface is ready when ffmpeg integration lands.


Backends Explained

Backend Activation Strengths Notes
Pillow Installed automatically with pip install -e . Zero native deps, works everywhere Best for small/medium images
libvips Install libvips + pip install -e .[vips] Fast, constant memory, smart cropping available Requires OS-level libvips libraries
  • CropMode.FIT: fits inside the target box, preserving aspect ratio.
  • CropMode.FILL: fills the target box by scaling and center-cropping.
  • CropMode.SMART: same as FILL; if libvips is active, switches to smartcrop.
  • CropMode.PAD: letterboxes the image on a background color.

Output formats are passed straight to the backend. The default quality is 90; adjust for smaller files or higher fidelity.


Development Workflow

source venv/bin/activate
pip install -e .[dev,vips]  # add dev extras when they land
pytest                      # once the test suite is added
python -m thumbnail_generator.cli --help

Recommended extras (when available) include Ruff for linting, Mypy for typing, and pytest with responses for mocking HTTP downloads.


Troubleshooting

  • ImportError: cannot load library 'libvips.so.42'
    Ensure libvips is installed system-wide and that your Python runtime comes from the same toolchain. Recreate the virtualenv with /usr/bin/python3 or use a dedicated conda env with conda install -c conda-forge libvips.

  • PyPI install without libvips
    If you install the package elsewhere and want to force Pillow, omit the [vips] extra or pip uninstall pyvips.

  • NotImplementedError for video
    Video thumbnailing is on the roadmap; the current placeholder signals that this API surface is reserved.

  • Timeouts fetching images
    The default HTTP timeout is 30 seconds. If you need retries, wrap thumbnail_from_url in your own retry logic or extend DEFAULT_HEADERS/DEFAULT_TIMEOUT in core.py.


Roadmap

  • Smart crop improvements (face/saliency detection fallback when Pillow is active).
  • Configurable caching (memory/disk).
  • CLI batch mode with globbing and progress indicators.
  • Video frame extraction using ffmpeg-python.

License

MIT © chrisppa

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

thumbnail_generator-0.1.1.tar.gz (6.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

thumbnail_generator-0.1.1-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

Details for the file thumbnail_generator-0.1.1.tar.gz.

File metadata

  • Download URL: thumbnail_generator-0.1.1.tar.gz
  • Upload date:
  • Size: 6.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.28.1

File hashes

Hashes for thumbnail_generator-0.1.1.tar.gz
Algorithm Hash digest
SHA256 74a11044944a2593c12d40d67a6ff815bd06138ae28b2b9b2b949090e53c6a64
MD5 21021fcc02dd1771e6aa7b1f7b829587
BLAKE2b-256 c976a26a31cc9ce87e8f05f90fd069d101e266f6ec4fc066aec9b8347a902bf0

See more details on using hashes here.

File details

Details for the file thumbnail_generator-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for thumbnail_generator-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 239e9e72cd5189237a94d34fd7a871c65b6061ba2ee177f633877063f6936152
MD5 93db2457c7da8744d95e9090c6b7c8ca
BLAKE2b-256 1f4b4f6bc5555e707e2ffbcf3de2f42553f1ce9945400027a3dcf97e2244a698

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page