image_server/README.md

5.5 KiB

Image Server

A FastAPI-based image server that serves files from directories or ZIP archives using hashed paths for secure, randomized access. The server provides a beautiful full-screen image viewing experience with navigation controls and optional auto-advance features.

Features

  • Secure File Access: Files are accessed via SHA-256 hashes of their paths (with salt) rather than direct file paths
  • Multiple Sources: Supports serving from directories, individual ZIP files, or glob patterns (e.g., *.zip)
  • Beautiful UI: Full-screen responsive image viewer with keyboard navigation
  • Navigation Controls:
    • Previous/Next buttons (clickable chevrons or arrow keys)
    • Random access mode
    • Ordered sequential access with configurable delay
    • Play/pause toggle for auto-advance
  • Keyboard Shortcuts:
    • Left/Right Arrow or H/L: Navigate previous/next
    • Space: Toggle play/pause
    • +/= or J: Increase slide delay
      • or K: Decrease slide delay
    • O: Toggle between ordered and random modes
  • MIME Type Detection: Automatically sets correct content types for served files
  • Health Check Endpoint: Monitor server status and indexed file count

Installation

Prerequisites

  • Python 3.13 or higher
  • UV package manager (recommended) or pip
# Clone the repository
git clone <repository-url>
cd image_server

# Install dependencies
uv sync

# Activate virtual environment
source .venv/bin/activate

Using pip

pip install fastapi uvicorn

Usage

Basic Usage

# Serve files from a directory
python main.py /path/to/your/images

# Serve files from a ZIP archive
python main.py /path/to/archive.zip

# Serve files matching a glob pattern
python main.py "path/to/images/*.zip"

Server Options

python main.py [SOURCE] [OPTIONS]

Arguments:
  SOURCE              Path to directory, ZIP archive, or glob pattern (e.g., *.zip, path/to/zips/*.zip)

Options:
  --host TEXT         Host to bind to (default: 0.0.0.0)
  --port INTEGER      Port to bind to (default: 8000)
  --salt TEXT         Salt for hashing file paths (default: random)
  -h, --help          Show help message and exit

Examples

# Start server on default port 8000
python main.py ./photos

# Start server on custom host and port
python main.py ./photos --host 127.0.0.1 --port 3000

# Start server with custom salt for consistent hashing
python main.py ./photos --salt mysecretkey123

# Start server serving from ZIP files
python main.py ./archives/*.zip

API Endpoints

File Access

  • GET /api/{file_hash}/data - Retrieve file data by hash
    • Returns: File content with appropriate Content-Type header
    • Response: StreamingResponse of the file data

Navigation Pages

  • GET /{file_hash} - View file with navigation controls

    • Displays image with previous/next navigation
  • GET /{order}/{delay}/{file_hash} - View file with auto-refresh

    • order: "next" (sequential) or "random"
    • delay: Seconds before auto-advancing
    • file_hash: Starting file hash

Special Endpoints

  • GET / - Redirect to a random file
  • GET /{order}/{delay} - Redirect to random file with order/delay settings
  • GET /api/health - Health check endpoint
    • Returns: JSON with status and file count

How It Works

File Indexing

When started, the server indexes all files from the provided source(s):

  • For directories: Walks the directory tree and indexes all files
  • For ZIP archives: Indexes all files within the archive
  • For glob patterns: Processes each matching file

Each file is assigned a unique SHA-256 hash based on:

  • File path (relative to source or within ZIP)
  • Salt value (random or user-provided)

Security

  • Direct file path access is prevented
  • Files can only be accessed via their cryptographic hashes
  • Salt prevents hash prediction attacks
  • No filesystem traversal vulnerabilities

User Interface

The server serves a single-page application (frontend.html) that provides:

  • Full-screen image display
  • Click-to-navigate on image
  • Chevron buttons for previous/next navigation
  • Play/pause button for auto-advance control
  • Responsive design that works on mobile and desktop

Development

Running in Development Mode

# With auto-reload for development
uvicorn main:app --reload --host 0.0.0.0 --port 8000

Code Structure

  • main.py - Contains all server logic, routing, and file indexing
  • frontend.html - HTML template for the user interface
  • FileIndexer - Base class for indexing files from directories
  • ZipFileIndexer - Extension for indexing files from ZIP archives
  • Global file_mapping dictionary - Maps hashes to file paths/filenames

Adding New Features

  1. New Indexer Types: Create a class inheriting from FileIndexer and override the _index() method
  2. New Routes: Add functions decorated with appropriate HTTP method decorators (@app.get, etc.)
  3. UI Changes: Modify frontend.html template and update template substitution in _render_page()

Dependencies

  • FastAPI - Modern web framework for building APIs
  • Uvicorn - ASGI server for running the application
  • Python Standard Library - hashlib, mimetypes, secrets, zipfile, etc.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Commit your changes
  4. Push to the branch
  5. Open a pull request

Please ensure your code follows the existing style and includes appropriate tests.