194 lines
6.7 KiB
Python
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)
|