mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-19 17:03:02 +00:00
73 lines
2.3 KiB
Python
73 lines
2.3 KiB
Python
"""The Modelling Run Distributor: POST /v1/modelling/trigger-run (ADR-0055).
|
|
|
|
Accepts a portfolio-scoped modelling request expressed as filters, resolves
|
|
them to a concrete property set (ADR-0056), pre-creates one batch sub_task per
|
|
SQS message under the app-owned task, and fans the batches out to the
|
|
modelling_e2e workers. Never models synchronously; owns nothing after the
|
|
fan-out — progress and terminal state roll up from the workers.
|
|
"""
|
|
|
|
import json
|
|
from collections.abc import Callable, Iterator
|
|
from typing import Any, cast
|
|
|
|
import boto3
|
|
from fastapi import APIRouter, Depends
|
|
from sqlmodel import Session
|
|
|
|
from backend.app.config import get_settings
|
|
from backend.app.db.connection import db_engine
|
|
from backend.app.dependencies import validate_token
|
|
from backend.app.modelling.schemas import TriggerRunRequest
|
|
|
|
# Sends pre-serialised message bodies to the modelling_e2e queue. A seam so
|
|
# tests record bodies instead of calling AWS.
|
|
MessageSender = Callable[[list[str]], None]
|
|
|
|
|
|
def get_session() -> Iterator[Session]:
|
|
with Session(db_engine) as session:
|
|
yield session
|
|
|
|
|
|
def get_message_sender() -> MessageSender:
|
|
settings = get_settings()
|
|
client: Any = cast(
|
|
Any, boto3.client("sqs", settings.AWS_DEFAULT_REGION)
|
|
) # pyright: ignore[reportUnknownMemberType]
|
|
queue_url = settings.MODELLING_E2E_SQS_URL
|
|
|
|
def send(bodies: list[str]) -> None:
|
|
# send_message_batch caps at 10 entries per call — chunk accordingly.
|
|
for start in range(0, len(bodies), 10):
|
|
chunk = bodies[start : start + 10]
|
|
client.send_message_batch(
|
|
QueueUrl=queue_url,
|
|
Entries=[
|
|
{"Id": str(index), "MessageBody": body}
|
|
for index, body in enumerate(chunk)
|
|
],
|
|
)
|
|
|
|
return send
|
|
|
|
|
|
router = APIRouter(
|
|
prefix="/modelling",
|
|
tags=["modelling"],
|
|
dependencies=[Depends(validate_token)],
|
|
)
|
|
|
|
|
|
@router.post("/trigger-run", status_code=202)
|
|
async def trigger_run(
|
|
body: TriggerRunRequest,
|
|
session: Session = Depends(get_session),
|
|
send_messages: MessageSender = Depends(get_message_sender),
|
|
) -> dict[str, str]:
|
|
raise NotImplementedError
|
|
|
|
|
|
# json is used by the implementation; referenced here so the stub imports are
|
|
# stable for the first RED.
|
|
_ = json
|