Add WSGI entry point and gunicorn; default debug off
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X9jG4CUFcH6n4vFvgtwndY
This commit is contained in:
parent
0eb33d9120
commit
4c5ba24a1d
5 changed files with 29 additions and 1 deletions
|
|
@ -69,6 +69,14 @@ uv run admin-analytics dashboard
|
|||
|
||||
Opens at [http://localhost:8050](http://localhost:8050). Use `--port` to change the port, or `--host 0.0.0.0` for network access (e.g. over Tailscale).
|
||||
|
||||
For a production server, run it under gunicorn instead of Dash's development server:
|
||||
|
||||
```bash
|
||||
uv run gunicorn -w 2 -b 127.0.0.1:8050 admin_analytics.dashboard.wsgi:server
|
||||
```
|
||||
|
||||
Each worker opens its own read-only DuckDB connection. Don't use `--preload`, which would share one connection across forked workers.
|
||||
|
||||
The dashboard must be restarted to pick up newly ingested data (DuckDB opens in read-only mode to avoid lock conflicts).
|
||||
|
||||
The dashboard has eight tabs:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ dependencies = [
|
|||
"pandas>=2.0",
|
||||
"dash>=2.17",
|
||||
"plotly[express]>=5.22",
|
||||
"gunicorn>=26.2.0",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ def scrape() -> None:
|
|||
def dashboard(
|
||||
host: Annotated[str, typer.Option(help="Host to bind to (0.0.0.0 for network access)")] = "127.0.0.1",
|
||||
port: Annotated[int, typer.Option(help="Port to serve on")] = 8050,
|
||||
debug: Annotated[bool, typer.Option(help="Enable Dash debug mode")] = True,
|
||||
debug: Annotated[bool, typer.Option(help="Enable Dash debug mode")] = False,
|
||||
) -> None:
|
||||
"""Launch the analytics dashboard."""
|
||||
from admin_analytics.dashboard.app import create_app
|
||||
|
|
|
|||
8
src/admin_analytics/dashboard/wsgi.py
Normal file
8
src/admin_analytics/dashboard/wsgi.py
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
"""WSGI entry point for production servers, e.g.:
|
||||
|
||||
uv run gunicorn admin_analytics.dashboard.wsgi:server
|
||||
"""
|
||||
|
||||
from admin_analytics.dashboard.app import create_app
|
||||
|
||||
server = create_app().server
|
||||
11
uv.lock
generated
11
uv.lock
generated
|
|
@ -18,6 +18,7 @@ dependencies = [
|
|||
{ name = "beautifulsoup4" },
|
||||
{ name = "dash" },
|
||||
{ name = "duckdb" },
|
||||
{ name = "gunicorn" },
|
||||
{ name = "httpx" },
|
||||
{ name = "lxml" },
|
||||
{ name = "openpyxl" },
|
||||
|
|
@ -41,6 +42,7 @@ requires-dist = [
|
|||
{ name = "beautifulsoup4", specifier = ">=4.12" },
|
||||
{ name = "dash", specifier = ">=2.17" },
|
||||
{ name = "duckdb", specifier = ">=1.0" },
|
||||
{ name = "gunicorn", specifier = ">=26.2.0" },
|
||||
{ name = "httpx", specifier = ">=0.27" },
|
||||
{ name = "lxml", specifier = ">=5.0" },
|
||||
{ name = "openpyxl", specifier = ">=3.1" },
|
||||
|
|
@ -356,6 +358,15 @@ wheels = [
|
|||
{ url = "https://files.pythonhosted.org/packages/29/4b/45d90626aef8e65336bed690106d1382f7a43665e2249017e9527df8823b/greenlet-3.3.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c04c5e06ec3e022cbfe2cd4a846e1d4e50087444f875ff6d2c2ad8445495cf1a", size = 237086, upload-time = "2026-02-20T20:20:45.786Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gunicorn"
|
||||
version = "26.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d9/8a/e4ef6ee11701b6cd64702848415ffb69eeff85cb388a3c6c7fe86f22f3f8/gunicorn-26.2.0.tar.gz", hash = "sha256:62b864895d9ebff0b2f9867ba04fe811c93121596540830c9c916d0769668447", size = 787921, upload-time = "2026-08-24T15:05:59.3Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/85/7522a52e5e2f42faf1a129113ab63e548c42e103e9af395b7bfe65e403e2/gunicorn-26.2.0-py3-none-any.whl", hash = "sha256:bd249d0b3f7972f7432f0a6b6ff3b3ee2d129f70cd1ff6c09a9dd9e29a2b88e3", size = 228389, upload-time = "2026-08-24T15:05:57.67Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.16.0"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue