import logging import sys import time from logging.handlers import RotatingFileHandler from pathlib import Path from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from app.core.config import settings from app.middlewares.rate_limiter import RateLimitMiddleware from app.middlewares.security import SecurityHeadersMiddleware # Import routers from app.routers import ( admin, auth, cart, categories, health, inventory, orders, payments, products, reviews, search, tags, users, ) # Configure logging log_dir = Path("/app/storage/logs") log_dir.mkdir(parents=True, exist_ok=True) log_file = log_dir / "app.log" # Set up rotating file handler file_handler = RotatingFileHandler(log_file, maxBytes=10485760, backupCount=5) file_handler.setFormatter(logging.Formatter( "%(asctime)s - %(name)s - %(levelname)s - %(message)s" )) # Set up console handler console_handler = logging.StreamHandler(sys.stdout) console_handler.setFormatter(logging.Formatter( "%(asctime)s - %(name)s - %(levelname)s - %(message)s" )) # Configure root logger logging.basicConfig( level=logging.INFO, handlers=[file_handler, console_handler] ) # Create FastAPI app instance app = FastAPI( title="Comprehensive E-Commerce API", description=""" # E-Commerce API A full-featured e-commerce API built with FastAPI and SQLite. ## Features * **User Management**: Registration, authentication, profiles * **Product Management**: CRUD operations, image uploads * **Category & Tag Management**: Hierarchical categories, product tagging * **Shopping Cart**: Add, update, remove items * **Order Processing**: Create orders, track status * **Payment Integration**: Process payments with multiple methods * **Inventory Management**: Track stock levels * **Search & Filtering**: Advanced product search and filtering * **Reviews & Ratings**: User reviews and product ratings * **Admin Dashboard**: Sales analytics and reporting ## Authentication Most endpoints require authentication using JSON Web Tokens (JWT). To authenticate: 1. Register a user or use the default admin credentials 2. Login using the /api/auth/login endpoint 3. Use the returned access token in the Authorization header for subsequent requests: `Authorization: Bearer {your_access_token}` ## Getting Started 1. Create a user account using the /api/auth/register endpoint 2. Browse products using the /api/products endpoints 3. Add items to your cart using the /api/cart endpoints 4. Create an order using the /api/orders endpoints 5. Process payment using the /api/payments endpoints ## API Status Codes * 200: Success * 201: Created * 204: No Content * 400: Bad Request * 401: Unauthorized * 403: Forbidden * 404: Not Found * 422: Validation Error * 429: Too Many Requests * 500: Internal Server Error """, version="1.0.0", docs_url="/docs", redoc_url="/redoc", openapi_tags=[ {"name": "Health", "description": "Health check endpoint"}, {"name": "Authentication", "description": "User registration and authentication"}, {"name": "Users", "description": "User profile management"}, {"name": "Products", "description": "Product management and information"}, {"name": "Categories", "description": "Product category management"}, {"name": "Tags", "description": "Product tag management"}, {"name": "Shopping Cart", "description": "Shopping cart operations"}, {"name": "Orders", "description": "Order creation and management"}, {"name": "Payments", "description": "Payment processing and management"}, {"name": "Reviews", "description": "Product reviews and ratings"}, {"name": "Search", "description": "Product search and filtering"}, {"name": "Inventory", "description": "Inventory management"}, {"name": "Admin", "description": "Admin dashboard and analytics"}, ], license_info={ "name": "MIT", "url": "https://opensource.org/licenses/MIT", }, contact={ "name": "E-Commerce API Support", "email": "support@example.com", "url": "https://example.com/support", }, ) # Configure CORS app.add_middleware( CORSMiddleware, allow_origins=["*"], # In production, replace this with specific origins allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Add security headers middleware app.add_middleware( SecurityHeadersMiddleware, content_security_policy="default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; connect-src 'self'" ) # Add rate limiting middleware app.add_middleware( RateLimitMiddleware, rate_limit_per_minute=settings.RATE_LIMIT_PER_MINUTE, whitelist_paths=["/health", "/docs", "/redoc", "/openapi.json"] ) # Add request timing middleware @app.middleware("http") async def add_process_time_header(request: Request, call_next): start_time = time.time() response = await call_next(request) process_time = time.time() - start_time response.headers["X-Process-Time"] = f"{process_time:.4f} sec" return response # Add global exception handler @app.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception): logging.error(f"Unhandled exception: {str(exc)}") return JSONResponse( status_code=500, content={"detail": "An unexpected error occurred. Please try again later."} ) # Include routers app.include_router(health.router, tags=["Health"]) app.include_router(users.router, prefix="/api/users", tags=["Users"]) app.include_router(auth.router, prefix="/api/auth", tags=["Authentication"]) app.include_router(products.router, prefix="/api/products", tags=["Products"]) app.include_router(categories.router, prefix="/api/categories", tags=["Categories"]) app.include_router(tags.router, prefix="/api/tags", tags=["Tags"]) app.include_router(cart.router, prefix="/api/cart", tags=["Shopping Cart"]) app.include_router(orders.router, prefix="/api/orders", tags=["Orders"]) app.include_router(payments.router, prefix="/api/payments", tags=["Payments"]) app.include_router(reviews.router, prefix="/api/reviews", tags=["Reviews"]) app.include_router(search.router, prefix="/api/search", tags=["Search"]) app.include_router(inventory.router, prefix="/api/inventory", tags=["Inventory"]) app.include_router(admin.router, prefix="/api/admin", tags=["Admin"]) if __name__ == "__main__": import uvicorn uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)