79 lines
2.6 KiB
Python
79 lines
2.6 KiB
Python
from fastapi import FastAPI, Depends, HTTPException, Request
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.exceptions import RequestValidationError
|
|
import uvicorn
|
|
from pathlib import Path
|
|
from sqlalchemy.orm import Session
|
|
import logging
|
|
import time
|
|
|
|
from app.database import get_db, Base, engine
|
|
from app.api.routers import assets, exchanges, markets, rates, health
|
|
from app.exceptions import (
|
|
CoinCapAPIException,
|
|
validation_exception_handler,
|
|
http_exception_handler,
|
|
coincap_api_exception_handler,
|
|
general_exception_handler
|
|
)
|
|
from app.utils.logging import setup_logging
|
|
from starlette.exceptions import HTTPException as StarletteHTTPException
|
|
|
|
# Setup logging
|
|
setup_logging(log_level="INFO")
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Create the FastAPI app
|
|
app = FastAPI(
|
|
title="Cryptocurrency Data Service",
|
|
description="Backend service for cryptocurrency data from CoinCap API",
|
|
version="0.1.0",
|
|
)
|
|
|
|
# Register exception handlers
|
|
app.add_exception_handler(RequestValidationError, validation_exception_handler)
|
|
app.add_exception_handler(StarletteHTTPException, http_exception_handler)
|
|
app.add_exception_handler(CoinCapAPIException, coincap_api_exception_handler)
|
|
app.add_exception_handler(Exception, general_exception_handler)
|
|
|
|
# CORS middleware configuration
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["*"],
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
# 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"] = str(process_time)
|
|
logger.debug(f"Request to {request.url.path} processed in {process_time:.4f} seconds")
|
|
return response
|
|
|
|
# Include routers
|
|
app.include_router(health.router)
|
|
app.include_router(assets.router, prefix="/api")
|
|
app.include_router(exchanges.router, prefix="/api")
|
|
app.include_router(markets.router, prefix="/api")
|
|
app.include_router(rates.router, prefix="/api")
|
|
|
|
# Startup event
|
|
@app.on_event("startup")
|
|
async def startup_event():
|
|
logger.info("Starting up Cryptocurrency Data Service")
|
|
# Create database tables at startup
|
|
# In production, you should use Alembic migrations instead
|
|
# Base.metadata.create_all(bind=engine)
|
|
|
|
# Shutdown event
|
|
@app.on_event("shutdown")
|
|
async def shutdown_event():
|
|
logger.info("Shutting down Cryptocurrency Data Service")
|
|
|
|
if __name__ == "__main__":
|
|
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True) |