Initial commit
This commit is contained in:
commit
5f2db08b43
100 files changed
+16985
No files matched your search
@@ -0,0 +1,84 @@
|
||||
"""`dashboard` CLI subcommand (spec §5, task t_b38e9af2).
|
||||
|
||||
Wires the dashboard server into the shared `scraper/cli.py` ADDITIVELY +
|
||||
DEFENSIVELY, mirroring parser/correlate/analyze (the guarded `register()`
|
||||
pattern): `cli.py` calls `register(sub)` inside a try/except and adds its
|
||||
handler without touching any sibling handler. The `dashboard` name does not
|
||||
collide.
|
||||
|
||||
This is the CLI/app entry point per the task contract. The server itself lives
|
||||
in `scraper/dashboard/server.py`; this module just parses flags and calls
|
||||
`server.serve(...)`.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from .. import relational
|
||||
from . import server as _server
|
||||
|
||||
log = logging.getLogger("scraper.dashboard_cli")
|
||||
|
||||
|
||||
def _already_registered(sub, name: str) -> bool:
|
||||
actions = getattr(sub, "_choices_actions", [])
|
||||
return any(getattr(a, "name", None) == name for a in actions)
|
||||
|
||||
|
||||
def register(sub) -> None:
|
||||
"""Register the `dashboard` subcommand (guarded — skip if a sibling owns it)."""
|
||||
if _already_registered(sub, "dashboard"):
|
||||
return
|
||||
pd = sub.add_parser(
|
||||
"dashboard",
|
||||
help="serve the legislative dashboard (API + static UI)",
|
||||
description=("Serve the legislative dashboard. Reads the relational DB "
|
||||
"(bills/committees/members + bill_tags) and serves the "
|
||||
"API_CONTRACT.md endpoints + the static frontend."),
|
||||
)
|
||||
pd.add_argument("--host", default="127.0.0.1",
|
||||
help="bind host (default 127.0.0.1)")
|
||||
pd.add_argument("--port", type=int, default=8000,
|
||||
help="bind port (default 8000)")
|
||||
pd.add_argument("--db", default=relational.DEFAULT_DB,
|
||||
help="SQLite path (default db/daily_file.sqlite)")
|
||||
pd.add_argument("--prefs", default="out/prefs.json",
|
||||
help="preferences JSON file (default out/prefs.json)")
|
||||
pd.add_argument("--auth", default="out/auth.json",
|
||||
help="local-auth JSON file (default out/auth.json)")
|
||||
pd.add_argument("--no-static", dest="static", action="store_false",
|
||||
help="API only, no static frontend")
|
||||
pd.add_argument("--log", action="store_true",
|
||||
help="log HTTP requests to stderr")
|
||||
pd.set_defaults(func=handle_dashboard)
|
||||
|
||||
|
||||
def handle_dashboard(args) -> int:
|
||||
"""CLI handler for the `dashboard` subcommand."""
|
||||
return _server.serve(
|
||||
host=args.host,
|
||||
port=args.port,
|
||||
db_path=args.db,
|
||||
prefs_path=args.prefs,
|
||||
auth_path=args.auth,
|
||||
serve_static=getattr(args, "static", True),
|
||||
log_on=getattr(args, "log", False),
|
||||
)
|
||||
|
||||
|
||||
def main(argv=None) -> int:
|
||||
"""Direct invocation: `python -m scraper.dashboard_cli`."""
|
||||
import argparse
|
||||
p = argparse.ArgumentParser(
|
||||
prog="scraper.dashboard_cli",
|
||||
description="Serve the legislative dashboard.")
|
||||
sub = p.add_subparsers(dest="command", required=True)
|
||||
register(sub)
|
||||
args = p.parse_args(argv)
|
||||
return args.func(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user