init.py in submodules, aliases for different redirections

This commit is contained in:
DarkCat09 2023-02-20 12:41:29 +04:00
parent 03e4c63d38
commit 6b9d616808
7 changed files with 75 additions and 42 deletions

27
app/forms/__init__.py Normal file
View file

@ -0,0 +1,27 @@
"""Module containing WTForms classes
and helper functions for Starlette-WTF"""
from typing import Type, TypeVar
from fastapi import Request
from starlette_wtf import StarletteForm
T = TypeVar('T', bound=StarletteForm)
async def get_form(
form: Type[T],
req: Request) -> T:
"""Almost the same as `form.from_formdata`,
and must be used *instead* of instantiatng
form object directly as in Flask
Args:
form (Type[StarletteForm]): StarletteForm class
req (Request): Request object
Returns:
StarletteForm instance
"""
return await form.from_formdata(request=req)

View file

@ -9,8 +9,8 @@ from starlette_wtf import CSRFProtectMiddleware
from . import common from . import common
from .sql import db from .sql import db
# Add your paths here from .paths import Paths
from .paths.paths import Paths # Add your paths below
from .paths import pages from .paths import pages
from .paths import table from .paths import table
from .paths import errors from .paths import errors

View file

@ -1,3 +1,5 @@
"""Module containing FastAPI paths"""
import abc import abc
from fastapi import FastAPI from fastapi import FastAPI

View file

@ -5,7 +5,7 @@ from pathlib import Path
from fastapi import Request, Response from fastapi import Request, Response
from fastapi import HTTPException from fastapi import HTTPException
from . import paths from . import Paths
from .. import respond from .. import respond
from .. import common from .. import common
@ -13,7 +13,7 @@ from .. import common
codes = [404, 500] codes = [404, 500]
class ErrorsPaths(paths.Paths): class ErrorsPaths(Paths):
"""Sets up custom error pages, """Sets up custom error pages,
inherited from paths.Paths""" inherited from paths.Paths"""

View file

@ -2,11 +2,11 @@
from fastapi import Request, Response from fastapi import Request, Response
from . import paths from . import Paths
from .. import respond from .. import respond
class MainPaths(paths.Paths): class MainPaths(Paths):
"""Main FastAPI app paths, """Main FastAPI app paths,
inherits paths.Paths""" inherits paths.Paths"""

View file

@ -1,3 +1,5 @@
"""Paths related to working with database"""
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from fastapi import Depends from fastapi import Depends
@ -5,17 +7,18 @@ from fastapi import Request, Response
from starlette_wtf import csrf_protect from starlette_wtf import csrf_protect
from . import paths from . import Paths
from .. import respond from .. import respond
from ..sql import db from ..sql import db
from ..sql import crud from ..sql import crud
from ..sql import schemas from ..sql import schemas
from ..forms import get_form
from ..forms.users import AddUserForm from ..forms.users import AddUserForm
LIMIT = 10 LIMIT = 10
class TablePaths(paths.Paths): class TablePaths(Paths):
def add_paths(self) -> None: def add_paths(self) -> None:
@ -42,7 +45,7 @@ class TablePaths(paths.Paths):
req: Request, req: Request,
db_s: Session = Depends(db.get_db)) -> Response: db_s: Session = Depends(db.get_db)) -> Response:
form = await AddUserForm.from_formdata(request=req) form = await get_form(AddUserForm, req)
if await form.validate_on_submit(): if await form.validate_on_submit():

View file

