from datetime import datetime import time from collections.abc import Callable from typing import Annotated from fastapi import Body, FastAPI, HTTPException, Response, Request from fastapi.exceptions import RequestValidationError as exc from fastapi.routing import APIRoute from sqlalchemy.exc import SQLAlchemyError, IntegrityError from psycopg.errors import UniqueViolation from starlette.concurrency import iterate_in_threadpool from starlette.background import BackgroundTask from .background import write_log async def app_middleware(request: Request, call_next): try: req_body = await request.json() except Exception: req_body = None start_time = time.perf_counter() response = await call_next(request) process_time = time.perf_counter() - start_time if request.url.path.split('/')[1] != 'static': res_body = [section async for section in response.body_iterator] response.body_iterator = iterate_in_threadpool(iter(res_body)) if res_body != None and len(res_body) > 0: res_body = res_body[0].decode() else: res_body = True #add the background task to the background response object to queue the job response.background = BackgroundTask(write_log, request, response, req_body, res_body, process_time) return response