#!/usr/bin/env python3 # ----------------------------------------------------------------------------- # Home-Ka — US real-estate aggregator (Groupe KA) # Author: Simon-Pierre Boucher — contact@spboucher.ai # run.py : entry point — sync, watch, serve, discovery, brokerage seed # ----------------------------------------------------------------------------- """Usage: python run.py sync [source ...] # sync listings from all/selected sources python run.py watch [minutes] # sync loop (default 60 min) python run.py serve [port] # start the API + frontend (default 8099) python run.py list # list registered connectors & sources python run.py seed [file] # load data/brokerages_seed.json python run.py discover [n] # inspect the next n brokerages (default 25) python run.py rescore # recompute brokerage priority scores python run.py geocode [n] # geocode listings without coordinates python run.py quality # re-run the quality gate python run.py dedup # re-run the dedup pass """ from __future__ import annotations import os import sys from pathlib import Path # Load .env (feed credentials, SCRAPFLY_KEY, HOMEKA_ADMIN_TOKEN...) without # any external dependency _env = Path(__file__).parent / ".env" if _env.exists(): for line in _env.read_text().splitlines(): line = line.strip() if line and not line.startswith("#") and "=" in line: k, _, v = line.partition("=") os.environ.setdefault(k.strip(), v.strip()) def main() -> None: cmd = sys.argv[1] if len(sys.argv) > 1 else "serve" if cmd == "sync": from homeka import ingest ingest.run(sys.argv[2:] or None) elif cmd == "watch": from homeka import ingest minutes = int(sys.argv[2]) if len(sys.argv) > 2 else 60 ingest.watch(minutes * 60) elif cmd == "list": from homeka import db from homeka.connectors import CUSTOM, FAMILIES print("families:", ", ".join(sorted(FAMILIES))) for sid in sorted(CUSTOM): print(f"custom {sid}") con = db.connect() for s in db.get_sources(con): flag = "on " if s["enabled"] else "off" print(f"source [{flag}] {s['id']:28s} type={s['connector_type']}") con.close() elif cmd == "seed": from homeka import brokerages res = brokerages.load_seed(sys.argv[2] if len(sys.argv) > 2 else None) print(f"[home-ka] brokerage seed: {res}") elif cmd == "discover": from homeka import discovery n = int(sys.argv[2]) if len(sys.argv) > 2 else 25 print(discovery.run_batch(limit=n)) elif cmd == "rescore": from homeka import brokerages print(f"[home-ka] rescored {brokerages.rescore()} brokerage(s)") elif cmd == "geocode": from homeka import geocode print(geocode.run_batch(int(sys.argv[2]) if len(sys.argv) > 2 else None)) elif cmd == "quality": from homeka import db, quality con = db.connect() print(quality.refresh(con)) con.close() elif cmd == "dedup": from homeka import db con = db.connect() print(f"[home-ka] dedup: {db.refresh_dedup(con)} hidden") con.close() elif cmd == "serve": import uvicorn port = int(sys.argv[2]) if len(sys.argv) > 2 else 8099 uvicorn.run("homeka.web:app", host="0.0.0.0", port=port) else: print(__doc__) sys.exit(1) if __name__ == "__main__": main()