Skip to content

Repository files navigation

Thumbnail API - Production-Ready REST API

Overview

A production-ready REST API service for image thumbnail generation built with FastAPI and Python. The service accepts image uploads, resizes them into thumbnails using preset sizes or custom dimensions, and returns metadata about the generated thumbnails.

Features

  • ✅ Async-first architecture using FastAPI + Uvicorn
  • ✅ Support for multiple image formats (JPEG, PNG, WebP, GIF)
  • ✅ Preset sizes (thumbnail, small, medium, large)
  • ✅ Custom dimension support
  • ✅ Aspect ratio preservation
  • ✅ Comprehensive input validation & error handling
  • ✅ Concurrent request handling (async/await)
  • ✅ Automatic OpenAPI documentation (/docs)
  • ✅ Full test coverage with pytest
  • ✅ CI/CD pipeline with GitHub Actions
  • ✅ Docker support for easy deployment
  • ✅ Production-grade logging & health checks

Quick Start

Prerequisites

  • Python 3.11+
  • pip or poetry

Installation

# Clone repository
git clone <repository-url>
cd thumbnail-api

# Create virtual environment
python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

Running the Server

# Development (with auto-reload)
python -m app.main

# Or using uvicorn directly
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

The API will be available at: http://localhost:8000

  • Interactive API docs: http://localhost:8000/docs
  • ReDoc documentation: http://localhost:8000/redoc

API Endpoints

Generate Thumbnail

POST /api/thumbnails

Upload an image and generate a thumbnail.

Request:

curl -X POST "http://localhost:8000/api/thumbnails" \
  -F "file=@image.jpg" \
  -F "preset=small"

Using custom dimensions:

curl -X POST "http://localhost:8000/api/thumbnails" \
  -F "file=@image.jpg" \
  -F "custom_width=400" \
  -F "custom_height=300" \
  -F "preserve_aspect_ratio=true"

Response:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "metadata": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "original_filename": "image.jpg",
    "original_width": 1920,
    "original_height": 1080,
    "original_format": "jpeg",
    "thumbnail_width": 300,
    "thumbnail_height": 300,
    "file_size_bytes": 15234,
    "created_at": "2026-02-24T10:30:45.123456"
  },
  "download_url": "/api/thumbnails/550e8400-e29b-41d4-a716-446655440000/download"
}

Get Thumbnail Metadata

GET /api/thumbnails/{thumbnail_id}

Download Thumbnail

GET /api/thumbnails/{thumbnail_id}/download

List Available Presets

GET /api/thumbnails/presets

Response:

[
  {
    "name": "thumbnail",
    "width": 150,
    "height": 150
  },
  {
    "name": "small",
    "width": 300,
    "height": 300
  },
  {
    "name": "medium",
    "width": 600,
    "height": 600
  },
  {
    "name": "large",
    "width": 1200,
    "height": 1200
  }
]

Health Check

GET /health

Configuration

Create a .env file based on .env.example:

# Application
APP_NAME=Thumbnail API
DEBUG=False
LOG_LEVEL=INFO

# Server
HOST=0.0.0.0
PORT=8000

# File Storage
STORAGE_PATH=./uploads
THUMBNAIL_PATH=./thumbnails
MAX_FILE_SIZE_MB=50

# Image Processing
ALLOWED_FORMATS=jpg,jpeg,png,webp,gif
ENABLE_CORS=True

Running Tests

# Run all tests
pytest -v

# With coverage report
pytest --cov=app --cov-report=html

# Run specific test file
pytest tests/test_api.py -v

# Run tests matching pattern
pytest -k "test_generate_thumbnail" -v

Project Structure

thumbnail-api/
├── app/
│   ├── __init__.py
│   ├── config.py              # Configuration management
│   ├── main.py                # FastAPI app factory
│   ├── schemas.py             # Pydantic models
│   ├── api/
│   │   ├── __init__.py
│   │   └── routes.py          # API endpoints
│   ├── services/
│   │   ├── __init__.py
│   │   ├── image_service.py   # Image processing logic
│   │   └── storage.py         # File storage operations
│   └── utils/
│       ├── __init__.py
│       └── validators.py      # Input validation
├── tests/
│   ├── __init__.py
│   ├── conftest.py            # Pytest fixtures
│   ├── test_api.py            # API endpoint tests
│   └── test_services.py       # Service layer tests
├── .github/
│   └── workflows/
│       └── ci.yml             # GitHub Actions CI/CD
├── requirements.txt
├── pytest.ini
├── .gitignore
├── Dockerfile
├── docker-compose.yml
├── .env.example
└── README.md

Docker Deployment

Build and Run

# Build image
docker build -t thumbnail-api:latest .

# Run container
docker run -p 8000:8000 \
  -v $(pwd)/uploads:/app/uploads \
  -v $(pwd)/thumbnails:/app/thumbnails \
  thumbnail-api:latest

Using Docker Compose

docker-compose up -d
docker-compose down

CI/CD Pipeline

This project includes a GitHub Actions workflow (.github/workflows/ci.yml) that:

  • Runs on every push and pull request
  • Runs the full test suite
  • Checks code coverage
  • Validates code formatting

Performance & Concurrency

  • Async Architecture: FastAPI + Uvicorn handle hundreds of concurrent requests
  • Non-blocking I/O: Async file operations via aiofiles
  • Image Processing: Pillow with efficient JPEG encoding
  • Worker Processes: Run multiple Uvicorn workers for horizontal scaling

For production, run multiple workers:

uvicorn app.main:app --workers 4 --host 0.0.0.0 --port 8000

Error Handling

All endpoints return appropriate HTTP status codes:

  • 201: Thumbnail created successfully
  • 400: Bad request (validation errors)
  • 404: Resource not found
  • 422: Validation error
  • 500: Server error

Error response format:

{
  "error": "Error type",
  "detail": "Detailed error message",
  "status_code": 400
}

Contributing

  1. Create a feature branch
  2. Make changes and ensure tests pass
  3. Submit a pull request

License

MIT License - See LICENSE file for details

Support

For issues, feature requests, or questions, please open an issue on GitHub.

About

Accepts an image and generates a thumbnail..

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages