Spaces:
Runtime error
Runtime error
File size: 4,321 Bytes
73a6a7e 1cfeb58 73a6a7e 71192d1 73a6a7e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# app/main.py
import logging
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request, status
from fastapi.responses import JSONResponse
from fastapi.middleware.gzip import GZipMiddleware
from fastapi.middleware.cors import CORSMiddleware
from app.core.config import APP_NAME # For logger naming
from app.core.logging import configure_logging # Import the new logging configuration
from app.core.exceptions import ServiceError, ModelNotDownloadedError # Import custom exceptions
# Import your routers
# Adjust these imports if your router file names or structure are different
from app.routers import (
grammar, tone, voice, inclusive_language,
readability, paraphrase, translate, synonyms, rewrite, analyze
)
# Configure logging at the very beginning
configure_logging()
logger = logging.getLogger(f"{APP_NAME}.main")
@asynccontextmanager
async def lifespan(app: FastAPI):
"""
Context manager for application startup and shutdown events.
Models are now lazily loaded, so no explicit loading here.
"""
logger.info("Application starting up...")
# Any other global startup tasks can go here
yield
logger.info("Application shutting down...")
# Any global shutdown tasks can go here (e.g., closing database connections)
app = FastAPI(
title="Writing Assistant API (Local)",
description="Local API for the desktop Writing Assistant application, providing various NLP functionalities.",
version="0.1.0",
lifespan=lifespan,
)
# --- Middleware Setup ---
app.add_middleware(GZipMiddleware, minimum_size=500)
# CORS Middleware for local development/desktop app scenarios
# Allows all origins for local testing. Restrict as needed for deployment.
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Adjust this for specific origins in a web deployment
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# --- Global Exception Handlers ---
@app.exception_handler(ServiceError)
async def service_error_handler(request: Request, exc: ServiceError):
"""
Handles custom ServiceError exceptions, returning a structured JSON response.
"""
logger.error(f"Service Error caught for path {request.url.path}: {exc.detail}", exc_info=True)
return JSONResponse(
status_code=exc.status_code,
content=exc.to_dict(), # Use the to_dict method from ServiceError
)
@app.exception_handler(ModelNotDownloadedError)
async def model_not_downloaded_error_handler(request: Request, exc: ModelNotDownloadedError):
"""
Handles ModelNotDownloadedError exceptions, informing the client a model is missing.
"""
logger.warning(f"Model Not Downloaded Error caught for path {request.url.path}: Model '{exc.model_id}' is missing for feature '{exc.feature_name}'.")
return JSONResponse(
status_code=exc.status_code,
content=exc.to_dict(), # Use the to_dict method from ModelNotDownloadedError
)
@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
"""
Handles all other unhandled exceptions, returning a generic server error.
"""
logger.exception(f"Unhandled exception caught for path {request.url.path}: {exc}") # Use logger.exception to log traceback
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content={
"detail": "An unexpected internal server error occurred.",
"error_type": "InternalServerError",
},
)
# --- Include Routers ---
# Note: You will need to create/update these files in app/routers/
# if they don't exist or don't match the new async service methods.
for router, tag in [
(grammar.router, "Grammar"),
(tone.router, "Tone"),
(voice.router, "Voice"),
(inclusive_language.router, "Inclusive Language"),
(readability.router, "Readability"),
(rewrite.router, "Rewrite"),
(analyze.router, "Analyze"),
(paraphrase.router, "Paraphrasing"),
(translate.router, "Translation"),
(synonyms.router, "Synonyms")
]:
app.include_router(router, tags=[tag])
# --- Root Endpoint ---
@app.get("/", tags=["Health Check"])
async def root():
"""
Root endpoint for health check.
"""
return {"message": "Writing Assistant API is running!"} |