atriumchain-api / main.py
Jainish1808's picture
Upload folder using huggingface_hub
ce6c350 verified
"""
Production-Ready FastAPI Application
Real Estate Tokenization Platform - AtriumChain Platform
"""
from fastapi import FastAPI, status, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
from fastapi.responses import JSONResponse
from contextlib import asynccontextmanager
from slowapi import _rate_limit_exceeded_handler
from slowapi.errors import RateLimitExceeded
from config import settings
from db import init_mongo, close_mongo, check_db_health
from utils.logger import setup_logging
from middleware.security import SecurityHeadersMiddleware, RequestIDMiddleware, limiter
# Import routes
from routes import (
auth,
otp,
properties,
market,
wallet,
portfolio,
admin,
super_admin,
secondary_market,
profile
)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Application lifespan events"""
print("\n" + "="*80)
print("STARTING REAL ESTATE TOKENIZATION PLATFORM")
print("="*80 + "\n")
# Startup
try:
# Initialize logging system
setup_logging()
print("[APP] βœ… Logging system initialized")
db = init_mongo(app)
print("[APP] βœ… Application startup complete\n")
except Exception as e:
print(f"[APP] [ERROR] Startup failed: {str(e)}\n")
raise
yield
# Shutdown
print("\n[APP] Shutting down...")
close_mongo()
print("[APP] βœ… Shutdown complete\n")
# Create FastAPI app
app = FastAPI(
title="Real Estate Tokenization Platform",
description="Production-ready platform for fractional real estate investment using blockchain",
version="2.0.0",
lifespan=lifespan
)
# Add HTTPS redirect middleware in production
if settings.is_production():
app.add_middleware(HTTPSRedirectMiddleware)
print("[APP] βœ… HTTPS enforcement enabled (production mode)")
# Add security middleware
app.add_middleware(SecurityHeadersMiddleware)
app.add_middleware(RequestIDMiddleware)
# Add rate limiter
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=settings.CORS_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Health check endpoint
@app.get("/", tags=["Health"])
async def root():
"""Root endpoint - API health check"""
return {
"message": "πŸš€ AtriumChain Backend Started Successfully!",
"status": "online",
"service": "Real Estate Tokenization Platform",
"version": "2.0.0",
"environment": settings.XRPL_NETWORK,
"docs": "/"
}
@app.get("/health", tags=["Health"])
async def health_check():
"""Detailed health check including database connectivity"""
db_health = check_db_health()
return {
"status": "healthy" if db_health["status"] == "healthy" else "degraded",
"api": "online",
"database": db_health
}
# Include routers
app.include_router(
auth.router,
prefix="/api/v1/auth",
tags=["Authentication"]
)
app.include_router(
otp.router,
prefix="/api/v1/otp",
tags=["OTP Verification"]
)
app.include_router(
properties.router,
prefix="/api/v1",
tags=["Properties"]
)
app.include_router(
market.router,
prefix="/api/v1",
tags=["Market"]
)
app.include_router(
secondary_market.router,
prefix="/api/v1",
tags=["Secondary Market"]
)
app.include_router(
wallet.router,
prefix="/api/v1",
tags=["Wallet"]
)
app.include_router(
portfolio.router,
prefix="/api/v1",
tags=["Portfolio"]
)
app.include_router(
admin.router,
prefix="/api/v1",
tags=["Admin"]
)
app.include_router(
super_admin.router,
prefix="/api/v1",
tags=["Super Admin"]
)
app.include_router(
profile.router,
prefix="/api/v1/profile",
tags=["Profile"]
)
# Global exception handler (sanitized)
@app.exception_handler(Exception)
async def global_exception_handler(request, exc):
"""Handle all unhandled exceptions (hide internals in production)."""
# Use structured logging instead of print
import logging
logger = logging.getLogger(__name__)
logger.error(f"Unhandled exception: {exc.__class__.__name__}: {str(exc)}", exc_info=settings.is_development())
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content={
"detail": "An unexpected error occurred. Please try again later.",
"error": str(exc) if settings.is_development() else "Internal server error"
}
)
# Run with: uvicorn main:app --reload --port 8000
if __name__ == "__main__":
import uvicorn
print("\n" + "="*80)
print("DEVELOPMENT SERVER (LOCAL ONLY)")
print("="*80)
print("Starting server on http://127.0.0.1:8000")
print("API Documentation: http://127.0.0.1:8000/docs")
print("NOTE: For production, use: uvicorn main:app --host 0.0.0.0 --port 8000")
print("="*80 + "\n")
uvicorn.run(
"main:app",
host="0.0.0.0", # Bind to localhost only for development security
port=8000,
reload=True,
log_level="info"
)