feat: initial Flask project setup with factory pattern
This commit is contained in:
39
app/__init__.py
Normal file
39
app/__init__.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
from flask import Flask
|
||||||
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
import tomllib
|
||||||
|
import os
|
||||||
|
|
||||||
|
db = SQLAlchemy()
|
||||||
|
|
||||||
|
|
||||||
|
def create_app(config_path=None):
|
||||||
|
app = Flask(__name__, instance_relative_config=True)
|
||||||
|
|
||||||
|
os.makedirs(app.instance_path, exist_ok=True)
|
||||||
|
|
||||||
|
app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{os.path.join(app.instance_path, 'worklog.db')}"
|
||||||
|
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
||||||
|
app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY", "dev-secret-change-in-prod")
|
||||||
|
|
||||||
|
# Load TOML config
|
||||||
|
if config_path is None:
|
||||||
|
config_path = os.path.join(os.path.dirname(app.root_path), "config.toml")
|
||||||
|
if os.path.exists(config_path):
|
||||||
|
with open(config_path, "rb") as f:
|
||||||
|
app.config["TOML"] = tomllib.load(f)
|
||||||
|
else:
|
||||||
|
app.config["TOML"] = {}
|
||||||
|
|
||||||
|
db.init_app(app)
|
||||||
|
|
||||||
|
from app.routes.dashboard import bp as dashboard_bp
|
||||||
|
from app.routes.entries import bp as entries_bp
|
||||||
|
from app.routes.reports import bp as reports_bp
|
||||||
|
app.register_blueprint(dashboard_bp)
|
||||||
|
app.register_blueprint(entries_bp)
|
||||||
|
app.register_blueprint(reports_bp)
|
||||||
|
|
||||||
|
with app.app_context():
|
||||||
|
db.create_all()
|
||||||
|
|
||||||
|
return app
|
||||||
BIN
app/__pycache__/__init__.cpython-314.pyc
Normal file
BIN
app/__pycache__/__init__.cpython-314.pyc
Normal file
Binary file not shown.
0
app/routes/__init__.py
Normal file
0
app/routes/__init__.py
Normal file
BIN
app/routes/__pycache__/__init__.cpython-314.pyc
Normal file
BIN
app/routes/__pycache__/__init__.cpython-314.pyc
Normal file
Binary file not shown.
BIN
app/routes/__pycache__/dashboard.cpython-314.pyc
Normal file
BIN
app/routes/__pycache__/dashboard.cpython-314.pyc
Normal file
Binary file not shown.
BIN
app/routes/__pycache__/entries.cpython-314.pyc
Normal file
BIN
app/routes/__pycache__/entries.cpython-314.pyc
Normal file
Binary file not shown.
BIN
app/routes/__pycache__/reports.cpython-314.pyc
Normal file
BIN
app/routes/__pycache__/reports.cpython-314.pyc
Normal file
Binary file not shown.
3
app/routes/dashboard.py
Normal file
3
app/routes/dashboard.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from flask import Blueprint
|
||||||
|
|
||||||
|
bp = Blueprint("dashboard", __name__)
|
||||||
3
app/routes/entries.py
Normal file
3
app/routes/entries.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from flask import Blueprint
|
||||||
|
|
||||||
|
bp = Blueprint("entries", __name__)
|
||||||
3
app/routes/reports.py
Normal file
3
app/routes/reports.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from flask import Blueprint
|
||||||
|
|
||||||
|
bp = Blueprint("reports", __name__)
|
||||||
5
requirements.txt
Normal file
5
requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
flask>=3.0
|
||||||
|
flask-sqlalchemy>=3.1
|
||||||
|
pytest>=8.0
|
||||||
|
pytest-flask>=1.3
|
||||||
|
gunicorn>=22.0
|
||||||
6
run.py
Normal file
6
run.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from app import create_app
|
||||||
|
|
||||||
|
app = create_app()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(debug=True)
|
||||||
60
tests/conftest.py
Normal file
60
tests/conftest.py
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import pytest
|
||||||
|
from app import create_app, db as _db
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def app(tmp_path):
|
||||||
|
config_path = tmp_path / "config.toml"
|
||||||
|
config_path.write_text("""
|
||||||
|
[vehicles.voiture]
|
||||||
|
name = "Peugeot 308"
|
||||||
|
fuel = "diesel"
|
||||||
|
co2_per_km = 142
|
||||||
|
cv = 5
|
||||||
|
|
||||||
|
[vehicles.velo]
|
||||||
|
name = "Vélo"
|
||||||
|
fuel = "none"
|
||||||
|
co2_per_km = 0
|
||||||
|
|
||||||
|
[journeys.voiture_seule]
|
||||||
|
name = "Voiture seule"
|
||||||
|
distances = { voiture = 25 }
|
||||||
|
|
||||||
|
[journeys.voiture_velo]
|
||||||
|
name = "Voiture + Vélo"
|
||||||
|
distances = { voiture = 14, velo = 8 }
|
||||||
|
|
||||||
|
[journeys.velo_seul]
|
||||||
|
name = "Vélo seul"
|
||||||
|
distances = { velo = 24 }
|
||||||
|
|
||||||
|
[[bareme_kilometrique.2025.cv_5.tranches]]
|
||||||
|
km_max = 3000
|
||||||
|
taux = 0.548
|
||||||
|
forfait = 0
|
||||||
|
|
||||||
|
[[bareme_kilometrique.2025.cv_5.tranches]]
|
||||||
|
km_max = 6000
|
||||||
|
taux = 0.316
|
||||||
|
forfait = 699
|
||||||
|
|
||||||
|
[[bareme_kilometrique.2025.cv_5.tranches]]
|
||||||
|
km_max = 0
|
||||||
|
taux = 0.364
|
||||||
|
forfait = 0
|
||||||
|
""", encoding="utf-8")
|
||||||
|
|
||||||
|
application = create_app(config_path=str(config_path))
|
||||||
|
application.config["TESTING"] = True
|
||||||
|
application.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:"
|
||||||
|
|
||||||
|
with application.app_context():
|
||||||
|
_db.create_all()
|
||||||
|
yield application
|
||||||
|
_db.drop_all()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def client(app):
|
||||||
|
return app.test_client()
|
||||||
Reference in New Issue
Block a user