Config -> common.py, added paths, respond.py functions and templates
This commit is contained in:
parent
bfea5eeb06
commit
804e07b555
6 changed files with 182 additions and 8 deletions
17
app/common.py
Normal file
17
app/common.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import secrets
|
||||||
|
|
||||||
|
from fastapi.templating import Jinja2Templates
|
||||||
|
from pydantic import BaseSettings
|
||||||
|
|
||||||
|
|
||||||
|
class Settings(BaseSettings):
|
||||||
|
secret_key: str = secrets.token_hex(32)
|
||||||
|
templates_dir: str = '../templates'
|
||||||
|
static_dir: str = '../static'
|
||||||
|
|
||||||
|
settings = Settings()
|
||||||
|
|
||||||
|
|
||||||
|
templates = Jinja2Templates(
|
||||||
|
directory=settings.templates_dir,
|
||||||
|
)
|
50
app/errors.py
Normal file
50
app/errors.py
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
"""Custom error pages for FastAPI app"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from fastapi import Request, Response
|
||||||
|
from fastapi import HTTPException
|
||||||
|
|
||||||
|
from . import paths
|
||||||
|
from . import respond
|
||||||
|
from .common import settings
|
||||||
|
|
||||||
|
# Add other HTTP error codes
|
||||||
|
codes = [404, 500]
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorsPaths(paths.Paths):
|
||||||
|
"""Sets up custom error pages,
|
||||||
|
inherited from paths.Paths"""
|
||||||
|
|
||||||
|
def add_paths(self) -> None:
|
||||||
|
|
||||||
|
for code in codes:
|
||||||
|
self.add_handler(code)
|
||||||
|
|
||||||
|
def add_handler(self, code: int) -> None:
|
||||||
|
"""Adds an error handler to FastAPI app.
|
||||||
|
Only for internal use!
|
||||||
|
|
||||||
|
Args:
|
||||||
|
code (int): HTTP error code
|
||||||
|
"""
|
||||||
|
|
||||||
|
tmpl_dir = (
|
||||||
|
Path(__file__).parent /
|
||||||
|
settings.templates_dir
|
||||||
|
)
|
||||||
|
file = tmpl_dir / f'{code}.html'
|
||||||
|
|
||||||
|
if not file.exists():
|
||||||
|
return
|
||||||
|
|
||||||
|
@self.app.exception_handler(code)
|
||||||
|
async def handler(req: Request, exc: HTTPException) -> Response:
|
||||||
|
|
||||||
|
return respond.with_tmpl(
|
||||||
|
f'{code}.html',
|
||||||
|
code=code,
|
||||||
|
request=req,
|
||||||
|
exc=exc,
|
||||||
|
)
|
|
@ -1,16 +1,9 @@
|
||||||
import secrets
|
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
|
||||||
from pydantic import BaseSettings
|
#from .common import settings, templates
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
|
||||||
secret_key: str = secrets.token_hex(32)
|
|
||||||
|
|
||||||
|
|
||||||
settings = Settings()
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
app.mount(
|
app.mount(
|
||||||
'/static',
|
'/static',
|
||||||
|
|
16
app/pages.py
Normal file
16
app/pages.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
"""Main FastAPI paths"""
|
||||||
|
|
||||||
|
from fastapi import Response
|
||||||
|
|
||||||
|
from . import paths
|
||||||
|
from . import respond
|
||||||
|
|
||||||
|
|
||||||
|
class MainPaths(paths.Paths):
|
||||||
|
"""Main FastAPI app paths, inherits paths.Paths"""
|
||||||
|
|
||||||
|
def add_paths(self) -> None:
|
||||||
|
|
||||||
|
@self.app.get('/')
|
||||||
|
def index() -> Response:
|
||||||
|
return respond.with_tmpl('index.html')
|
21
app/paths.py
Normal file
21
app/paths.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import abc
|
||||||
|
|
||||||
|
from fastapi import FastAPI
|
||||||
|
|
||||||
|
|
||||||
|
class Paths(abc.ABC):
|
||||||
|
"""Abstract class for storing paths for FastAPI app"""
|
||||||
|
|
||||||
|
def __init__(self, app: FastAPI) -> None:
|
||||||
|
"""Abstract class for storing paths
|
||||||
|
for FastAPI app
|
||||||
|
|
||||||
|
Args:
|
||||||
|
app (FastAPI): Application object
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.app = app
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def add_paths(self) -> None:
|
||||||
|
"""Add paths to the FastAPI application"""
|
77
app/respond.py
Normal file
77
app/respond.py
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
import os
|
||||||
|
import mimetypes
|
||||||
|
from typing import Optional, Mapping
|
||||||
|
|
||||||
|
from fastapi import Response
|
||||||
|
from fastapi.responses import FileResponse
|
||||||
|
from starlette.background import BackgroundTask
|
||||||
|
|
||||||
|
from .common import templates
|
||||||
|
|
||||||
|
|
||||||
|
def with_tmpl(
|
||||||
|
name: str,
|
||||||
|
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
|
||||||
|
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=context,
|
||||||
|
status_code=code,
|
||||||
|
headers=headers,
|
||||||
|
background=background,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def with_file(
|
||||||
|
path: os.PathLike,
|
||||||
|
mime: Optional[str] = None,
|
||||||
|
code: int = 200,
|
||||||
|
headers: Optional[Mapping[str, str]] = None,
|
||||||
|
background: Optional[BackgroundTask] = None) -> FileResponse:
|
||||||
|
"""Send a file specified in `path`
|
||||||
|
automatically guessing mimetype if `mime` is None
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path (os.PathLike): File path
|
||||||
|
mime (Optional[str], optional): File mimetype
|
||||||
|
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:
|
||||||
|
FileResponse: FastAPI's FileResponse object
|
||||||
|
"""
|
||||||
|
|
||||||
|
return FileResponse(
|
||||||
|
path=path,
|
||||||
|
media_type=(
|
||||||
|
mime or
|
||||||
|
mimetypes.guess_type(path)[0]
|
||||||
|
),
|
||||||
|
status_code=code,
|
||||||
|
headers=headers,
|
||||||
|
background=background,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Alias
|
||||||
|
with_template = with_tmpl
|
Loading…
Reference in a new issue