Implemented get_db for MySQL, wrapped all routes in classes
This commit is contained in:
parent
c7da7e32b7
commit
2f55d03aab
7 changed files with 130 additions and 42 deletions
|
@ -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
25
flaskapp/db.py
Normal 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
|
|
@ -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
15
flaskapp/pages.py
Normal 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')
|
|
@ -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"""
|
||||||
|
|
3
pylintrc
3
pylintrc
|
@ -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,
|
||||||
_
|
_
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue