Skip to main content
Glama
main.py5.55 kB
"""FastAPI application main entry point. This module creates and configures the FastAPI application instance with all middleware, routes, and error handlers. """ import time from contextlib import asynccontextmanager from typing import Any import uvicorn from fastapi import FastAPI, Request, Response from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse # Import routes from src.api.routes import ( batch, comments, documents, export, health, layout, lists, media, metadata, revisions, search, security, styles, tables, templates, text, toc, ) from src.core.config import get_settings from src.core.constants import ( API_V1_PREFIX, OPENAPI_DESCRIPTION, OPENAPI_TITLE, OPENAPI_VERSION, ) from src.core.exceptions import BaseDocxException @asynccontextmanager async def lifespan(app: FastAPI): """Application lifespan handler. Args: app: FastAPI application instance. Yields: None after startup, cleanup on shutdown. """ # Startup settings = get_settings() app.state.start_time = time.time() # Create directories if they don't exist import os for dir_path in [settings.upload_dir, settings.export_dir, settings.temp_dir]: os.makedirs(dir_path, exist_ok=True) yield # Shutdown from src.database.base import dispose_engine await dispose_engine() def create_application() -> FastAPI: """Create and configure the FastAPI application. Returns: Configured FastAPI application instance. """ settings = get_settings() app = FastAPI( title=OPENAPI_TITLE, description=OPENAPI_DESCRIPTION, version=OPENAPI_VERSION, docs_url="/docs", redoc_url="/redoc", openapi_url="/openapi.json", lifespan=lifespan, ) # Add CORS middleware app.add_middleware( CORSMiddleware, allow_origins=settings.cors_origins, allow_credentials=settings.cors_allow_credentials, allow_methods=settings.cors_allow_methods, allow_headers=settings.cors_allow_headers, ) # Add custom exception handlers @app.exception_handler(BaseDocxException) async def docx_exception_handler( request: Request, exc: BaseDocxException, ) -> JSONResponse: """Handle custom application exceptions.""" return JSONResponse( status_code=exc.status_code, content=exc.to_dict(), ) @app.exception_handler(Exception) async def general_exception_handler( request: Request, exc: Exception, ) -> JSONResponse: """Handle unexpected exceptions.""" return JSONResponse( status_code=500, content={ "error": { "code": "INTERNAL_ERROR", "message": str(exc) if settings.debug else "Internal server error", } }, ) # Request timing middleware @app.middleware("http") async def add_process_time_header( request: Request, call_next, ) -> Response: """Add processing time header to responses.""" start_time = time.time() response = await call_next(request) process_time = time.time() - start_time response.headers["X-Process-Time"] = str(process_time) return response # Include API routes app.include_router(health.router, prefix=API_V1_PREFIX, tags=["Health"]) app.include_router(documents.router, prefix=API_V1_PREFIX, tags=["Documents"]) app.include_router(text.router, prefix=API_V1_PREFIX, tags=["Text"]) app.include_router(tables.router, prefix=API_V1_PREFIX, tags=["Tables"]) app.include_router(lists.router, prefix=API_V1_PREFIX, tags=["Lists"]) app.include_router(media.router, prefix=API_V1_PREFIX, tags=["Media"]) app.include_router(styles.router, prefix=API_V1_PREFIX, tags=["Styles"]) app.include_router(layout.router, prefix=API_V1_PREFIX, tags=["Layout"]) app.include_router(toc.router, prefix=API_V1_PREFIX, tags=["TOC"]) app.include_router(comments.router, prefix=API_V1_PREFIX, tags=["Comments"]) app.include_router(revisions.router, prefix=API_V1_PREFIX, tags=["Revisions"]) app.include_router(search.router, prefix=API_V1_PREFIX, tags=["Search"]) app.include_router(export.router, prefix=API_V1_PREFIX, tags=["Export"]) app.include_router(templates.router, prefix=API_V1_PREFIX, tags=["Templates"]) app.include_router(security.router, prefix=API_V1_PREFIX, tags=["Security"]) app.include_router(metadata.router, prefix=API_V1_PREFIX, tags=["Metadata"]) app.include_router(batch.router, prefix=API_V1_PREFIX, tags=["Batch"]) # Root endpoint @app.get("/", tags=["Root"]) async def root() -> dict[str, Any]: """Root endpoint with API information.""" return { "name": OPENAPI_TITLE, "version": OPENAPI_VERSION, "docs": "/docs", "openapi": "/openapi.json", } return app # Create application instance app = create_application() def run() -> None: """Run the application with uvicorn.""" settings = get_settings() uvicorn.run( "src.api.main:app", host=settings.host, port=settings.port, reload=settings.reload, workers=settings.workers if not settings.reload else 1, ) if __name__ == "__main__": run()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Fu-Jie/MCP-OPENAPI-DOCX'

If you have feedback or need assistance with the MCP directory API, please join our Discord server