Compare commits
No commits in common. "107dbfaf7b27e1b22486b965a5dd38d7bf885463" and "354a473f77a90290ed856423c371cec777ae4796" have entirely different histories.
107dbfaf7b
...
354a473f77
25 changed files with 49 additions and 644 deletions
5
.env
5
.env
|
@ -1,5 +0,0 @@
|
||||||
MYSQL_HOST=${REPO_NAME_SNAKE}_db
|
|
||||||
MUSQL_PORT=3306
|
|
||||||
MYSQL_USER=${REPO_NAME_SNAKE}
|
|
||||||
MYSQL_PASSWORD=
|
|
||||||
MYSQL_DATABASE=${REPO_NAME_SNAKE}
|
|
|
@ -1,5 +0,0 @@
|
||||||
MYSQL_HOST=localhost
|
|
||||||
MUSQL_PORT=3306
|
|
||||||
MYSQL_USER=darkcat09
|
|
||||||
MYSQL_PASSWORD=
|
|
||||||
MYSQL_DATABASE=apptest
|
|
|
@ -1,6 +0,0 @@
|
||||||
app/*.py
|
|
||||||
templates/base.html
|
|
||||||
docker-compose.yml
|
|
||||||
Makefile
|
|
||||||
.env
|
|
||||||
README.md
|
|
52
.gitignore
vendored
52
.gitignore
vendored
|
@ -72,23 +72,56 @@ instance/
|
||||||
# Sphinx documentation
|
# Sphinx documentation
|
||||||
docs/_build/
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
# pyenv
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
# .python-version
|
# .python-version
|
||||||
|
|
||||||
# pipenv
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
#Pipfile.lock
|
#Pipfile.lock
|
||||||
|
|
||||||
# poetry
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
#poetry.lock
|
#poetry.lock
|
||||||
|
|
||||||
# pdm
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
#pdm.lock
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/#use-with-ide
|
||||||
.pdm.toml
|
.pdm.toml
|
||||||
|
|
||||||
# PEP 582
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
__pypackages__/
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
# Environments
|
# Environments
|
||||||
|
.env
|
||||||
.venv
|
.venv
|
||||||
env/
|
env/
|
||||||
venv/
|
venv/
|
||||||
|
@ -96,6 +129,13 @@ ENV/
|
||||||
env.bak/
|
env.bak/
|
||||||
venv.bak/
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
# mkdocs documentation
|
# mkdocs documentation
|
||||||
/site
|
/site
|
||||||
|
|
||||||
|
@ -113,6 +153,10 @@ dmypy.json
|
||||||
# Cython debug symbols
|
# Cython debug symbols
|
||||||
cython_debug/
|
cython_debug/
|
||||||
|
|
||||||
# IDE
|
# PyCharm
|
||||||
.vscode/
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
.idea/
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
FROM python:3-alpine
|
|
||||||
RUN apk update && apk upgrade && apk add py-pip make
|
|
||||||
WORKDIR /app
|
|
||||||
COPY . .
|
|
||||||
RUN pip install -r requirements.txt
|
|
||||||
CMD make prod
|
|
||||||
EXPOSE 8000
|
|
20
Makefile
20
Makefile
|
@ -1,20 +0,0 @@
|
||||||
dev:
|
|
||||||
DEBUG="true" python3 -m uvicorn main:app --reload
|
|
||||||
|
|
||||||
prod:
|
|
||||||
python3 -m uvicorn main:app
|
|
||||||
|
|
||||||
format:
|
|
||||||
python3 -m autopep8 -r --in-place app/
|
|
||||||
|
|
||||||
check:
|
|
||||||
python3 -m mypy app/
|
|
||||||
python3 -m pylint app/
|
|
||||||
|
|
||||||
docker:
|
|
||||||
docker build -t ${REPO_OWNER_LOWER}/${REPO_NAME_SNAKE} .
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf app/__pycache__
|
|
||||||
rm -rf __pycache__
|
|
||||||
rm -rf .mypy_cache
|
|
|
@ -1,24 +0,0 @@
|
||||||
import secrets
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from fastapi.templating import Jinja2Templates
|
|
||||||
from pydantic import BaseSettings
|
|
||||||
|
|
||||||
|
|
||||||
file_dir = Path(__file__).parent
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
|
||||||
secret_key: str = secrets.token_hex(32)
|
|
||||||
templates_dir: str = str(
|
|
||||||
file_dir.parent / 'templates'
|
|
||||||
)
|
|
||||||
static_dir: str = str(
|
|
||||||
file_dir.parent / 'static'
|
|
||||||
)
|
|
||||||
|
|
||||||
settings = Settings()
|
|
||||||
|
|
||||||
|
|
||||||
templates = Jinja2Templates(
|
|
||||||
directory=settings.templates_dir,
|
|
||||||
)
|
|
|
@ -1,50 +0,0 @@
|
||||||
"""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,
|
|
||||||
)
|
|
25
app/main.py
25
app/main.py
|
@ -1,25 +0,0 @@
|
||||||
from typing import List, Type
|
|
||||||
from fastapi import FastAPI
|
|
||||||
from fastapi.staticfiles import StaticFiles
|
|
||||||
|
|
||||||
from .common import settings
|
|
||||||
|
|
||||||
# Add your paths here
|
|
||||||
from .paths import Paths
|
|
||||||
from . import pages
|
|
||||||
from . import errors
|
|
||||||
|
|
||||||
paths: List[Type[Paths]] = [
|
|
||||||
pages.MainPaths,
|
|
||||||
errors.ErrorsPaths,
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI()
|
|
||||||
app.mount(
|
|
||||||
'/static',
|
|
||||||
StaticFiles(directory=settings.static_dir),
|
|
||||||
name='static',
|
|
||||||
)
|
|
||||||
for p in paths:
|
|
||||||
p(app).add_paths()
|
|
20
app/pages.py
20
app/pages.py
|
@ -1,20 +0,0 @@
|
||||||
"""Main FastAPI paths"""
|
|
||||||
|
|
||||||
from fastapi import Request, 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(req: Request) -> Response:
|
|
||||||
return respond.with_tmpl(
|
|
||||||
'index.html',
|
|
||||||
request=req,
|
|
||||||
)
|
|
21
app/paths.py
21
app/paths.py
|
@ -1,21 +0,0 @@
|
||||||
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"""
|
|
|
@ -1,77 +0,0 @@
|
||||||
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
|
|
|
@ -1,19 +0,0 @@
|
||||||
version: "3"
|
|
||||||
|
|
||||||
services:
|
|
||||||
${REPO_NAME_SNAKE}:
|
|
||||||
image: ${REPO_OWNER}/${REPO_NAME_SNAKE}:latest
|
|
||||||
container_name: ${REPO_NAME_SNAKE}
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "8080:8000"
|
|
||||||
links:
|
|
||||||
- ${REPO_NAME_SNAKE}_db
|
|
||||||
env_file: .env
|
|
||||||
${REPO_NAME_SNAKE}_db:
|
|
||||||
image: mariadb:latest
|
|
||||||
container_name: ${REPO_NAME_SNAKE}_db
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- "./database:/var/lib/mysql"
|
|
||||||
env_file: .env
|
|
9
main.py
9
main.py
|
@ -1,9 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import uvicorn
|
|
||||||
|
|
||||||
from app.main import app
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
uvicorn.run(app)
|
|
187
pylintrc
187
pylintrc
|
@ -1,187 +0,0 @@
|
||||||
[MAIN]
|
|
||||||
analyse-fallback-blocks=no
|
|
||||||
extension-pkg-allow-list=
|
|
||||||
extension-pkg-whitelist=
|
|
||||||
fail-on=
|
|
||||||
fail-under=10
|
|
||||||
ignore=CVS
|
|
||||||
ignore-paths=
|
|
||||||
ignore-patterns=^\.#
|
|
||||||
ignored-modules=
|
|
||||||
jobs=4
|
|
||||||
limit-inference-results=100
|
|
||||||
load-plugins=
|
|
||||||
persistent=yes
|
|
||||||
py-version=3.10
|
|
||||||
recursive=no
|
|
||||||
suggestion-mode=yes
|
|
||||||
unsafe-load-any-extension=no
|
|
||||||
|
|
||||||
[REPORTS]
|
|
||||||
evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10))
|
|
||||||
msg-template=
|
|
||||||
reports=no
|
|
||||||
score=yes
|
|
||||||
|
|
||||||
[MESSAGES CONTROL]
|
|
||||||
confidence=HIGH,
|
|
||||||
CONTROL_FLOW,
|
|
||||||
INFERENCE,
|
|
||||||
INFERENCE_FAILURE,
|
|
||||||
UNDEFINED
|
|
||||||
disable=raw-checker-failed,
|
|
||||||
bad-inline-option,
|
|
||||||
locally-disabled,
|
|
||||||
file-ignored,
|
|
||||||
suppressed-message,
|
|
||||||
useless-suppression,
|
|
||||||
deprecated-pragma,
|
|
||||||
use-symbolic-message-instead
|
|
||||||
enable=c-extension-no-member
|
|
||||||
|
|
||||||
[SIMILARITIES]
|
|
||||||
ignore-comments=yes
|
|
||||||
ignore-docstrings=yes
|
|
||||||
ignore-imports=yes
|
|
||||||
ignore-signatures=yes
|
|
||||||
min-similarity-lines=4
|
|
||||||
|
|
||||||
[MISCELLANEOUS]
|
|
||||||
notes=FIXME,
|
|
||||||
XXX,
|
|
||||||
TODO
|
|
||||||
notes-rgx=
|
|
||||||
|
|
||||||
[DESIGN]
|
|
||||||
exclude-too-few-public-methods=
|
|
||||||
ignored-parents=
|
|
||||||
max-args=5
|
|
||||||
max-attributes=7
|
|
||||||
max-bool-expr=5
|
|
||||||
max-branches=12
|
|
||||||
max-locals=15
|
|
||||||
max-parents=7
|
|
||||||
max-public-methods=20
|
|
||||||
max-returns=6
|
|
||||||
max-statements=50
|
|
||||||
min-public-methods=1
|
|
||||||
|
|
||||||
[STRING]
|
|
||||||
check-quote-consistency=no
|
|
||||||
check-str-concat-over-line-jumps=no
|
|
||||||
|
|
||||||
[CLASSES]
|
|
||||||
check-protected-access-in-special-methods=no
|
|
||||||
defining-attr-methods=__init__,
|
|
||||||
__new__,
|
|
||||||
setUp,
|
|
||||||
__post_init__
|
|
||||||
exclude-protected=_asdict,
|
|
||||||
_fields,
|
|
||||||
_replace,
|
|
||||||
_source,
|
|
||||||
_make
|
|
||||||
valid-classmethod-first-arg=cls
|
|
||||||
valid-metaclass-classmethod-first-arg=cls
|
|
||||||
|
|
||||||
[FORMAT]
|
|
||||||
expected-line-ending-format=
|
|
||||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
|
||||||
indent-after-paren=4
|
|
||||||
indent-string=' '
|
|
||||||
max-line-length=100
|
|
||||||
max-module-lines=1000
|
|
||||||
single-line-class-stmt=no
|
|
||||||
single-line-if-stmt=no
|
|
||||||
|
|
||||||
[IMPORTS]
|
|
||||||
allow-any-import-level=
|
|
||||||
allow-wildcard-with-all=no
|
|
||||||
deprecated-modules=
|
|
||||||
ext-import-graph=
|
|
||||||
import-graph=
|
|
||||||
int-import-graph=
|
|
||||||
known-standard-library=
|
|
||||||
known-third-party=enchant
|
|
||||||
preferred-modules=
|
|
||||||
|
|
||||||
[VARIABLES]
|
|
||||||
additional-builtins=
|
|
||||||
allow-global-unused-variables=yes
|
|
||||||
allowed-redefined-builtins=
|
|
||||||
callbacks=cb_,
|
|
||||||
_cb
|
|
||||||
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
|
||||||
ignored-argument-names=_.*|^ignored_|^unused_
|
|
||||||
init-import=no
|
|
||||||
redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
|
|
||||||
|
|
||||||
[LOGGING]
|
|
||||||
logging-format-style=old
|
|
||||||
logging-modules=logging
|
|
||||||
|
|
||||||
[EXCEPTIONS]
|
|
||||||
overgeneral-exceptions=BaseException,
|
|
||||||
Exception
|
|
||||||
|
|
||||||
[BASIC]
|
|
||||||
argument-naming-style=snake_case
|
|
||||||
attr-naming-style=snake_case
|
|
||||||
bad-names=foo,
|
|
||||||
bar,
|
|
||||||
baz,
|
|
||||||
toto,
|
|
||||||
tutu,
|
|
||||||
tata
|
|
||||||
bad-names-rgxs=
|
|
||||||
class-attribute-naming-style=any
|
|
||||||
class-const-naming-style=UPPER_CASE
|
|
||||||
class-naming-style=PascalCase
|
|
||||||
const-naming-style=any
|
|
||||||
docstring-min-length=-1
|
|
||||||
function-naming-style=snake_case
|
|
||||||
good-names=i,
|
|
||||||
j,
|
|
||||||
k,
|
|
||||||
f,
|
|
||||||
db,
|
|
||||||
ex,
|
|
||||||
Run,
|
|
||||||
_
|
|
||||||
good-names-rgxs=
|
|
||||||
include-naming-hint=no
|
|
||||||
inlinevar-naming-style=any
|
|
||||||
method-naming-style=snake_case
|
|
||||||
module-naming-style=snake_case
|
|
||||||
name-group=
|
|
||||||
no-docstring-rgx=^_
|
|
||||||
property-classes=abc.abstractproperty
|
|
||||||
variable-naming-style=snake_case
|
|
||||||
|
|
||||||
[SPELLING]
|
|
||||||
max-spelling-suggestions=4
|
|
||||||
spelling-dict=
|
|
||||||
spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:
|
|
||||||
spelling-ignore-words=
|
|
||||||
spelling-private-dict-file=
|
|
||||||
spelling-store-unknown-words=no
|
|
||||||
|
|
||||||
[TYPECHECK]
|
|
||||||
contextmanager-decorators=contextlib.contextmanager
|
|
||||||
generated-members=
|
|
||||||
ignore-none=yes
|
|
||||||
ignore-on-opaque-inference=yes
|
|
||||||
ignored-checks-for-mixins=no-member,
|
|
||||||
not-async-context-manager,
|
|
||||||
not-context-manager,
|
|
||||||
attribute-defined-outside-init
|
|
||||||
ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace
|
|
||||||
missing-member-hint=yes
|
|
||||||
missing-member-hint-distance=1
|
|
||||||
missing-member-max-choices=1
|
|
||||||
mixin-class-rgx=.*[Mm]ixin
|
|
||||||
signature-mutators=
|
|
||||||
|
|
||||||
[REFACTORING]
|
|
||||||
max-nested-blocks=5
|
|
||||||
never-returning-functions=sys.exit,argparse.parse_error
|
|
|
@ -1,5 +0,0 @@
|
||||||
fastapi==0.92.0
|
|
||||||
uvicorn[standard]==0.20.0
|
|
||||||
jinja2==3.1.2
|
|
||||||
starlette-wtf==0.4.3
|
|
||||||
python-dotenv==0.21.1
|
|
|
@ -1,60 +0,0 @@
|
||||||
body {
|
|
||||||
height: 100vh;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
font-family: sans-serif;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
--bg: #fff;
|
|
||||||
--fg: #000;
|
|
||||||
|
|
||||||
background: var(--bg);
|
|
||||||
color: var(--fg);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
body {
|
|
||||||
--bg: #202023;
|
|
||||||
--fg: #eee;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
header { margin-top: 5px; }
|
|
||||||
footer { margin-bottom: 5px; }
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #5b8a55;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
filter: brightness(120%);
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
form > div {
|
|
||||||
margin-top: 5px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: end;
|
|
||||||
}
|
|
||||||
form > div > label {
|
|
||||||
width: 50%;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
form > div > input {
|
|
||||||
width: 50%;
|
|
||||||
border: 1px solid var(--fg);
|
|
||||||
outline: none;
|
|
||||||
background: var(--bg);
|
|
||||||
color: var(--fg);
|
|
||||||
}
|
|
||||||
form > div > input:hover,
|
|
||||||
form > div > input:focus {
|
|
||||||
filter: brightness(130%);
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
addEventListener('load', () => {
|
|
||||||
document.getElementById('js')
|
|
||||||
.innerText = new Date().toLocaleString()
|
|
||||||
})
|
|
|
@ -1,11 +0,0 @@
|
||||||
{% extends "base.html" %}
|
|
||||||
|
|
||||||
{% block title %}404{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h1>404: Not Found</h1>
|
|
||||||
<p>
|
|
||||||
Go to the
|
|
||||||
<a href="/">main page</a>
|
|
||||||
</p>
|
|
||||||
{% endblock %}
|
|
|
@ -1,15 +0,0 @@
|
||||||
{% extends "base.html" %}
|
|
||||||
|
|
||||||
{% block title %}500{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h1>500: ISE</h1>
|
|
||||||
<p>
|
|
||||||
An error occured while
|
|
||||||
processing your request.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Please, try again later
|
|
||||||
or contact web site admin.
|
|
||||||
</p>
|
|
||||||
{% endblock %}
|
|
|
@ -1,21 +0,0 @@
|
||||||
{% extends "base.html" %}
|
|
||||||
|
|
||||||
{% block title %}Admin{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h1>Add a person to DB</h1>
|
|
||||||
<form action="/add" method="post">
|
|
||||||
{{ form.hidden_tag() }}
|
|
||||||
{% for field in form %}
|
|
||||||
{% if field.name != 'csrf_token' %}
|
|
||||||
<div>
|
|
||||||
{{ field.label }}
|
|
||||||
{{ field }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
<div>
|
|
||||||
<input type="submit" value="Add">
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
|
|
@ -1,18 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<meta name="description" content="${REPO_DESCRIPTION}">
|
|
||||||
<title>{% block title %}{% endblock %} | ${REPO_NAME}</title>
|
|
||||||
<link rel="stylesheet" href="/static/css/style.css">
|
|
||||||
<script src="/static/js/script.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<header>${REPO_NAME}</header>
|
|
||||||
<article>
|
|
||||||
{% block content %}{% endblock %}
|
|
||||||
</article>
|
|
||||||
<footer id="js"></footer>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,12 +0,0 @@
|
||||||
{% extends "base.html" %}
|
|
||||||
|
|
||||||
{% block title %}Main page{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h1>
|
|
||||||
This is the default main page of
|
|
||||||
<a href="https://git.dc09.ru/DarkCat09/tmpl-fastapi">
|
|
||||||
FastAPI app template
|
|
||||||
</a>
|
|
||||||
</h1>
|
|
||||||
{% endblock %}
|
|
|
@ -1,18 +0,0 @@
|
||||||
{% extends "base.html" %}
|
|
||||||
|
|
||||||
{% block title %}Database{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h1>Sample database</h1>
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
{% for row in rows %}
|
|
||||||
<tr>
|
|
||||||
{% for cell in row %}
|
|
||||||
<td>{{ cell }}</td>
|
|
||||||
{% endfor %}
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{% endblock %}
|
|
Loading…
Add table
Reference in a new issue