broker-sync/broker_sync/cli.py

60 lines
1.7 KiB
Python
Raw Normal View History

from __future__ import annotations
import os
import sys
import typer
app = typer.Typer(help="broker-sync: pull brokerage activity into Wealthfolio")
@app.command("version")
def version() -> None:
"""Print version and exit — used by the no-op Phase 0 CronJob as a liveness check."""
from broker_sync import __version__
typer.echo(f"broker-sync {__version__}")
@app.command("auth-spike")
def auth_spike(
wf_base_url: str = typer.Option(..., envvar="WF_BASE_URL", help="Wealthfolio base URL"),
wf_username: str = typer.Option(..., envvar="WF_USERNAME"),
wf_password: str = typer.Option(..., envvar="WF_PASSWORD"),
session_path: str = typer.Option("/data/wealthfolio_session.json", envvar="WF_SESSION_PATH"),
) -> None:
"""Phase 0.5 — prove end-to-end auth + 1 activity import against live Wealthfolio."""
import asyncio
from broker_sync.sinks.wealthfolio import WealthfolioSink
async def _run() -> None:
sink = WealthfolioSink(
base_url=wf_base_url,
username=wf_username,
password=wf_password,
session_path=session_path,
)
try:
await sink.login()
accounts = await sink.list_accounts()
typer.echo(f"Logged in. {len(accounts)} account(s) visible.")
finally:
await sink.close()
try:
asyncio.run(_run())
except Exception as e:
typer.echo(f"auth-spike failed: {e}", err=True)
sys.exit(1)
def main() -> None:
# Entry point called by the console-script in pyproject.toml.
app()
if __name__ == "__main__":
# Guard env for readability when running under `python -m broker_sync.cli`.
os.environ.setdefault("COLUMNS", "120")
main()