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 os
import secrets import secrets
from typing import Optional
from typing import Type, List
from flask import Flask 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 errors
from . import db
routes: List[Type[Routes]] = [
pages.RoutePages,
errors.RouteErrors,
]
def create_app() -> Flask: def create_app() -> Flask:
@ -26,14 +36,45 @@ def create_app() -> Flask:
secrets.token_hex(32), 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 # Create instance/ directory
try: try:
os.makedirs(app.instance_path) os.makedirs(app.instance_path)
except OSError: except OSError:
pass pass
# Add routes # Add all routes
routes.add_routes(app) for r in routes:
errors.add_routes(app) r(app).add_routes()
return app 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 Flask
from flask import render_template from flask import render_template
from . import routes
# Add other HTTP error codes here # Add other HTTP error codes here
CODES = [404, 500] CODES = [404, 500]
def add_routes(app: Flask) -> None: class RouteErrors(routes.Routes):
"""Add all error handlers """Error handlers wrapped in Routes interface"""
Args: def __init__(self, app: Flask) -> None:
app (Flask): Flask application
"""
tmpl_dir = app.template_folder super().__init__(app)
if tmpl_dir is None:
return
tmpl = Path(__file__).parent / tmpl_dir tmpl_dir = self.app.template_folder
if tmpl_dir is None:
return
for code in CODES: self.tmpl = Path(__file__).parent / tmpl_dir
add_handler(app, tmpl, code)
def add_routes(self) -> None:
"""Add all error handlers"""
def add_handler( for code in CODES:
app: Flask, self.add_handler(code)
tmpl: Path,
code: int) -> None:
"""Add Flask app error handler.
Only for internal use
Args: def add_handler(self, code: int) -> None:
app (Flask): Flask application """Add Flask app error handler.
file (str): Template filename Only for internal use
code (int): Error code
"""
file = f'{code}.html' Args:
code (int): HTTP error code
"""
if (tmpl / file).exists(): file = f'{code}.html'
@app.errorhandler(code) if (self.tmpl / file).exists():
def handler(_e):
return render_template(file), 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 Flask
from flask import render_template
def add_routes(app: Flask) -> None: class Routes(abc.ABC):
"""Add main routes """Flask app routes interface"""
Args: def __init__(self, app: Flask) -> None:
app (Flask): Flask application """Flask app routes
"""
@app.route('/') Args:
def index(): app (Flask): Flask application
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-public-methods=20
max-returns=6 max-returns=6
max-statements=50 max-statements=50
min-public-methods=2 min-public-methods=1
[STRING] [STRING]
check-quote-consistency=no check-quote-consistency=no
@ -144,6 +144,7 @@ good-names=i,
j, j,
k, k,
f, f,
db,
ex, ex,
Run, Run,
_ _

View file

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