SPB Git forge

spb/home-ka

Public
10commits 1branches 0releases
793.0 KBsize
maindefault branch
20 days agolast push
Python 49.6% TypeScript 25.5% CSS 24.1%
2.4 KB · 68 lines python
Raw Blame History
1# -----------------------------------------------------------------------------2# Home-Ka — US real-estate aggregator (Groupe KA)3# Author: Simon-Pierre Boucher — contact@spboucher.ai4# connectors/__init__.py : AUTO-DISCOVERING connector registry (recursive).5#6# Same principle as immo-ka, extended with connector FAMILIES:7#   - FAMILIES:  {"reso": RESOConnector, "xml": XMLFeedConnector, ...}8#     generic config-driven classes (class attribute `family`), instantiated9#     per source from the `sources` table — a new source of a known family10#     is a DB row, zero code.11#   - CUSTOM:    {"acme_realty": AcmeRealtyConnector, ...}12#     one-site classes (class attribute `source_id`), like immo-ka.13# Every module under this package (subpackages included) is imported; a broken14# connector never blocks the others.15# -----------------------------------------------------------------------------16from __future__ import annotations1718import importlib19import pkgutil20import sys2122from .base import BaseConnector2324FAMILIES: dict[str, type[BaseConnector]] = {}25CUSTOM: dict[str, type[BaseConnector]] = {}262728def _register(module) -> None:29    for obj in vars(module).values():30        if not (isinstance(obj, type) and issubclass(obj, BaseConnector)31                and obj is not BaseConnector):32            continue33        fam = getattr(obj, "family", "")34        sid = getattr(obj, "source_id", "")35        if fam and obj.__dict__.get("family"):36            FAMILIES[fam] = obj37        if sid and obj.__dict__.get("source_id"):38            CUSTOM[sid] = obj394041def _walk(package_name: str, path) -> None:42    for mod in pkgutil.iter_modules(path):43        if mod.name in ("base", "__init__"):44            continue45        full = f"{package_name}.{mod.name}"46        try:47            module = importlib.import_module(full)48        except Exception as exc:   # a broken connector never blocks the others49            print(f"[home-ka] connector '{full}' skipped: {exc}", file=sys.stderr)50            continue51        _register(module)52        if mod.ispkg:53            _walk(full, module.__path__)545556_walk(__name__, __path__)575859def build(source_id: str, connector_type: str,60          config: dict | None = None) -> BaseConnector | None:61    """Instantiate the connector for a `sources` row (or a custom class)."""62    if source_id in CUSTOM:63        return CUSTOM[source_id]()64    cls = FAMILIES.get(connector_type)65    if cls is None:66        return None67    return cls(source_id, config or {})68