Model/infrastructure/address2uprn_queue_client.py
Jun-te Kim 7b00a33cd2 infrastructure: typed S3/SQS clients (S3Client, CsvS3Client, SqsClient, Address2UprnQueueClient)
Slice 3/6 of the postcode_splitter refactor (Hestia-Homes/Model#1101).
Introduces a thin typed infrastructure layer wrapping boto3 for the AWS
side of the splitter. S3Client/SqsClient are bucket-/queue-bound byte
adapters; CsvS3Client subclasses S3Client to round-trip CSV row dicts
via the existing parse_s3_uri helper in utils/s3.py; Address2UprnQueueClient
subclasses SqsClient to publish the typed {task_id, sub_task_id, s3_uri}
fan-out body the downstream consumer expects. moto[s3,sqs] is pulled into
test.requirements.txt and the new tests/infrastructure/ suite exercises
each client against the moto backend (S3 round-trip, CSV round-trip,
SQS send + body inspection, typed publish + body inspection). pyright
--strict is clean on the new modules.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 17:12:21 +00:00

27 lines
734 B
Python

from uuid import UUID
from infrastructure.sqs_client import SqsClient
class Address2UprnQueueClient(SqsClient):
"""SQS client that publishes Address-to-UPRN fan-out messages.
The body shape is fixed by the downstream consumer:
``{"task_id": str, "sub_task_id": str, "s3_uri": str}``
"""
def publish(
self,
*,
parent_task_id: UUID,
child_subtask_id: UUID,
s3_uri: str,
) -> str:
"""Send a typed Address-to-UPRN message. Returns the SQS ``MessageId``."""
return self.send(
{
"task_id": str(parent_task_id),
"sub_task_id": str(child_subtask_id),
"s3_uri": s3_uri,
}
)