mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
SAL
This commit is contained in:
parent
cf14a4e3aa
commit
5b677dedbe
8 changed files with 149 additions and 0 deletions
34
applications/SAL/Dockerfile
Normal file
34
applications/SAL/Dockerfile
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
FROM public.ecr.aws/lambda/python:3.11
|
||||
|
||||
# Postgres host/port/database are baked into the image at build time from
|
||||
# the deploy workflow's --build-arg values (GitHub Actions DEV_DB_* secrets),
|
||||
# mirroring backend/postcode_splitter/handler/Dockerfile. They map onto the
|
||||
# POSTGRES_* names PostgresConfig.from_env reads. Username/password are NOT
|
||||
# baked in -- Terraform injects those as Lambda env vars from Secrets Manager.
|
||||
ARG DEV_DB_HOST
|
||||
ARG DEV_DB_PORT
|
||||
ARG DEV_DB_NAME
|
||||
|
||||
ENV POSTGRES_HOST=${DEV_DB_HOST}
|
||||
ENV POSTGRES_PORT=${DEV_DB_PORT}
|
||||
ENV POSTGRES_DATABASE=${DEV_DB_NAME}
|
||||
|
||||
WORKDIR /var/task
|
||||
|
||||
COPY applications/postcode_splitter/requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy the layered source the handler imports from. The new splitter pulls
|
||||
# only DDD-shaped packages — no pandas, no legacy backend/.
|
||||
COPY domain/ domain/
|
||||
COPY infrastructure/ infrastructure/
|
||||
COPY orchestration/ orchestration/
|
||||
COPY repositories/ repositories/
|
||||
COPY utilities/ utilities/
|
||||
COPY applications/ applications/
|
||||
|
||||
# Place the handler at the Lambda task root so the runtime can resolve
|
||||
# ``main.handler`` without an extra package prefix.
|
||||
COPY applications/landlord_description_overrides/handler.py /var/task/main.py
|
||||
|
||||
CMD ["main.handler"]
|
||||
46
applications/SAL/handler.py
Normal file
46
applications/SAL/handler.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
from typing import Any
|
||||
import boto3
|
||||
from orchestration.landlord_description_overrides_orchestrator import (
|
||||
SALOrchestrator,
|
||||
)
|
||||
from infrastructure.csv_s3_client import CsvS3Client
|
||||
from repositories.raw_address.raw_address_csv_s3_repository import (
|
||||
RawAddressCsvS3Repository,
|
||||
)
|
||||
from domain.addresses.raw_address import AddressList
|
||||
|
||||
|
||||
def handler(
|
||||
body: dict[str, Any],
|
||||
context: Any,
|
||||
) -> dict[str, list[str]]:
|
||||
|
||||
s3_uri = "s3://retrofit-data-dev/bulk_onboarding_inputs/hyde2 (1).csv"
|
||||
bucket = "retrofit-data-dev"
|
||||
|
||||
# boto3.client is overloaded per-service in the installed stubs; cast
|
||||
# to Any so the strict-mode checker treats it as opaque.
|
||||
boto3_client: Any = boto3.client # noqa
|
||||
boto_s3: Any = boto3_client("s3")
|
||||
|
||||
csv_client = CsvS3Client(boto_s3, bucket)
|
||||
raw_address_repo = RawAddressCsvS3Repository(csv_client, bucket)
|
||||
|
||||
orchestrator = SALOrchestrator(
|
||||
raw_address_repo=raw_address_repo,
|
||||
)
|
||||
|
||||
list_of_raw_address: AddressList = orchestrator.get_raw_addresses(
|
||||
input_s3_uri=s3_uri
|
||||
)
|
||||
|
||||
col_to_desc_map = orchestrator.get_col_to_description_mappings(
|
||||
list_of_raw_address=list_of_raw_address
|
||||
)
|
||||
|
||||
# Read csv of user input
|
||||
# get the column and unique variations of each description
|
||||
# { walls: "wall variation 1", "wall varition 2"}
|
||||
# Call chatgpt(input from landlord, our way of understanding the mapping) Retrun -> lanlordMapped
|
||||
|
||||
return {"hello world": ["hello world"]}
|
||||
5
applications/SAL/local_handler/.env.local.example
Normal file
5
applications/SAL/local_handler/.env.local.example
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
POSTGRES_HOST=
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_USERNAME=
|
||||
POSTGRES_PASSWORD=
|
||||
POSTGRES_DATABASE=
|
||||
9
applications/SAL/local_handler/docker-compose.yml
Normal file
9
applications/SAL/local_handler/docker-compose.yml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
services:
|
||||
landlord_overrides:
|
||||
build:
|
||||
context: ../../../
|
||||
dockerfile: applications/landlord_description_overrides/Dockerfile
|
||||
ports:
|
||||
- "9002:8080"
|
||||
env_file:
|
||||
- .env.local
|
||||
16
applications/SAL/local_handler/invoke_local_lambda.py
Executable file
16
applications/SAL/local_handler/invoke_local_lambda.py
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env python3
|
||||
import json
|
||||
import requests
|
||||
|
||||
HOST = "localhost"
|
||||
PORT = "9002"
|
||||
|
||||
LAMBDA_URL = f"http://{HOST}:{PORT}/2015-03-31/functions/function/invocations"
|
||||
|
||||
payload = {"Records": [{"body": json.dumps({})}]}
|
||||
|
||||
response = requests.post(LAMBDA_URL, json=payload)
|
||||
|
||||
print("Status code:", response.status_code)
|
||||
print("Response:")
|
||||
print(response.text)
|
||||
12
applications/SAL/local_handler/run_local.sh
Executable file
12
applications/SAL/local_handler/run_local.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
if [ ! -f .env.local ]; then
|
||||
cp .env.local.example .env.local
|
||||
echo "Created .env.local from the template — fill it in, then re-run." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker compose build --no-cache
|
||||
docker compose up --force-recreate
|
||||
4
applications/SAL/requirements.txt
Normal file
4
applications/SAL/requirements.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
boto3
|
||||
pydantic
|
||||
sqlmodel
|
||||
psycopg2-binary
|
||||
23
orchestration/sal_orchestrator.py
Normal file
23
orchestration/sal_orchestrator.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
from repositories.raw_address.raw_address_repository import RawAddressRepository
|
||||
from domain.addresses.raw_address import AddressList
|
||||
|
||||
|
||||
class SALOrchestrator:
|
||||
def __init__(self, raw_address_repo: RawAddressRepository) -> None:
|
||||
self._raw_address_repo = raw_address_repo
|
||||
|
||||
def get_raw_addresses(
|
||||
self,
|
||||
input_s3_uri: str,
|
||||
) -> AddressList:
|
||||
return self._raw_address_repo.load_batch(input_s3_uri)
|
||||
|
||||
def get_col_to_description_mappings(
|
||||
self, list_of_raw_address: AddressList
|
||||
) -> dict[str, set[str]]:
|
||||
mappings: dict[str, set[str]] = {}
|
||||
for raw_address in list_of_raw_address:
|
||||
for key, value in raw_address.additional_info.items():
|
||||
# Lower-case so case-only typos collapse to one variant.
|
||||
mappings.setdefault(key, set()).add(value.lower())
|
||||
return mappings
|
||||
Loading…
Add table
Reference in a new issue