- Add comprehensive REST API for download queue management
- Implement GET /api/queue/status endpoint with queue status and statistics
- Implement POST /api/queue/add for adding episodes to queue with priority support
- Implement DELETE /api/queue/{id} and DELETE /api/queue/ for removing items
- Implement POST /api/queue/start and /api/queue/stop for queue control
- Implement POST /api/queue/pause and /api/queue/resume for pause/resume
- Implement POST /api/queue/reorder for queue item reordering
- Implement DELETE /api/queue/completed for clearing completed items
- Implement POST /api/queue/retry for retrying failed downloads
- Add get_download_service and get_anime_service dependencies
- Register download router in FastAPI application
- Add comprehensive test suite for all endpoints
- All endpoints require JWT authentication
- Update infrastructure documentation
- Remove completed task from instructions.md
Follows REST conventions with proper error handling and status codes.
Tests cover success cases, error conditions, and authentication requirements.
20 KiB
Aniworld Web Application Infrastructure
conda activate AniWorld
Project Structure
/home/lukas/Volume/repo/Aniworld/
├── src/
│ ├── server/ # FastAPI web application
│ │ ├── fastapi_app.py # Main FastAPI application (simplified)
│ │ ├── main.py # FastAPI application entry point
│ │ ├── controllers/ # Route controllers
│ │ │ ├── __init__.py # Controllers package
│ │ │ ├── health_controller.py # Health check endpoints
│ │ │ ├── page_controller.py # HTML page routes
│ │ │ └── error_controller.py # Error handling controllers
│ │ ├── api/ # API route handlers
│ │ │ ├── __init__.py
│ │ │ ├── auth.py # Authentication endpoints
│ │ │ ├── config.py # Configuration endpoints
│ │ │ ├── anime.py # Anime management endpoints
│ │ │ ├── download.py # Download queue endpoints
│ │ │ └── search.py # Search endpoints
│ │ ├── models/ # Pydantic models
│ │ │ ├── __init__.py
│ │ │ ├── auth.py
│ │ │ ├── config.py
│ │ │ ├── anime.py
│ │ │ └── download.py
│ │ ├── services/ # Business logic services
│ │ │ ├── __init__.py
│ │ │ ├── auth_service.py
│ │ │ ├── config_service.py
│ │ │ ├── anime_service.py
│ │ │ └── download_service.py
│ │ ├── utils/ # Utility functions
│ │ │ ├── __init__.py
│ │ │ ├── security.py
│ │ │ ├── dependencies.py # Dependency injection
│ │ │ └── templates.py # Shared Jinja2 template config
│ │ └── web/ # Frontend assets
│ │ ├── templates/ # Jinja2 HTML templates
│ │ │ ├── base.html
│ │ │ ├── login.html
│ │ │ ├── setup.html
│ │ │ ├── config.html
│ │ │ ├── anime.html
│ │ │ ├── download.html
│ │ │ └── search.html
│ │ └── static/ # Static web assets
│ │ ├── css/
│ │ ├── js/
│ │ └── images/
│ ├── core/ # Existing core functionality
│ └── cli/ # Existing CLI application
├── data/ # Application data storage
│ ├── config.json # Application configuration
│ ├── anime_library.db # SQLite database for anime library
│ ├── download_queue.json # Download queue state
│ └── cache/ # Temporary cache files
├── logs/ # Application logs
│ ├── app.log # Main application log
│ ├── download.log # Download-specific logs
│ └── error.log # Error logs
├── requirements.txt # Python dependencies
├── docker-compose.yml # Docker deployment configuration
└── README.md
Technology Stack
Backend
- FastAPI: Modern Python web framework for building APIs
- Uvicorn: ASGI server for running FastAPI applications
- SQLite: Lightweight database for storing anime library and configuration
- Pydantic: Data validation and serialization
- Jinja2: Template engine for server-side rendering
Frontend
- HTML5/CSS3: Core web technologies
- JavaScript (Vanilla): Client-side interactivity
- Bootstrap 5: CSS framework for responsive design
- HTMX: Modern approach for dynamic web applications
Security
- Passlib: Password hashing and verification
- python-jose: JWT token handling
- bcrypt: Secure password hashing
Authentication Models & Sessions
- Authentication request/response Pydantic models live in
src/server/models/auth.py. - Sessions are represented by
SessionModeland can be backed by an in-memory store or a persistent table depending on deployment needs. JWTs are used for stateless authentication by default; a persistent session store may be configured in production to enable revocation and long-lived sessions.
Configuration
Data Storage
- Configuration: JSON files in
data/directory - Anime Library: SQLite database with series information
- Download Queue: JSON file with current download status
- Logs: Structured logging to files in
logs/directory
API Endpoints
Authentication
POST /api/auth/login- Master password authenticationPOST /api/auth/logout- Logout and invalidate sessionGET /api/auth/status- Check authentication status
Configuration
GET /api/config- Get current configurationPUT /api/config- Update configurationPOST /api/setup- Initial setup
Configuration API Notes
- The configuration endpoints are exposed under
/api/configand operate primarily on a JSON-serializableAppConfigmodel. They are designed to be lightweight and avoid performing IO during validation (the/api/config/validateendpoint runs in-memory checks only). - Persistence of configuration changes is intentionally "best-effort" for now and mirrors fields into the runtime settings object. A follow-up task should add durable storage (file or DB) for configs.
Anime Management
GET /api/anime- List anime with missing episodesPOST /api/anime/{id}/download- Add episodes to download queueGET /api/anime/{id}- Get anime details
Note: The anime management API has been implemented under /api/v1/anime with
endpoints for listing series with missing episodes, searching providers,
triggering a local rescan, and fetching series details. The implementation
delegates to the existing core SeriesApp and uses dependency injection for
initialization.
Download Management
GET /api/queue/status- Get download queue status and statisticsPOST /api/queue/add- Add episodes to download queueDELETE /api/queue/{id}- Remove item from queueDELETE /api/queue/- Remove multiple items from queuePOST /api/queue/start- Start download queue processingPOST /api/queue/stop- Stop download queue processingPOST /api/queue/pause- Pause queue processingPOST /api/queue/resume- Resume queue processingPOST /api/queue/reorder- Reorder pending queue itemsDELETE /api/queue/completed- Clear completed downloadsPOST /api/queue/retry- Retry failed downloads
Search
GET /api/search?q={query}- Search for animePOST /api/search/add- Add anime to library
Logging
Log Levels
- INFO: General application information
- WARNING: Potential issues that don't stop execution
- ERROR: Errors that affect functionality
- DEBUG: Detailed debugging information (development only)
Log Files
app.log: General application logsdownload.log: Download-specific operationserror.log: Error and exception logs
Security Considerations
- Master password protection for application access
- Secure session management with JWT tokens
- Input validation and sanitization
- Rate limiting on API endpoints
- HTTPS enforcement in production
- Secure file path handling to prevent directory traversal
Authentication Service
- A lightweight authentication service is provided by
src/server/services/auth_service.py. - Uses bcrypt (passlib) to hash the master password and issues JWTs for
stateless sessions. Tokens are signed with the
JWT_SECRET_KEYfrom configuration and expire based onSESSION_TIMEOUT_HOURS. - Failed login attempts are tracked in-memory and a temporary lockout is applied after multiple failures. For multi-process deployments, move this state to a shared store (Redis) and persist the master password hash in a secure config store.
Recent Infrastructure Changes
Route Controller Refactoring (October 2025)
Restructured the FastAPI application to use a controller-based architecture for better code organization and maintainability.
Changes Made
-
Created Controller Structure:
src/server/controllers/- New directory for route controllerssrc/server/controllers/__init__.py- Controllers package initializationsrc/server/controllers/health_controller.py- Health check endpointssrc/server/controllers/page_controller.py- HTML page routessrc/server/controllers/error_controller.py- Error handling controllers
-
Shared Template Configuration:
src/server/utils/templates.py- Centralized Jinja2 template configuration- Fixed template path resolution for proper template loading
-
Main Application Updates:
src/server/fastapi_app.py- Refactored to use controller routers- Removed direct route definitions from main file
- Added router inclusion using
app.include_router() - Simplified error handlers to delegate to controller functions
-
Fixed Import Issues:
- Resolved circular import in
src/core/__init__.py - Removed non-existent
applicationmodule import
- Resolved circular import in
Controller Architecture
Anime Service Notes
- The new
anime_serviceruns the existing blockingSeriesAppinside a threadpool (via ThreadPoolExecutor). This keeps the FastAPI event loop responsive while leveraging the existing core logic. - A small in-process LRU cache is used for the frequently-read "missing episodes" list to reduce IO; cache invalidation happens after a rescan.
- For multi-worker or multi-host deployments, move cache/state to a shared store (Redis) and ensure the threadpool sizing matches the worker's CPU and IO profile.
Health Controller (health_controller.py):
router = APIRouter(prefix="/health", tags=["health"])
@router.get("") - Health check endpoint
Page Controller (page_controller.py):
router = APIRouter(tags=["pages"])
@router.get("/") - Main application page
@router.get("/setup") - Setup page
@router.get("/login") - Login page
@router.get("/queue") - Download queue page
Error Controller (error_controller.py):
async def not_found_handler() - Custom 404 error handling
async def server_error_handler() - Custom 500 error handling
Benefits of the New Structure
- Separation of Concerns: Each controller handles specific functionality
- Modularity: Easy to add new controllers and routes
- Testability: Controllers can be tested independently
- Maintainability: Cleaner code organization and easier debugging
- Scalability: Simple to extend with new features
Verified Working Endpoints
All endpoints tested and confirmed working:
- Health:
/health→ Returns{"status": "healthy", ...} - Root:
/→ Serves main application page - Setup:
/setup→ Serves setup page - Auth API:
/api/auth/*→ Endpoints for setup, login, logout and status (JWT-based) - Login:
/login→ Serves login page - Queue:
/queue→ Serves download queue page
File Structure After Refactoring
src/server/
├── fastapi_app.py # Main FastAPI application (simplified)
├── controllers/ # NEW: Route controllers
│ ├── __init__.py # Controllers package
├── utils/
│ ├── dependencies.py # Existing dependency injection
│ └── templates.py # NEW: Shared Jinja2 template config
└── web/ # Existing frontend assets
├── templates/ # HTML templates
└── static/ # CSS, JS, images
Authentication Middleware (October 2025)
An authentication middleware component was added to the FastAPI application to centralize token parsing and provide lightweight protection of authentication endpoints:
src/server/middleware/auth.pyimplements:- Bearer JWT parsing and session attachment to
request.state.session - A simple per-IP in-memory rate limiter applied to
/api/auth/loginand/api/auth/setup(default 5 requests/minute)
- Bearer JWT parsing and session attachment to
Notes:
- This is intentionally simple and designed for single-process deployments. For production use across multiple workers or hosts, replace the in-memory limiter with a distributed store (e.g. Redis) and add a persistent token revocation list if needed.
API Models and Contracts
- Pydantic models living in
src/server/models/define the canonical API contracts used by FastAPI endpoints. These models are intentionally lightweight and focused on serialization, validation, and OpenAPI documentation generation. - Keep models stable: changes to model shapes are breaking changes for clients. Bump API versioning or provide migration layers when altering public response fields.
- Infrastructure considerations: ensure the deployment environment has
required libraries (e.g.,
pydantic) installed and that schema validation errors are logged to the centralized logging system. For high-throughput routes, consider response model caching at the application or reverse-proxy layer.
Download Queue Models
- Download queue models in
src/server/models/download.pydefine the data structures for the download queue system. - Key models include:
DownloadItem: Represents a single queued download with metadata, progress tracking, and error informationQueueStatus: Overall queue state with active, pending, completed, and failed downloadsQueueStats: Aggregated statistics for monitoring queue performanceDownloadProgress: Real-time progress information (percent, speed, ETA)DownloadRequest/DownloadResponse: API request/response contracts
- Models enforce validation constraints (e.g., positive episode numbers, progress percentage 0-100, non-negative retry counts) and provide clean JSON serialization for API endpoints and WebSocket updates.
Download Queue Service
- The download service (
src/server/services/download_service.py) manages the complete lifecycle of anime episode downloads. - Core features:
- Priority-based Queue: Items added with HIGH priority are processed first, NORMAL and LOW follow in FIFO order
- Concurrent Processing: Configurable max concurrent downloads (default 2) to optimize bandwidth usage
- Persistence: Queue state is automatically saved to
data/download_queue.jsonand recovered on service restart - Retry Logic: Failed downloads are automatically retried up to a configurable limit (default 3 attempts) with exponential backoff
- Progress Tracking: Real-time download progress with speed, percentage, and ETA calculations
- WebSocket Integration: Broadcasts queue updates, progress, and completion/failure events to connected clients
- Operations:
add_to_queue(): Add episodes to download queue with priorityremove_from_queue(): Cancel pending or active downloadsreorder_queue(): Manually adjust queue order for pending itemspause_queue()/resume_queue(): Control download processingretry_failed(): Retry failed downloads with retry count checksget_queue_status(): Get complete queue state (active, pending, completed, failed)get_queue_stats(): Get aggregated statistics (counts, download size, speed)
- Infrastructure notes:
- Service uses ThreadPoolExecutor for concurrent download processing
- Queue processor runs as async background task with configurable sleep intervals
- Progress callbacks are executed in threadpool and broadcast via async WebSocket
- For multi-process deployments, move queue state to shared store (Redis/DB) and implement distributed locking for concurrent access control
- Singleton instance pattern used via
get_download_service()factory
- Testing: Comprehensive unit tests in
tests/unit/test_download_service.pycover queue operations, persistence, retry logic, and error handling
Download Queue API Endpoints (October 2025)
Implemented comprehensive REST API endpoints for download queue management:
- File:
src/server/api/download.py - Router Prefix:
/api/queue - Authentication: All endpoints require JWT authentication via
require_authdependency
Implemented Endpoints
-
GET /api/queue/status - Retrieve complete queue status
- Returns:
QueueStatusResponsewith status and statistics - Includes: active downloads, pending items, completed/failed items, queue stats
- Returns:
-
POST /api/queue/add - Add episodes to download queue
- Request:
DownloadRequestwith serie info, episodes, and priority - Returns:
DownloadResponsewith added item IDs - Validates episode list is non-empty
- Supports HIGH, NORMAL, and LOW priority levels
- Request:
-
DELETE /api/queue/{item_id} - Remove single item from queue
- Returns: 204 No Content on success, 404 if item not found
- Cancels active downloads if necessary
-
DELETE /api/queue/ - Remove multiple items (batch operation)
- Request:
QueueOperationRequestwith list of item IDs - Returns: 204 No Content (partial success acceptable)
- Request:
-
POST /api/queue/start - Start queue processor
- Idempotent operation (safe to call multiple times)
-
POST /api/queue/stop - Stop queue processor
- Waits for active downloads to complete (with timeout)
-
POST /api/queue/pause - Pause queue processing
- Active downloads continue, no new downloads start
-
POST /api/queue/resume - Resume queue processing
-
POST /api/queue/reorder - Reorder pending queue item
- Request:
QueueReorderRequestwith item_id and new_position - Returns: 404 if item not in pending queue
- Request:
-
DELETE /api/queue/completed - Clear completed items from history
- Returns count of cleared items
-
POST /api/queue/retry - Retry failed downloads
- Request:
QueueOperationRequestwith item IDs (empty for all) - Only retries items under max retry limit
- Request:
Dependencies
- get_download_service: Factory function providing singleton DownloadService instance
- Automatically initializes AnimeService as dependency
- Raises 503 if anime directory not configured
- get_anime_service: Factory function providing singleton AnimeService instance
- Required by DownloadService for anime operations
- Both dependencies added to
src/server/utils/dependencies.py
Error Handling
- All endpoints return structured JSON error responses
- HTTP status codes follow REST conventions (200, 201, 204, 400, 401, 404, 500, 503)
- Service-level exceptions (DownloadServiceError) mapped to 400 Bad Request
- Generic exceptions mapped to 500 Internal Server Error
- Authentication errors return 401 Unauthorized
Testing
- Comprehensive test suite in
tests/api/test_download_endpoints.py - Tests cover:
- Successful operations for all endpoints
- Authentication requirements
- Error conditions (empty lists, not found, service errors)
- Priority handling
- Batch operations
- Uses pytest fixtures for authenticated client and mocked download service
Integration
- Router registered in
src/server/fastapi_app.pyviaapp.include_router(download_router) - Follows same patterns as other API routers (auth, anime, config)
- Full OpenAPI documentation available at
/api/docs