import os import mimetypes from functools import partial from typing import Optional, Mapping from fastapi import Request, Response from fastapi.responses import RedirectResponse from fastapi.responses import PlainTextResponse from fastapi.responses import FileResponse from starlette.background import BackgroundTask from .common import templates def with_redirect( url: str = '/', code: int = 302, *args, **kwargs) -> RedirectResponse: """Return a redirect to the page specified in `url`. By default, code is 302 so method is changed to GET. To leave the same HTTP method, use 307 status code or call `with_redirect_307` function. `args` and `kwargs` are passed directly to the Response contructor Args: url (str, optional): Target URL, root by default code (int, optional): HTTP response code Returns: FastAPI's RedirectResponse object """ return RedirectResponse( url=url, status_code=code, *args, **kwargs, ) def with_text( content: str, code: int = 200, *args, **kwargs) -> PlainTextResponse: """Return a plain text to the user. `args` and `kwargs` are passed directly to the Response contructor Args: content (str): Plain text content code (int, optional): HTTP response code Returns: FastAPI's PlainTextResponse object """ return PlainTextResponse( content=content, status_code=code, *args, **kwargs, ) def with_tmpl( name: str, request: Request, code: int = 200, headers: Optional[Mapping[str, str]] = None, background: Optional[BackgroundTask] = None, **context) -> Response: """Render a Jinja2 template and return Response object. `response_class` parameter is not needed Args: name (str): Template filename request (Request): FastAPI request object code (int, optional): HTTP response code headers (Optional[Mapping[str, str]], optional): Additional headers, passed to Response constructor background (Optional[BackgroundTask], optional): Background task, passed to Response constructor Returns: FastAPI's TemplateResponse object """ return templates.TemplateResponse( name=name, context={ 'request': request, **context, }, status_code=code, headers=headers, background=background, ) def with_file( path: os.PathLike, mime: Optional[str] = None, code: int = 200, *args, **kwargs) -> FileResponse: """Send a file specified in `path` automatically guessing mimetype if `mime` is None. `args` and `kwargs` are passed directly to the Response contructor Args: path (os.PathLike): File path mime (Optional[str], optional): File mimetype code (int, optional): HTTP response code Returns: FileResponse: FastAPI's FileResponse object """ return FileResponse( path=path, media_type=( mime or mimetypes.guess_type(path)[0] ), status_code=code, *args, **kwargs, ) # Aliases with_template = with_tmpl with_redirect_302 = partial( with_redirect, code=302, ) with_redirect_307 = partial( with_redirect, code=307, )