Implemented get_db for MySQL, wrapped all routes in classes

This commit is contained in:
DarkCat09 2023-02-15 19:55:06 +04:00
parent c7da7e32b7
commit 2f55d03aab
7 changed files with 130 additions and 42 deletions

View file

@ -2,11 +2,21 @@
import os
import secrets
from typing import Optional
from typing import Type, List
from flask import Flask
from flaskext.mysql import MySQL # type: ignore
from . import routes
from .routes import Routes
from . import pages
from . import errors
from . import db
routes: List[Type[Routes]] = [
pages.RoutePages,
errors.RouteErrors,
]
def create_app() -> Flask:
@ -26,14 +36,45 @@ def create_app() -> Flask:
secrets.token_hex(32),
)
# Setup MySQL database
app.config.update({
'MYSQL_DATABASE_HOST': os.getenv('DB_HOST', 'localhost'),
'MYSQL_DATABASE_PORT': parseint(os.getenv('DB_PORT'), 3306),
'MYSQL_DATABASE_USER': os.getenv('DB_USER', 'root'),
'MYSQL_DATABASE_PASSWORD': os.getenv('DB_PASSWORD', ''),
'MYSQL_DATABASE_DB': os.getenv('DB_DATABASE', '${REPO_NAME_SNAKE}'),
})
sql = MySQL(app)
db.set_db(sql)
# Create instance/ directory
try:
os.makedirs(app.instance_path)
except OSError:
pass
# Add routes
routes.add_routes(app)
errors.add_routes(app)
# Add all routes
for r in routes:
r(app).add_routes()
return app
def parseint(
value: Optional[str],
default: int) -> Optional[int]:
"""Parses integer from the string,
returns default value on error
Args:
value (Optional[str]): String or None
default (int): Default value
Returns:
Integer or None
"""
try:
return int(value or default)
except ValueError:
return default

25
flaskapp/db.py Normal file
View file

@ -0,0 +1,25 @@
"""Simple wrapper for getting/setting
db key in global Flask object called `g`"""
from flask import g
from flaskext.mysql import MySQL # type: ignore
def set_db(db: MySQL) -> None:
"""Add the database to `g` object
Args:
db (MySQL): MySQL database
"""
g.db = db
def get_db() -> MySQL:
"""Get the database from `g` object
Returns:
MySQL database
"""
return g.db

View file

@ -5,44 +5,43 @@ from pathlib import Path
from flask import Flask
from flask import render_template
from . import routes
# Add other HTTP error codes here
CODES = [404, 500]
def add_routes(app: Flask) -> None:
"""Add all error handlers
class RouteErrors(routes.Routes):
"""Error handlers wrapped in Routes interface"""
Args:
app (Flask): Flask application
"""
def __init__(self, app: Flask) -> None:
tmpl_dir = app.template_folder
super().__init__(app)
tmpl_dir = self.app.template_folder
if tmpl_dir is None:
return
tmpl = Path(__file__).parent / tmpl_dir
self.tmpl = Path(__file__).parent / tmpl_dir
def add_routes(self) -> None:
"""Add all error handlers"""
for code in CODES:
add_handler(app, tmpl, code)
self.add_handler(code)
def add_handler(
app: Flask,
tmpl: Path,
code: int) -> None:
def add_handler(self, code: int) -> None:
"""Add Flask app error handler.
Only for internal use
Args:
app (Flask): Flask application
file (str): Template filename
code (int): Error code
code (int): HTTP error code
"""
file = f'{code}.html'
if (tmpl / file).exists():
if (self.tmpl / file).exists():
@app.errorhandler(code)
@self.app.errorhandler(code)
def handler(_e):
return render_template(file), code

15
flaskapp/pages.py Normal file
View file

@ -0,0 +1,15 @@
"""Main Flask app routes"""
from flask import render_template
from . import routes
class RoutePages(routes.Routes):
"""Main Flask app routes"""
def add_routes(self) -> None:
@self.app.route('/')
def index():
return render_template('index.html')

View file

@ -1,16 +1,22 @@
"""Main Flask app routes"""
"""Interface for all routes classes"""
import abc
from flask import Flask
from flask import render_template
def add_routes(app: Flask) -> None:
"""Add main routes
class Routes(abc.ABC):
"""Flask app routes interface"""
def __init__(self, app: Flask) -> None:
"""Flask app routes
Args:
app (Flask): Flask application
"""
@app.route('/')
def index():
return render_template('index.html')
self.app = app
@abc.abstractmethod
def add_routes(self) -> None:
"""Add routes"""

View file

@ -64,7 +64,7 @@ max-parents=7
max-public-methods=20
max-returns=6
max-statements=50
min-public-methods=2
min-public-methods=1
[STRING]
check-quote-consistency=no
@ -144,6 +144,7 @@ good-names=i,
j,
k,
f,
db,
ex,
Run,
_

View file

@ -1,2 +1,3 @@
flask==2.2.2
flask-mysql==1.5.2
gunicorn==20.1.0