@ -1,8 +1,9 @@
import os import os
import mimetypes import mimetypes
from functools import partial
from typing import Optional, Mapping from typing import Optional, Mapping
from fastapi import Response from fastapi import Request, Response
from fastapi.responses import RedirectResponse from fastapi.responses import RedirectResponse
from fastapi.responses import PlainTextResponse from fastapi.responses import PlainTextResponse
from fastapi.responses import FileResponse from fastapi.responses import FileResponse
@ -15,19 +16,17 @@ from .common import templates
def with_redirect( def with_redirect(
url: str = '/', url: str = '/',
code: int = 302, code: int = 302,
headers: Optional[Mapping[str, str]] = None, *args, **kwargs) -> RedirectResponse:
background: Optional[BackgroundTask] = None) -> Response: """Return a redirect to the page specified in `url`.
"""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: Args:
url (str, optional): url (str, optional): Target URL, root by default
Target URL (Location header),
root by default
code (int, optional): HTTP response code 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: Returns:
FastAPI's RedirectResponse object FastAPI's RedirectResponse object
@ -36,25 +35,21 @@ def with_redirect(
return RedirectResponse( return RedirectResponse(
url=url, url=url,
status_code=code, status_code=code,
headers=headers, *args, **kwargs,
background=background,
) )
def with_text( def with_text(
content: str, content: str,
code: int = 200, code: int = 200,
headers: Optional[Mapping[str, str]] = None, *args, **kwargs) -> PlainTextResponse:
background: Optional[BackgroundTask] = None) -> Response: """Return a plain text to the user.
"""Return a plain text to the user `args` and `kwargs` are passed directly
to the Response contructor
Args: Args:
content (str): Plain text content content (str): Plain text content
code (int, optional): HTTP response code 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: Returns:
FastAPI's PlainTextResponse object FastAPI's PlainTextResponse object
@ -63,13 +58,13 @@ def with_text(
return PlainTextResponse( return PlainTextResponse(
content=content, content=content,
status_code=code, status_code=code,
headers=headers, *args, **kwargs,
background=background,
) )
def with_tmpl( def with_tmpl(
name: str, name: str,
request: Request,
code: int = 200, code: int = 200,
headers: Optional[Mapping[str, str]] = None, headers: Optional[Mapping[str, str]] = None,
background: Optional[BackgroundTask] = None, background: Optional[BackgroundTask] = None,
@ -79,6 +74,7 @@ def with_tmpl(
Args: Args:
name (str): Template filename name (str): Template filename
request (Request): FastAPI request object
code (int, optional): HTTP response code code (int, optional): HTTP response code
headers (Optional[Mapping[str, str]], optional): headers (Optional[Mapping[str, str]], optional):
Additional headers, passed to Response constructor Additional headers, passed to Response constructor
@ -91,7 +87,10 @@ def with_tmpl(
return templates.TemplateResponse( return templates.TemplateResponse(
name=name, name=name,
context=context, context={
'request': request,
**context,
},
status_code=code, status_code=code,
headers=headers, headers=headers,
background=background, background=background,
@ -102,19 +101,16 @@ def with_file(
path: os.PathLike, path: os.PathLike,
mime: Optional[str] = None, mime: Optional[str] = None,
code: int = 200, code: int = 200,
headers: Optional[Mapping[str, str]] = None, *args, **kwargs) -> FileResponse:
background: Optional[BackgroundTask] = None) -> FileResponse:
"""Send a file specified in `path` """Send a file specified in `path`
automatically guessing mimetype if `mime` is None automatically guessing mimetype if `mime` is None.
`args` and `kwargs` are passed directly
to the Response contructor
Args: Args:
path (os.PathLike): File path path (os.PathLike): File path
mime (Optional[str], optional): File mimetype mime (Optional[str], optional): File mimetype
code (int, optional): HTTP response code 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: Returns:
FileResponse: FastAPI's FileResponse object FileResponse: FastAPI's FileResponse object
@ -127,10 +123,15 @@ def with_file(
mimetypes.guess_type(path)[0] mimetypes.guess_type(path)[0]
), ),
status_code=code, status_code=code,
headers=headers, *args, **kwargs,
background=background,
) )
# Alias # Aliases
with_template = with_tmpl with_template = with_tmpl
with_redirect_302 = partial(
with_redirect, code=302,
)
with_redirect_307 = partial(
with_redirect, code=307,
)