""" Run audit_generator locally. Writes XLSX to ./local_output/ instead of S3. Usage: cd /workspaces/model python scripts/run_audit_generator_local.py """ from __future__ import annotations import os import sys from io import BytesIO from pathlib import Path from typing import Any # Load .env before importing infra modules from dotenv import load_dotenv load_dotenv(Path(__file__).parent.parent / "backend" / ".env") from infrastructure.postgres.config import PostgresConfig from infrastructure.postgres.engine import make_engine, make_session from orchestration.audit_generator_orchestrator import AuditGeneratorOrchestrator from orchestration.audit_generator_unit_of_work import AuditGeneratorUnitOfWork class _LocalS3Client: """Writes to local filesystem instead of S3.""" def __init__(self, output_dir: Path) -> None: self._output_dir = output_dir self._output_dir.mkdir(parents=True, exist_ok=True) @property def bucket(self) -> str: return "local" def get_object(self, key: str) -> bytes: raise NotImplementedError def put_object(self, key: str, body: bytes) -> str: dest = self._output_dir / Path(key).name dest.write_bytes(body) print(f"Saved: {dest}") return str(dest) def main() -> None: deal_id = sys.argv[1] if len(sys.argv) > 1 else input("hubspot_deal_id: ").strip() output_dir = Path(__file__).parent.parent / "local_output" engine = make_engine(PostgresConfig.from_env(os.environ)) def session_factory() -> Any: return make_session(engine) def uow_factory() -> AuditGeneratorUnitOfWork: return AuditGeneratorUnitOfWork(session_factory) AuditGeneratorOrchestrator( hubspot_deal_id=deal_id, s3_client=_LocalS3Client(output_dir), # type: ignore[arg-type] uow_factory=uow_factory, ).run() if __name__ == "__main__": main()