194 lines
6.7 KiB
Python

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)