Model/applications/abri/handler.py
2026-07-07 14:40:33 +00:00

59 lines
2.5 KiB
Python

"""Lambda entry point for the Abri OpenHousing flows.
Consumes the abri SQS queue (one trigger message per scrape, sent by the
HubSpot scraper) and dispatches the fired flows through the AbriOrchestrator.
Env-to-clients glue only; behaviour lives behind the dispatch seam.
"""
import os
from typing import Any, Dict
from hubspot.client import Client # type: ignore[reportMissingTypeStubs]
from sqlalchemy.pool import NullPool
from sqlmodel import Session
from applications.abri.abri_trigger_request import AbriTriggerRequest
from applications.abri.dispatch import dispatch_abri_flows
from domain.tasks.tasks import Source
from infrastructure.abri.abri_client import AbriClient
from infrastructure.abri.config import AbriConfig
from infrastructure.hubspot.deal_contacts_client import HubspotDealContactsClient
from infrastructure.hubspot.deal_properties_client import HubspotDealPropertiesClient
from infrastructure.postgres.config import PostgresConfig
from infrastructure.postgres.engine import make_engine
from orchestration.abri_orchestrator import AbriOrchestrator
from repositories.hubspot_deals.deal_database_postgres_gateway import (
DealDatabasePostgresGateway,
)
from utilities.aws_lambda.task_handler import task_handler
from utilities.logger import setup_logger
logger = setup_logger()
@task_handler(task_source="abri_api", source=Source.HUBSPOT_DEAL)
def handler(body: dict[str, Any], context: Any) -> Dict[str, str]:
request = AbriTriggerRequest.model_validate(body)
abri_client = AbriClient(config=AbriConfig.from_env(os.environ))
sdk_client: Client = Client.create( # type: ignore[reportUnknownMemberType]
access_token=os.environ["HUBSPOT_API_KEY"]
)
# NullPool: a fresh engine per invocation, so pooling would only
# accumulate idle connections across warm Lambda containers.
engine = make_engine(PostgresConfig.from_env(dict(os.environ)), poolclass=NullPool)
with Session(engine) as session:
deal_database = DealDatabasePostgresGateway(session=session)
orchestrator = AbriOrchestrator(
abri_client=abri_client,
deal_contacts=HubspotDealContactsClient(sdk_client=sdk_client),
deal_properties=HubspotDealPropertiesClient(sdk_client=sdk_client),
deal_database=deal_database,
)
summary = dispatch_abri_flows(request, orchestrator, deal_database)
logger.info(
"Abri flows completed for deal %s: %s", request.hubspot_deal_id, summary
)
return summary