From 4193ce3b4ed2c67a1509956458381d2d010e7e6f Mon Sep 17 00:00:00 2001 From: mwiegand Date: Thu, 23 Apr 2026 01:02:33 +0200 Subject: [PATCH] feat(l4d2-web): scaffold flask app and health endpoint --- components/l4d2-web-app/README.md | 1 + components/l4d2-web-app/pyproject.toml | 22 +++++++++++++++++++ .../l4d2-web-app/src/l4d2web/__init__.py | 3 +++ components/l4d2-web-app/src/l4d2web/app.py | 16 ++++++++++++++ components/l4d2-web-app/src/l4d2web/config.py | 8 +++++++ components/l4d2-web-app/tests/test_health.py | 11 ++++++++++ 6 files changed, 61 insertions(+) create mode 100644 components/l4d2-web-app/README.md create mode 100644 components/l4d2-web-app/pyproject.toml create mode 100644 components/l4d2-web-app/src/l4d2web/__init__.py create mode 100644 components/l4d2-web-app/src/l4d2web/app.py create mode 100644 components/l4d2-web-app/src/l4d2web/config.py create mode 100644 components/l4d2-web-app/tests/test_health.py diff --git a/components/l4d2-web-app/README.md b/components/l4d2-web-app/README.md new file mode 100644 index 0000000..77211d1 --- /dev/null +++ b/components/l4d2-web-app/README.md @@ -0,0 +1 @@ +# l4d2-web-app diff --git a/components/l4d2-web-app/pyproject.toml b/components/l4d2-web-app/pyproject.toml new file mode 100644 index 0000000..a5100a4 --- /dev/null +++ b/components/l4d2-web-app/pyproject.toml @@ -0,0 +1,22 @@ +[build-system] +requires = ["setuptools>=68", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "l4d2web" +version = "0.1.0" +description = "L4D2 web app" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [ + "Flask>=3.0", + "SQLAlchemy>=2.0", + "alembic>=1.13", + "PyYAML>=6.0", +] + +[tool.setuptools] +package-dir = {"" = "src"} + +[tool.setuptools.packages.find] +where = ["src"] diff --git a/components/l4d2-web-app/src/l4d2web/__init__.py b/components/l4d2-web-app/src/l4d2web/__init__.py new file mode 100644 index 0000000..a05eb9a --- /dev/null +++ b/components/l4d2-web-app/src/l4d2web/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["__version__"] + +__version__ = "0.1.0" diff --git a/components/l4d2-web-app/src/l4d2web/app.py b/components/l4d2-web-app/src/l4d2web/app.py new file mode 100644 index 0000000..5f955d2 --- /dev/null +++ b/components/l4d2-web-app/src/l4d2web/app.py @@ -0,0 +1,16 @@ +from flask import Flask, jsonify + +from l4d2web.config import DEFAULT_CONFIG + + +def create_app(test_config: dict[str, object] | None = None) -> Flask: + app = Flask(__name__) + app.config.from_mapping(DEFAULT_CONFIG) + if test_config is not None: + app.config.update(test_config) + + @app.get("/health") + def health(): + return jsonify({"status": "ok"}) + + return app diff --git a/components/l4d2-web-app/src/l4d2web/config.py b/components/l4d2-web-app/src/l4d2web/config.py new file mode 100644 index 0000000..ad7ea2e --- /dev/null +++ b/components/l4d2-web-app/src/l4d2web/config.py @@ -0,0 +1,8 @@ +DEFAULT_CONFIG: dict[str, object] = { + "SECRET_KEY": "dev", + "DATABASE_URL": "sqlite:///l4d2web.db", + "STATUS_REFRESH_SECONDS": 8, + "JOB_WORKER_THREADS": 4, + "JOB_LOG_REPLAY_LIMIT": 2000, + "JOB_LOG_LINE_MAX_CHARS": 4096, +} diff --git a/components/l4d2-web-app/tests/test_health.py b/components/l4d2-web-app/tests/test_health.py new file mode 100644 index 0000000..a70466a --- /dev/null +++ b/components/l4d2-web-app/tests/test_health.py @@ -0,0 +1,11 @@ +from l4d2web.app import create_app + + +def test_health_endpoint() -> None: + app = create_app({"TESTING": True}) + client = app.test_client() + + response = client.get("/health") + + assert response.status_code == 200 + assert response.get_json() == {"status": "ok"}