- Changed getRefreshParams() to parse query params instead of path segments - Added buildUrl() helper to construct query param URLs - Updated keyboard shortcuts (j/k for delay, o for order toggle) to use query params
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
Using UV (Recommended)
# 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 fileGET /{order}/{delay}- Redirect to random file with order/delay settingsGET /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 indexingfrontend.html- HTML template for the user interfaceFileIndexer- Base class for indexing files from directoriesZipFileIndexer- Extension for indexing files from ZIP archives- Global
file_mappingdictionary - Maps hashes to file paths/filenames
Adding New Features
- New Indexer Types: Create a class inheriting from
FileIndexerand override the_index()method - New Routes: Add functions decorated with appropriate HTTP method decorators (
@app.get, etc.) - UI Changes: Modify
frontend.htmltemplate 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
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Open a pull request
Please ensure your code follows the existing style and includes appropriate tests.
Description
Languages
Python
90.7%
HTML
9.3%