azurefunctions-extensions-http-fastapi/azurefunctions/extensions/http/fastapi/web.py (108 lines of code) (raw):

# Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. from typing import Callable import uvicorn from azurefunctions.extensions.base import ( RequestSynchronizer, RequestTrackerMeta, ResponseLabels, ResponseTrackerMeta, WebApp, WebServer, ) from fastapi import FastAPI from fastapi import Request as FastApiRequest from fastapi import Response as FastApiResponse from fastapi.responses import FileResponse as FastApiFileResponse from fastapi.responses import HTMLResponse as FastApiHTMLResponse from fastapi.responses import JSONResponse as FastApiJSONResponse from fastapi.responses import ORJSONResponse as FastApiORJSONResponse from fastapi.responses import PlainTextResponse as FastApiPlainTextResponse from fastapi.responses import RedirectResponse as FastApiRedirectResponse from fastapi.responses import StreamingResponse as FastApiStreamingResponse from fastapi.responses import UJSONResponse as FastApiUJSONResponse from pydantic import BaseModel class RequestSynchronizer(RequestSynchronizer): def sync_route_params(self, request, path_params): # add null checks for request and path_params if request is None: raise TypeError("Request object is None") if path_params is None: raise TypeError("Path parameters are None") request.path_params.clear() request.path_params.update(path_params) class Request(metaclass=RequestTrackerMeta): request_type = FastApiRequest synchronizer = RequestSynchronizer() class Response(metaclass=ResponseTrackerMeta): label = ResponseLabels.STANDARD response_type = FastApiResponse class StreamingResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.STREAMING response_type = FastApiStreamingResponse class HTMLResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.HTML response_type = FastApiHTMLResponse class PlainTextResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.PLAIN_TEXT response_type = FastApiPlainTextResponse class RedirectResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.REDIRECT response_type = FastApiRedirectResponse class JSONResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.JSON response_type = FastApiJSONResponse class UJSONResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.UJSON response_type = FastApiUJSONResponse class ORJSONResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.ORJSON response_type = FastApiORJSONResponse class FileResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.FILE response_type = FastApiFileResponse class StrResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.STR response_type = str class DictResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.DICT response_type = dict class BoolResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.BOOL response_type = bool class PydanticResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.PYDANTIC response_type = BaseModel class IntResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.INT response_type = int class FloatResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.FLOAT response_type = float class ListResponse(metaclass=ResponseTrackerMeta): label = ResponseLabels.LIST response_type = list class WebApp(WebApp): def __init__(self): self.web_app = FastAPI() def route(self, func: Callable): # Apply the api_route decorator decorated_function = self.web_app.api_route( "/{path:path}", methods=[ "GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE", ], )(func) return decorated_function def get_app(self): return self.web_app class WebServer(WebServer): async def serve(self): uvicorn_config = uvicorn.Config( self.web_app, host=self.hostname, port=self.port ) server = uvicorn.Server(uvicorn_config) return await server.serve()