From 2867ebae09b84dc71c9bdfd7dc58556e2dbac703 Mon Sep 17 00:00:00 2001 From: Lukas Date: Sun, 12 Oct 2025 23:06:29 +0200 Subject: [PATCH] health check --- infrastructure.md | 229 ++++++++--- instructions.md | 408 ++++++++++---------- requirements.txt | 13 + src/core/__init__.py | 8 +- src/server/controllers/__init__.py | 5 + src/server/controllers/error_controller.py | 39 ++ src/server/controllers/health_controller.py | 31 ++ src/server/controllers/page_controller.py | 47 +++ src/server/fastapi_app.py | 97 +++++ src/server/utils/__init__.py | 6 + src/server/utils/dependencies.py | 180 +++++++++ src/server/utils/templates.py | 12 + src/server/web/templates/error.html | 42 ++ 13 files changed, 844 insertions(+), 273 deletions(-) create mode 100644 requirements.txt create mode 100644 src/server/controllers/__init__.py create mode 100644 src/server/controllers/error_controller.py create mode 100644 src/server/controllers/health_controller.py create mode 100644 src/server/controllers/page_controller.py create mode 100644 src/server/fastapi_app.py create mode 100644 src/server/utils/__init__.py create mode 100644 src/server/utils/dependencies.py create mode 100644 src/server/utils/templates.py create mode 100644 src/server/web/templates/error.html diff --git a/infrastructure.md b/infrastructure.md index 1e7a959..18238f8 100644 --- a/infrastructure.md +++ b/infrastructure.md @@ -1,4 +1,5 @@ # Aniworld Web Application Infrastructure + conda activate AniWorld ## Project Structure @@ -7,7 +8,13 @@ conda activate AniWorld /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 @@ -27,22 +34,24 @@ conda activate AniWorld │ │ │ ├── config_service.py │ │ │ ├── anime_service.py │ │ │ └── download_service.py -│ │ ├── static/ # Static web assets -│ │ │ ├── css/ -│ │ │ ├── js/ -│ │ │ └── images/ -│ │ ├── templates/ # Jinja2 HTML templates -│ │ │ ├── base.html -│ │ │ ├── login.html -│ │ │ ├── setup.html -│ │ │ ├── config.html -│ │ │ ├── anime.html -│ │ │ ├── download.html -│ │ │ └── search.html -│ │ └── utils/ # Utility functions -│ │ ├── __init__.py -│ │ ├── security.py -│ │ └── dependencies.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 @@ -62,75 +71,177 @@ conda activate AniWorld ## 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 + +- **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 + +- **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 + +- **Passlib**: Password hashing and verification +- **python-jose**: JWT token handling +- **bcrypt**: Secure password hashing ## 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 + +- **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 authentication -- `POST /api/auth/logout` - Logout and invalidate session -- `GET /api/auth/status` - Check authentication status + +- `POST /api/auth/login` - Master password authentication +- `POST /api/auth/logout` - Logout and invalidate session +- `GET /api/auth/status` - Check authentication status ### Configuration -- `GET /api/config` - Get current configuration -- `PUT /api/config` - Update configuration -- `POST /api/setup` - Initial setup + +- `GET /api/config` - Get current configuration +- `PUT /api/config` - Update configuration +- `POST /api/setup` - Initial setup ### Anime Management -- `GET /api/anime` - List anime with missing episodes -- `POST /api/anime/{id}/download` - Add episodes to download queue -- `GET /api/anime/{id}` - Get anime details + +- `GET /api/anime` - List anime with missing episodes +- `POST /api/anime/{id}/download` - Add episodes to download queue +- `GET /api/anime/{id}` - Get anime details ### Download Management -- `GET /api/downloads` - Get download queue status -- `DELETE /api/downloads/{id}` - Remove from queue -- `POST /api/downloads/priority` - Change download priority + +- `GET /api/downloads` - Get download queue status +- `DELETE /api/downloads/{id}` - Remove from queue +- `POST /api/downloads/priority` - Change download priority ### Search -- `GET /api/search?q={query}` - Search for anime -- `POST /api/search/add` - Add anime to library + +- `GET /api/search?q={query}` - Search for anime +- `POST /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) + +- **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 logs -- `download.log`: Download-specific operations -- `error.log`: Error and exception logs + +- `app.log`: General application logs +- `download.log`: Download-specific operations +- `error.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 \ No newline at end of file +- 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 + +## 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 + +1. **Created Controller Structure**: + + - `src/server/controllers/` - New directory for route controllers + - `src/server/controllers/__init__.py` - Controllers package initialization + - `src/server/controllers/health_controller.py` - Health check endpoints + - `src/server/controllers/page_controller.py` - HTML page routes + - `src/server/controllers/error_controller.py` - Error handling controllers + +2. **Shared Template Configuration**: + + - `src/server/utils/templates.py` - Centralized Jinja2 template configuration + - Fixed template path resolution for proper template loading + +3. **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 + +4. **Fixed Import Issues**: + - Resolved circular import in `src/core/__init__.py` + - Removed non-existent `application` module import + +#### Controller Architecture + +**Health Controller** (`health_controller.py`): + +```python +router = APIRouter(prefix="/health", tags=["health"]) +@router.get("") - Health check endpoint +``` + +**Page Controller** (`page_controller.py`): + +```python +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`): + +```python +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 +- 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 +``` diff --git a/instructions.md b/instructions.md index ee6c2e3..ba50e18 100644 --- a/instructions.md +++ b/instructions.md @@ -15,15 +15,6 @@ The goal is to create a FastAPI-based web application that provides a modern int - **Type Hints**: Use comprehensive type annotations - **Error Handling**: Proper exception handling and logging -## How you work - -1. Task the next task -2. Process the task -3. Make Tests. -4. Remove task from instructions.md -5. Commit in git -6. goto 1. - ## Implementation Order The tasks should be completed in the following order to ensure proper dependencies and logical progression: @@ -41,365 +32,366 @@ The tasks should be completed in the following order to ensure proper dependenci 11. **Deployment and Configuration** - Production setup 12. **Documentation and Error Handling** - Final documentation and error handling +# make the following steps for each task or subtask. make sure you do not miss one + +1. Task the next task +2. Process the task +3. Make Tests. +4. Remove task from instructions.md. +5. Update infrastructure.md +6. Commit in git + ## Core Tasks ### 1. Project Structure Setup -#### [] Create main FastAPI application structure - -- Create `src/server/main.py` -- Configure FastAPI app with CORS, middleware -- Set up static file serving for existing frontend assets -- Configure Jinja2 templates -- Add health check endpoint - #### [] Set up dependency injection system -- Create `src/server/utils/dependencies.py` -- Implement SeriesApp dependency injection -- Add database session dependency -- Create authentication dependency +- []Create `src/server/utils/dependencies.py` +- []Implement SeriesApp dependency injection +- []Add database session dependency +- []Create authentication dependency #### [] Configure logging system -- Create `src/server/utils/logging.py` -- Set up structured logging with multiple handlers -- Configure log rotation and cleanup -- Add request/response logging middleware +- []Create `src/server/utils/logging.py` +- []Set up structured logging with multiple handlers +- []Configure log rotation and cleanup +- []Add request/response logging middleware ### 2. Authentication System #### [] Implement authentication models -- Create `src/server/models/auth.py` -- Define LoginRequest, LoginResponse models -- Add SetupRequest, AuthStatus models -- Include session management models +- []Create `src/server/models/auth.py` +- []Define LoginRequest, LoginResponse models +- []Add SetupRequest, AuthStatus models +- []Include session management models #### [] Create authentication service -- Create `src/server/services/auth_service.py` -- Implement master password setup/validation -- Add session management with JWT tokens -- Include failed attempt tracking and lockout -- Add password strength validation +- []Create `src/server/services/auth_service.py` +- []Implement master password setup/validation +- []Add session management with JWT tokens +- []Include failed attempt tracking and lockout +- []Add password strength validation #### [] Implement authentication API endpoints -- Create `src/server/api/auth.py` -- Add POST `/api/auth/setup` - initial setup -- Add POST `/api/auth/login` - login endpoint -- Add POST `/api/auth/logout` - logout endpoint -- Add GET `/api/auth/status` - authentication status +- []Create `src/server/api/auth.py` +- []Add POST `/api/auth/setup` - initial setup +- []Add POST `/api/auth/login` - login endpoint +- []Add POST `/api/auth/logout` - logout endpoint +- []Add GET `/api/auth/status` - authentication status #### [] Create authentication middleware -- Create `src/server/middleware/auth.py` -- Implement JWT token validation -- Add request authentication checking -- Include rate limiting for auth endpoints +- []Create `src/server/middleware/auth.py` +- []Implement JWT token validation +- []Add request authentication checking +- []Include rate limiting for auth endpoints ### 3. Configuration Management #### [] Implement configuration models -- Create `src/server/models/config.py` -- Define ConfigResponse, ConfigUpdate models -- Add SchedulerConfig, LoggingConfig models -- Include ValidationResult model +- []Create `src/server/models/config.py` +- []Define ConfigResponse, ConfigUpdate models +- []Add SchedulerConfig, LoggingConfig models +- []Include ValidationResult model #### [] Create configuration service -- Create `src/server/services/config_service.py` -- Implement configuration loading/saving -- Add configuration validation -- Include backup/restore functionality -- Add scheduler configuration management +- []Create `src/server/services/config_service.py` +- []Implement configuration loading/saving +- []Add configuration validation +- []Include backup/restore functionality +- []Add scheduler configuration management #### [] Implement configuration API endpoints -- Create `src/server/api/config.py` -- Add GET `/api/config` - get configuration -- Add PUT `/api/config` - update configuration -- Add POST `/api/config/validate` - validate config -- Add GET/POST `/api/config/backup` - backup management +- []Create `src/server/api/config.py` +- []Add GET `/api/config` - get configuration +- []Add PUT `/api/config` - update configuration +- []Add POST `/api/config/validate` - validate config +- []Add GET/POST `/api/config/backup` - backup management ### 4. Anime Management Integration #### [] Implement anime models -- Create `src/server/models/anime.py` -- Define AnimeSeriesResponse, EpisodeInfo models -- Add SearchRequest, SearchResult models -- Include MissingEpisodeInfo model +- []Create `src/server/models/anime.py` +- []Define AnimeSeriesResponse, EpisodeInfo models +- []Add SearchRequest, SearchResult models +- []Include MissingEpisodeInfo model #### [] Create anime service wrapper -- Create `src/server/services/anime_service.py` -- Wrap SeriesApp functionality for web layer -- Implement async wrappers for blocking operations -- Add caching for frequently accessed data -- Include error handling and logging +- []Create `src/server/services/anime_service.py` +- []Wrap SeriesApp functionality for web layer +- []Implement async wrappers for blocking operations +- []Add caching for frequently accessed data +- []Include error handling and logging #### [] Implement anime API endpoints -- Create `src/server/api/anime.py` -- Add GET `/api/v1/anime` - list series with missing episodes -- Add POST `/api/v1/anime/rescan` - trigger rescan -- Add POST `/api/v1/anime/search` - search for new anime -- Add GET `/api/v1/anime/{id}` - get series details +- []Create `src/server/api/anime.py` +- []Add GET `/api/v1/anime` - list series with missing episodes +- []Add POST `/api/v1/anime/rescan` - trigger rescan +- []Add POST `/api/v1/anime/search` - search for new anime +- []Add GET `/api/v1/anime/{id}` - get series details ### 5. Download Queue Management #### [] Implement download queue models -- Create `src/server/models/download.py` -- Define DownloadItem, QueueStatus models -- Add DownloadProgress, QueueStats models -- Include DownloadRequest model +- []Create `src/server/models/download.py` +- []Define DownloadItem, QueueStatus models +- []Add DownloadProgress, QueueStats models +- []Include DownloadRequest model #### [] Create download queue service -- Create `src/server/services/download_service.py` -- Implement queue management (add, remove, reorder) -- Add download progress tracking -- Include queue persistence and recovery -- Add concurrent download management +- []Create `src/server/services/download_service.py` +- []Implement queue management (add, remove, reorder) +- []Add download progress tracking +- []Include queue persistence and recovery +- []Add concurrent download management #### [] Implement download API endpoints -- Create `src/server/api/download.py` -- Add GET `/api/queue/status` - get queue status -- Add POST `/api/queue/add` - add to queue -- Add DELETE `/api/queue/{id}` - remove from queue -- Add POST `/api/queue/start` - start downloads -- Add POST `/api/queue/stop` - stop downloads +- []Create `src/server/api/download.py` +- []Add GET `/api/queue/status` - get queue status +- []Add POST `/api/queue/add` - add to queue +- []Add DELETE `/api/queue/{id}` - remove from queue +- []Add POST `/api/queue/start` - start downloads +- []Add POST `/api/queue/stop` - stop downloads ### 6. WebSocket Real-time Updates #### [] Implement WebSocket manager -- Create `src/server/services/websocket_service.py` -- Add connection management -- Implement broadcast functionality -- Include room-based messaging -- Add connection cleanup +- []Create `src/server/services/websocket_service.py` +- []Add connection management +- []Implement broadcast functionality +- []Include room-based messaging +- []Add connection cleanup #### [] Add real-time progress updates -- Create `src/server/services/progress_service.py` -- Implement download progress broadcasting -- Add scan progress updates -- Include queue status changes -- Add error notifications +- []Create `src/server/services/progress_service.py` +- []Implement download progress broadcasting +- []Add scan progress updates +- []Include queue status changes +- []Add error notifications #### [] Integrate WebSocket with core services -- Update download service to emit progress -- Add scan progress notifications -- Include queue change broadcasts -- Add error/completion notifications +- []Update download service to emit progress +- []Add scan progress notifications +- []Include queue change broadcasts +- []Add error/completion notifications ### 7. Frontend Integration #### [] Integrate existing HTML templates -- Review and integrate existing HTML templates in `src/server/web/templates/` -- Ensure templates work with FastAPI Jinja2 setup -- Update template paths and static file references if needed -- Maintain existing responsive layout and theme switching +- []Review and integrate existing HTML templates in `src/server/web/templates/` +- []Ensure templates work with FastAPI Jinja2 setup +- []Update template paths and static file references if needed +- []Maintain existing responsive layout and theme switching #### [] Integrate existing JavaScript functionality -- Review existing JavaScript files in `src/server/web/static/js/` -- Update API endpoint URLs to match FastAPI routes -- Ensure WebSocket connections work with new backend -- Maintain existing functionality for app.js and queue.js +- []Review existing JavaScript files in `src/server/web/static/js/` +- []Update API endpoint URLs to match FastAPI routes +- []Ensure WebSocket connections work with new backend +- []Maintain existing functionality for app.js and queue.js #### [] Integrate existing CSS styling -- Review and integrate existing CSS files in `src/server/web/static/css/` -- Ensure styling works with FastAPI static file serving -- Maintain existing responsive design and theme support -- Update any hardcoded paths if necessary +- []Review and integrate existing CSS files in `src/server/web/static/css/` +- []Ensure styling works with FastAPI static file serving +- []Maintain existing responsive design and theme support +- []Update any hardcoded paths if necessary #### [] Update frontend-backend integration -- Ensure existing JavaScript calls match new API endpoints -- Update authentication flow to work with new auth system -- Verify WebSocket events match new service implementations -- Test all existing UI functionality with new backend +- []Ensure existing JavaScript calls match new API endpoints +- []Update authentication flow to work with new auth system +- []Verify WebSocket events match new service implementations +- []Test all existing UI functionality with new backend ### 8. Core Logic Integration #### [] Enhance SeriesApp for web integration -- Update `src/core/SeriesApp.py` -- Add async callback support -- Implement progress reporting -- Include better error handling -- Add cancellation support +- []Update `src/core/SeriesApp.py` +- []Add async callback support +- []Implement progress reporting +- []Include better error handling +- []Add cancellation support #### [] Create progress callback system -- Add progress callback interface -- Implement scan progress reporting -- Add download progress tracking -- Include error/completion callbacks +- []Add progress callback interface +- []Implement scan progress reporting +- []Add download progress tracking +- []Include error/completion callbacks #### [] Add configuration persistence -- Implement configuration file management -- Add settings validation -- Include backup/restore functionality -- Add migration support for config updates +- []Implement configuration file management +- []Add settings validation +- []Include backup/restore functionality +- []Add migration support for config updates ### 9. Database Layer #### [] Implement database models -- Create `src/server/database/models.py` -- Add SQLAlchemy models for anime series -- Implement download queue persistence -- Include user session storage +- []Create `src/server/database/models.py` +- []Add SQLAlchemy models for anime series +- []Implement download queue persistence +- []Include user session storage #### [] Create database service -- Create `src/server/database/service.py` -- Add CRUD operations for anime data -- Implement queue persistence -- Include database migration support +- []Create `src/server/database/service.py` +- []Add CRUD operations for anime data +- []Implement queue persistence +- []Include database migration support #### [] Add database initialization -- Create `src/server/database/init.py` -- Implement database setup -- Add initial data migration -- Include schema validation +- []Create `src/server/database/init.py` +- []Implement database setup +- []Add initial data migration +- []Include schema validation ### 10. Testing #### [] Create unit tests for services -- Create `tests/unit/test_auth_service.py` -- Create `tests/unit/test_anime_service.py` -- Create `tests/unit/test_download_service.py` -- Create `tests/unit/test_config_service.py` +- []Create `tests/unit/test_auth_service.py` +- []Create `tests/unit/test_anime_service.py` +- []Create `tests/unit/test_download_service.py` +- []Create `tests/unit/test_config_service.py` #### [] Create API endpoint tests -- Create `tests/api/test_auth_endpoints.py` -- Create `tests/api/test_anime_endpoints.py` -- Create `tests/api/test_download_endpoints.py` -- Create `tests/api/test_config_endpoints.py` +- []Create `tests/api/test_auth_endpoints.py` +- []Create `tests/api/test_anime_endpoints.py` +- []Create `tests/api/test_download_endpoints.py` +- []Create `tests/api/test_config_endpoints.py` #### [] Create integration tests -- Create `tests/integration/test_download_flow.py` -- Create `tests/integration/test_auth_flow.py` -- Create `tests/integration/test_websocket.py` +- []Create `tests/integration/test_download_flow.py` +- []Create `tests/integration/test_auth_flow.py` +- []Create `tests/integration/test_websocket.py` #### [] Create frontend integration tests -- Create `tests/frontend/test_existing_ui_integration.py` -- Test existing JavaScript functionality with new backend -- Verify WebSocket connections and real-time updates -- Test authentication flow with existing frontend +- []Create `tests/frontend/test_existing_ui_integration.py` +- []Test existing JavaScript functionality with new backend +- []Verify WebSocket connections and real-time updates +- []Test authentication flow with existing frontend ### 11. Deployment and Configuration #### [] Create Docker configuration -- Create `Dockerfile` -- Create `docker-compose.yml` -- Add environment configuration -- Include volume mappings for existing web assets +- []Create `Dockerfile` +- []Create `docker-compose.yml` +- []Add environment configuration +- []Include volume mappings for existing web assets #### [] Create production configuration -- Create `src/server/config/production.py` -- Add environment variable handling -- Include security settings -- Add performance optimizations +- []Create `src/server/config/production.py` +- []Add environment variable handling +- []Include security settings +- []Add performance optimizations #### [] Create startup scripts -- Create `scripts/start.sh` -- Create `scripts/setup.py` -- Add dependency installation -- Include database initialization +- []Create `scripts/start.sh` +- []Create `scripts/setup.py` +- []Add dependency installation +- []Include database initialization ### 12. Documentation and Error Handling #### [] Create API documentation -- Add OpenAPI/Swagger documentation -- Include endpoint descriptions -- Add request/response examples -- Include authentication details +- []Add OpenAPI/Swagger documentation +- []Include endpoint descriptions +- []Add request/response examples +- []Include authentication details #### [] Implement comprehensive error handling -- Create custom exception classes -- Add error logging and tracking -- Implement user-friendly error messages -- Include error recovery mechanisms +- []Create custom exception classes +- []Add error logging and tracking +- []Implement user-friendly error messages +- []Include error recovery mechanisms #### [] Create user documentation -- Create `docs/user_guide.md` -- Add installation instructions -- Include configuration guide -- Add troubleshooting section +- []Create `docs/user_guide.md` +- []Add installation instructions +- []Include configuration guide +- []Add troubleshooting section ## File Size Guidelines -- **Models**: Max 200 lines each -- **Services**: Max 450 lines each -- **API Endpoints**: Max 350 lines each -- **Templates**: Max 400 lines each -- **JavaScript**: Max 500 lines each -- **CSS**: Max 500 lines each -- **Tests**: Max 400 lines each +- []**Models**: Max 200 lines each +- []**Services**: Max 450 lines each +- []**API Endpoints**: Max 350 lines each +- []**Templates**: Max 400 lines each +- []**JavaScript**: Max 500 lines each +- []**CSS**: Max 500 lines each +- []**Tests**: Max 400 lines each ## Existing Frontend Assets The following frontend assets already exist and should be integrated: -- **Templates**: Located in `src/server/web/templates/` -- **JavaScript**: Located in `src/server/web/static/js/` (app.js, queue.js, etc.) -- **CSS**: Located in `src/server/web/static/css/` -- **Static Assets**: Images and other assets in `src/server/web/static/` +- []**Templates**: Located in `src/server/web/templates/` +- []**JavaScript**: Located in `src/server/web/static/js/` (app.js, queue.js, etc.) +- []**CSS**: Located in `src/server/web/static/css/` +- []**Static Assets**: Images and other assets in `src/server/web/static/` When working with these files: -- Review existing functionality before making changes -- Maintain existing UI/UX patterns and design -- Update API calls to match new FastAPI endpoints -- Preserve existing WebSocket event handling -- Keep existing theme and responsive design features +- []Review existing functionality before making changes +- []Maintain existing UI/UX patterns and design +- []Update API calls to match new FastAPI endpoints +- []Preserve existing WebSocket event handling +- []Keep existing theme and responsive design features ## Quality Assurance #### [] Code quality checks -- Run linting with flake8/pylint -- Check type hints with mypy -- Validate formatting with black -- Run security checks with bandit +- []Run linting with flake8/pylint +- []Check type hints with mypy +- []Validate formatting with black +- []Run security checks with bandit #### [] Performance testing -- Load test API endpoints -- Test WebSocket connection limits -- Validate download performance -- Check memory usage patterns +- []Load test API endpoints +- []Test WebSocket connection limits +- []Validate download performance +- []Check memory usage patterns #### [] Security validation -- Test authentication bypass attempts -- Validate input sanitization -- Check for injection vulnerabilities -- Test session management security +- []Test authentication bypass attempts +- []Validate input sanitization +- []Check for injection vulnerabilities +- []Test session management security Each task should be implemented with proper error handling, logging, and type hints according to the project's coding standards. diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..be76388 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,13 @@ +fastapi==0.104.1 +uvicorn[standard]==0.24.0 +jinja2==3.1.2 +python-multipart==0.0.6 +pydantic==2.5.0 +pydantic-settings==2.1.0 +python-jose[cryptography]==3.3.0 +passlib[bcrypt]==1.7.4 +aiofiles==23.2.1 +websockets==12.0 +pytest==7.4.3 +pytest-asyncio==0.21.1 +httpx==0.25.2 \ No newline at end of file diff --git a/src/core/__init__.py b/src/core/__init__.py index 117ab53..56e91a2 100644 --- a/src/core/__init__.py +++ b/src/core/__init__.py @@ -3,10 +3,6 @@ Core module for AniWorld application. Contains domain entities, interfaces, application services, and exceptions. """ -from . import entities -from . import exceptions -from . import interfaces -from . import application -from . import providers +from . import entities, exceptions, interfaces, providers -__all__ = ['entities', 'exceptions', 'interfaces', 'application', 'providers'] \ No newline at end of file +__all__ = ['entities', 'exceptions', 'interfaces', 'providers'] diff --git a/src/server/controllers/__init__.py b/src/server/controllers/__init__.py new file mode 100644 index 0000000..300a80d --- /dev/null +++ b/src/server/controllers/__init__.py @@ -0,0 +1,5 @@ +""" +Controllers package for FastAPI application. + +This package contains route controllers organized by functionality. +""" \ No newline at end of file diff --git a/src/server/controllers/error_controller.py b/src/server/controllers/error_controller.py new file mode 100644 index 0000000..8ee2643 --- /dev/null +++ b/src/server/controllers/error_controller.py @@ -0,0 +1,39 @@ +""" +Error handler controller for managing application exceptions. + +This module provides custom error handlers for different HTTP status codes. +""" +from fastapi import HTTPException, Request +from fastapi.responses import JSONResponse + +from src.server.utils.templates import templates + + +async def not_found_handler(request: Request, exc: HTTPException): + """Custom 404 handler.""" + if request.url.path.startswith("/api/"): + return JSONResponse( + status_code=404, + content={"detail": "API endpoint not found"} + ) + return templates.TemplateResponse( + "error.html", + {"request": request, "error": "Page not found", "status_code": 404} + ) + + +async def server_error_handler(request: Request, exc: Exception): + """Custom 500 handler.""" + if request.url.path.startswith("/api/"): + return JSONResponse( + status_code=500, + content={"detail": "Internal server error"} + ) + return templates.TemplateResponse( + "error.html", + { + "request": request, + "error": "Internal server error", + "status_code": 500 + } + ) \ No newline at end of file diff --git a/src/server/controllers/health_controller.py b/src/server/controllers/health_controller.py new file mode 100644 index 0000000..85193dc --- /dev/null +++ b/src/server/controllers/health_controller.py @@ -0,0 +1,31 @@ +""" +Health check controller for monitoring and status endpoints. + +This module provides health check endpoints for application monitoring. +""" +from typing import Optional + +from fastapi import APIRouter + +from src.core.SeriesApp import SeriesApp + +router = APIRouter(prefix="/health", tags=["health"]) + + +def get_series_app() -> Optional[SeriesApp]: + """Get the current SeriesApp instance.""" + # This will be replaced with proper dependency injection + from src.server.fastapi_app import series_app + return series_app + + +@router.get("") +async def health_check(): + """Health check endpoint for monitoring.""" + series_app = get_series_app() + return { + "status": "healthy", + "service": "aniworld-api", + "version": "1.0.0", + "series_app_initialized": series_app is not None + } \ No newline at end of file diff --git a/src/server/controllers/page_controller.py b/src/server/controllers/page_controller.py new file mode 100644 index 0000000..6edf792 --- /dev/null +++ b/src/server/controllers/page_controller.py @@ -0,0 +1,47 @@ +""" +Page controller for serving HTML templates. + +This module provides endpoints for serving HTML pages using Jinja2 templates. +""" +from fastapi import APIRouter, Request +from fastapi.responses import HTMLResponse + +from src.server.utils.templates import templates + +router = APIRouter(tags=["pages"]) + + +@router.get("/", response_class=HTMLResponse) +async def root(request: Request): + """Serve the main application page.""" + return templates.TemplateResponse( + "index.html", + {"request": request, "title": "Aniworld Download Manager"} + ) + + +@router.get("/setup", response_class=HTMLResponse) +async def setup_page(request: Request): + """Serve the setup page.""" + return templates.TemplateResponse( + "setup.html", + {"request": request, "title": "Setup - Aniworld"} + ) + + +@router.get("/login", response_class=HTMLResponse) +async def login_page(request: Request): + """Serve the login page.""" + return templates.TemplateResponse( + "login.html", + {"request": request, "title": "Login - Aniworld"} + ) + + +@router.get("/queue", response_class=HTMLResponse) +async def queue_page(request: Request): + """Serve the download queue page.""" + return templates.TemplateResponse( + "queue.html", + {"request": request, "title": "Download Queue - Aniworld"} + ) \ No newline at end of file diff --git a/src/server/fastapi_app.py b/src/server/fastapi_app.py new file mode 100644 index 0000000..98c3783 --- /dev/null +++ b/src/server/fastapi_app.py @@ -0,0 +1,97 @@ +""" +FastAPI application for Aniworld anime download manager. + +This module provides the main FastAPI application with proper CORS +configuration, middleware setup, static file serving, and Jinja2 template +integration. +""" +from pathlib import Path +from typing import Optional + +import uvicorn +from fastapi import FastAPI, HTTPException, Request +from fastapi.middleware.cors import CORSMiddleware +from fastapi.staticfiles import StaticFiles + +from src.config.settings import settings + +# Import core functionality +from src.core.SeriesApp import SeriesApp +from src.server.controllers.error_controller import ( + not_found_handler, + server_error_handler, +) + +# Import controllers +from src.server.controllers.health_controller import router as health_router +from src.server.controllers.page_controller import router as page_router + +# Initialize FastAPI app +app = FastAPI( + title="Aniworld Download Manager", + description="Modern web interface for Aniworld anime download management", + version="1.0.0", + docs_url="/api/docs", + redoc_url="/api/redoc" +) + +# Configure CORS +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], # Configure appropriately for production + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# Configure static files +STATIC_DIR = Path(__file__).parent / "web" / "static" +app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static") + +# Include routers +app.include_router(health_router) +app.include_router(page_router) + +# Global variables for application state +series_app: Optional[SeriesApp] = None + + +@app.on_event("startup") +async def startup_event(): + """Initialize application on startup.""" + global series_app + try: + # Initialize SeriesApp with configured directory + if settings.anime_directory: + series_app = SeriesApp(settings.anime_directory) + print("FastAPI application started successfully") + except Exception as e: + print(f"Error during startup: {e}") + + +@app.on_event("shutdown") +async def shutdown_event(): + """Cleanup on application shutdown.""" + print("FastAPI application shutting down") + + +@app.exception_handler(404) +async def handle_not_found(request: Request, exc: HTTPException): + """Custom 404 handler.""" + return await not_found_handler(request, exc) + + +@app.exception_handler(500) +async def handle_server_error(request: Request, exc: Exception): + """Custom 500 handler.""" + return await server_error_handler(request, exc) + + +if __name__ == "__main__": + uvicorn.run( + "fastapi_app:app", + host="127.0.0.1", + port=8000, + reload=True, + log_level="info" + ) diff --git a/src/server/utils/__init__.py b/src/server/utils/__init__.py new file mode 100644 index 0000000..b6a0403 --- /dev/null +++ b/src/server/utils/__init__.py @@ -0,0 +1,6 @@ +""" +Utility modules for the FastAPI application. + +This package contains dependency injection, security utilities, and other +helper functions for the web application. +""" \ No newline at end of file diff --git a/src/server/utils/dependencies.py b/src/server/utils/dependencies.py new file mode 100644 index 0000000..da9eaef --- /dev/null +++ b/src/server/utils/dependencies.py @@ -0,0 +1,180 @@ +""" +Dependency injection utilities for FastAPI. + +This module provides dependency injection functions for the FastAPI +application, including SeriesApp instances, database sessions, and +authentication dependencies. +""" +from typing import AsyncGenerator, Optional + +from fastapi import Depends, HTTPException, status +from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer +from sqlalchemy.ext.asyncio import AsyncSession + +from src.config.settings import settings +from src.core.SeriesApp import SeriesApp + +# Security scheme for JWT authentication +security = HTTPBearer() + + +# Global SeriesApp instance +_series_app: Optional[SeriesApp] = None + + +def get_series_app() -> SeriesApp: + """ + Dependency to get SeriesApp instance. + + Returns: + SeriesApp: The main application instance for anime management + + Raises: + HTTPException: If SeriesApp is not initialized or anime directory + is not configured + """ + global _series_app + + if not settings.anime_directory: + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="Anime directory not configured. Please complete setup." + ) + + if _series_app is None: + try: + _series_app = SeriesApp(settings.anime_directory) + except Exception as e: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Failed to initialize SeriesApp: {str(e)}" + ) + + return _series_app + + +def reset_series_app() -> None: + """Reset the global SeriesApp instance (for testing or config changes).""" + global _series_app + _series_app = None + + +async def get_database_session() -> AsyncGenerator[AsyncSession, None]: + """ + Dependency to get database session. + + Yields: + AsyncSession: Database session for async operations + """ + # TODO: Implement database session management + # This is a placeholder for future database implementation + raise HTTPException( + status_code=status.HTTP_501_NOT_IMPLEMENTED, + detail="Database functionality not yet implemented" + ) + + +def get_current_user( + credentials: HTTPAuthorizationCredentials = Depends(security) +) -> dict: + """ + Dependency to get current authenticated user. + + Args: + credentials: JWT token from Authorization header + + Returns: + dict: User information + + Raises: + HTTPException: If token is invalid or user is not authenticated + """ + # TODO: Implement JWT token validation + # This is a placeholder for authentication implementation + raise HTTPException( + status_code=status.HTTP_501_NOT_IMPLEMENTED, + detail="Authentication functionality not yet implemented" + ) + + +def require_auth( + current_user: dict = Depends(get_current_user) +) -> dict: + """ + Dependency that requires authentication. + + Args: + current_user: Current authenticated user from get_current_user + + Returns: + dict: User information + """ + return current_user + + +def optional_auth( + credentials: Optional[HTTPAuthorizationCredentials] = Depends( + HTTPBearer(auto_error=False) + ) +) -> Optional[dict]: + """ + Dependency for optional authentication. + + Args: + credentials: Optional JWT token from Authorization header + + Returns: + Optional[dict]: User information if authenticated, None otherwise + """ + if credentials is None: + return None + + try: + return get_current_user(credentials) + except HTTPException: + return None + + +class CommonQueryParams: + """Common query parameters for API endpoints.""" + + def __init__(self, skip: int = 0, limit: int = 100): + self.skip = skip + self.limit = limit + + +def common_parameters( + skip: int = 0, + limit: int = 100 +) -> CommonQueryParams: + """ + Dependency for common query parameters. + + Args: + skip: Number of items to skip (for pagination) + limit: Maximum number of items to return + + Returns: + CommonQueryParams: Common query parameters + """ + return CommonQueryParams(skip=skip, limit=limit) + + +# Dependency for rate limiting (placeholder) +async def rate_limit_dependency(): + """ + Dependency for rate limiting API requests. + + TODO: Implement rate limiting logic + """ + pass + + +# Dependency for request logging (placeholder) +async def log_request_dependency(): + """ + Dependency for logging API requests. + + TODO: Implement request logging logic + """ + pass \ No newline at end of file diff --git a/src/server/utils/templates.py b/src/server/utils/templates.py new file mode 100644 index 0000000..1a22af6 --- /dev/null +++ b/src/server/utils/templates.py @@ -0,0 +1,12 @@ +""" +Shared templates configuration for FastAPI application. + +This module provides centralized Jinja2 template configuration. +""" +from pathlib import Path + +from fastapi.templating import Jinja2Templates + +# Configure templates - shared across controllers +TEMPLATES_DIR = Path(__file__).parent.parent / "web" / "templates" +templates = Jinja2Templates(directory=str(TEMPLATES_DIR)) \ No newline at end of file diff --git a/src/server/web/templates/error.html b/src/server/web/templates/error.html new file mode 100644 index 0000000..ff3b507 --- /dev/null +++ b/src/server/web/templates/error.html @@ -0,0 +1,42 @@ + + + + + + Error - Aniworld + + + + +
+
+
+
+
+

Error {{ status_code }}

+
+
+
+ +
+
{{ error }}
+

+ {% if status_code == 404 %} + The page you're looking for doesn't exist. + {% elif status_code == 500 %} + Something went wrong on our end. Please try again later. + {% else %} + An unexpected error occurred. + {% endif %} +

+ Go Home +
+
+
+
+
+ + + + + \ No newline at end of file