mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Merge pull request #1072 from Hestia-Homes/feature/magicplan-trigger
Magicplan: corrections to trigger and handler
This commit is contained in:
commit
adecfda28f
7 changed files with 74 additions and 24 deletions
|
|
@ -20,7 +20,9 @@ def handler(body: dict[str, Any], context: Any) -> str:
|
||||||
api_key=settings.MAGICPLAN_API_KEY,
|
api_key=settings.MAGICPLAN_API_KEY,
|
||||||
)
|
)
|
||||||
# TODO: read s3_bucket from env var so staging/prod use the correct bucket
|
# TODO: read s3_bucket from env var so staging/prod use the correct bucket
|
||||||
plan: Plan = MagicPlanService(client, s3_bucket="retrofit-energy-assessments-dev").run(payload)
|
plan: Plan = MagicPlanService(
|
||||||
|
client, s3_bucket="retrofit-energy-assessments-dev"
|
||||||
|
).run(payload)
|
||||||
logger.info("Saved MagicPlan plan uid=%s", plan.uid)
|
logger.info("Saved MagicPlan plan uid=%s", plan.uid)
|
||||||
return plan.uid
|
return plan.uid
|
||||||
|
|
||||||
|
|
@ -30,7 +32,6 @@ if __name__ == "__main__":
|
||||||
"Records": [
|
"Records": [
|
||||||
{
|
{
|
||||||
"body": '{"address": "2 Laburnum Way Bromley BR2 8BZ", "hubspot_deal_id": "local-test-deal"}',
|
"body": '{"address": "2 Laburnum Way Bromley BR2 8BZ", "hubspot_deal_id": "local-test-deal"}',
|
||||||
"messageId": "local-test",
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,7 @@ sqlmodel
|
||||||
psycopg2-binary==2.9.10
|
psycopg2-binary==2.9.10
|
||||||
pydantic-settings==2.6.0
|
pydantic-settings==2.6.0
|
||||||
boto3==1.35.44
|
boto3==1.35.44
|
||||||
|
|
||||||
|
pytz==2024.2
|
||||||
|
pandas==2.2.2
|
||||||
|
numpy==2.1.2
|
||||||
|
|
|
||||||
11
backend/magic_plan/local_handler/docker-compose.yml
Normal file
11
backend/magic_plan/local_handler/docker-compose.yml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
version: "3.9"
|
||||||
|
|
||||||
|
services:
|
||||||
|
ecmk-fetcher-lambda:
|
||||||
|
build:
|
||||||
|
context: ../../../
|
||||||
|
dockerfile: backend/magic_plan/handler/Dockerfile
|
||||||
|
ports:
|
||||||
|
- "9000:8080"
|
||||||
|
env_file:
|
||||||
|
- ../../../.env
|
||||||
29
backend/magic_plan/local_handler/invoke_local_lambda.py
Normal file
29
backend/magic_plan/local_handler/invoke_local_lambda.py
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
|
||||||
|
HOST = "localhost"
|
||||||
|
PORT = "9000"
|
||||||
|
|
||||||
|
LAMBDA_URL = f"http://{HOST}:{PORT}/2015-03-31/functions/function/invocations"
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"Records": [
|
||||||
|
{
|
||||||
|
"messageId": "test-message-id",
|
||||||
|
"body": json.dumps(
|
||||||
|
# {
|
||||||
|
# "address": "2 Laburnum Way, Rombley, BR2 8BZ | Retrofit Assessment",
|
||||||
|
# "hubspot_deal_id": "500262906061",
|
||||||
|
# }
|
||||||
|
{"address": "33 Wallaby Way, Sydney", "hubspot_deal_id": "123456789"}
|
||||||
|
),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(LAMBDA_URL, json=payload)
|
||||||
|
|
||||||
|
print("Status code:", response.status_code)
|
||||||
|
print("Response:")
|
||||||
|
print(response.text)
|
||||||
|
|
@ -7,12 +7,11 @@ _BASE_URL = "https://cloud.magicplan.app/api/v2"
|
||||||
|
|
||||||
class MagicPlanClient:
|
class MagicPlanClient:
|
||||||
def __init__(self, customer_id: str, api_key: str) -> None:
|
def __init__(self, customer_id: str, api_key: str) -> None:
|
||||||
self._api_key = api_key
|
|
||||||
self._session = requests.Session()
|
self._session = requests.Session()
|
||||||
self._session.headers.update({"customer": customer_id})
|
self._session.headers.update({"customer": customer_id, "key": api_key})
|
||||||
|
|
||||||
def get_plans(self) -> PlansListResponse:
|
def get_plans(self) -> PlansListResponse:
|
||||||
r = self._session.get(f"{_BASE_URL}/plans", params={"key": self._api_key})
|
r = self._session.get(f"{_BASE_URL}/plans")
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
return PlansListResponse.model_validate(r.json()["data"])
|
return PlansListResponse.model_validate(r.json()["data"])
|
||||||
|
|
||||||
|
|
@ -23,8 +22,6 @@ class MagicPlanClient:
|
||||||
return self._fetch_plan(plan_id).content
|
return self._fetch_plan(plan_id).content
|
||||||
|
|
||||||
def _fetch_plan(self, plan_id: str) -> requests.Response:
|
def _fetch_plan(self, plan_id: str) -> requests.Response:
|
||||||
r = self._session.get(
|
r = self._session.get(f"{_BASE_URL}/plans/{plan_id}")
|
||||||
f"{_BASE_URL}/plans/{plan_id}", params={"key": self._api_key}
|
|
||||||
)
|
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
return r
|
return r
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ def test_handler_raises_on_missing_address(mock_plan: MagicMock) -> None:
|
||||||
|
|
||||||
def test_handler_constructs_client_from_settings(mock_service: MagicMock) -> None:
|
def test_handler_constructs_client_from_settings(mock_service: MagicMock) -> None:
|
||||||
# Arrange
|
# Arrange
|
||||||
body = {"address": ADDRESS}
|
body = {"address": ADDRESS, "hubspot_deal_id": "deal-123"}
|
||||||
with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings(customer_id="cust-xyz", api_key="key-xyz")), \
|
with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings(customer_id="cust-xyz", api_key="key-xyz")), \
|
||||||
patch("backend.magic_plan.handler.MagicPlanClient") as MockClient, \
|
patch("backend.magic_plan.handler.MagicPlanClient") as MockClient, \
|
||||||
patch("backend.magic_plan.handler.MagicPlanService", return_value=mock_service):
|
patch("backend.magic_plan.handler.MagicPlanService", return_value=mock_service):
|
||||||
|
|
@ -69,31 +69,37 @@ def test_handler_constructs_client_from_settings(mock_service: MagicMock) -> Non
|
||||||
|
|
||||||
def test_handler_calls_service_run_with_address(mock_service: MagicMock) -> None:
|
def test_handler_calls_service_run_with_address(mock_service: MagicMock) -> None:
|
||||||
# Arrange
|
# Arrange
|
||||||
body = {"address": ADDRESS}
|
body = {"address": ADDRESS, "hubspot_deal_id": "deal-123"}
|
||||||
with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings()), \
|
with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings()), \
|
||||||
patch("backend.magic_plan.handler.MagicPlanClient"), \
|
patch("backend.magic_plan.handler.MagicPlanClient"), \
|
||||||
patch("backend.magic_plan.handler.MagicPlanService", return_value=mock_service):
|
patch("backend.magic_plan.handler.MagicPlanService", return_value=mock_service):
|
||||||
# Act
|
# Act
|
||||||
_call_handler(body)
|
_call_handler(body)
|
||||||
# Assert
|
# Assert
|
||||||
mock_service.run.assert_called_once_with(ADDRESS, None)
|
mock_service.run.assert_called_once()
|
||||||
|
request = mock_service.run.call_args.args[0]
|
||||||
|
assert request.address == ADDRESS
|
||||||
|
assert request.uprn is None
|
||||||
|
|
||||||
|
|
||||||
def test_handler_passes_uprn_to_service(mock_service: MagicMock) -> None:
|
def test_handler_passes_uprn_to_service(mock_service: MagicMock) -> None:
|
||||||
# Arrange
|
# Arrange
|
||||||
body = {"address": ADDRESS, "uprn": "100023336956"}
|
body = {"address": ADDRESS, "uprn": "100023336956", "hubspot_deal_id": "deal-123"}
|
||||||
with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings()), \
|
with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings()), \
|
||||||
patch("backend.magic_plan.handler.MagicPlanClient"), \
|
patch("backend.magic_plan.handler.MagicPlanClient"), \
|
||||||
patch("backend.magic_plan.handler.MagicPlanService", return_value=mock_service):
|
patch("backend.magic_plan.handler.MagicPlanService", return_value=mock_service):
|
||||||
# Act
|
# Act
|
||||||
_call_handler(body)
|
_call_handler(body)
|
||||||
# Assert
|
# Assert
|
||||||
mock_service.run.assert_called_once_with(ADDRESS, "100023336956")
|
mock_service.run.assert_called_once()
|
||||||
|
request = mock_service.run.call_args.args[0]
|
||||||
|
assert request.address == ADDRESS
|
||||||
|
assert request.uprn == "100023336956"
|
||||||
|
|
||||||
|
|
||||||
def test_handler_returns_plan_uid(mock_service: MagicMock) -> None:
|
def test_handler_returns_plan_uid(mock_service: MagicMock) -> None:
|
||||||
# Arrange
|
# Arrange
|
||||||
body = {"address": ADDRESS}
|
body = {"address": ADDRESS, "hubspot_deal_id": "deal-123"}
|
||||||
with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings()), \
|
with patch("backend.magic_plan.handler.get_settings", return_value=_make_settings()), \
|
||||||
patch("backend.magic_plan.handler.MagicPlanClient"), \
|
patch("backend.magic_plan.handler.MagicPlanClient"), \
|
||||||
patch("backend.magic_plan.handler.MagicPlanService", return_value=mock_service):
|
patch("backend.magic_plan.handler.MagicPlanService", return_value=mock_service):
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ def _load_fixture(name: str) -> dict[str, Any]:
|
||||||
|
|
||||||
|
|
||||||
def _make_client(mock_session: MagicMock) -> MagicPlanClient:
|
def _make_client(mock_session: MagicMock) -> MagicPlanClient:
|
||||||
|
mock_session.headers = {}
|
||||||
with patch(
|
with patch(
|
||||||
"backend.magic_plan.magic_plan_client.requests.Session",
|
"backend.magic_plan.magic_plan_client.requests.Session",
|
||||||
return_value=mock_session,
|
return_value=mock_session,
|
||||||
|
|
@ -44,7 +45,14 @@ def test_customer_header_set_on_session(mock_session: MagicMock) -> None:
|
||||||
# Act
|
# Act
|
||||||
_make_client(mock_session)
|
_make_client(mock_session)
|
||||||
# Assert
|
# Assert
|
||||||
mock_session.headers.update.assert_called_once_with({"customer": CUSTOMER_ID})
|
assert mock_session.headers["customer"] == CUSTOMER_ID
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_key_header_set_on_session(mock_session: MagicMock) -> None:
|
||||||
|
# Act
|
||||||
|
_make_client(mock_session)
|
||||||
|
# Assert
|
||||||
|
assert mock_session.headers["key"] == API_KEY
|
||||||
|
|
||||||
|
|
||||||
# --- get_plans ---
|
# --- get_plans ---
|
||||||
|
|
@ -62,9 +70,7 @@ def test_get_plans_calls_correct_url(
|
||||||
# Act
|
# Act
|
||||||
client.get_plans()
|
client.get_plans()
|
||||||
# Assert
|
# Assert
|
||||||
mock_session.get.assert_called_once_with(
|
mock_session.get.assert_called_once_with(f"{BASE_URL}/plans")
|
||||||
f"{BASE_URL}/plans", params={"key": API_KEY}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_plans_calls_raise_for_status(
|
def test_get_plans_calls_raise_for_status(
|
||||||
|
|
@ -126,9 +132,7 @@ def test_get_plan_calls_correct_url(
|
||||||
# Act
|
# Act
|
||||||
client.get_plan(plan_id)
|
client.get_plan(plan_id)
|
||||||
# Assert
|
# Assert
|
||||||
mock_session.get.assert_called_once_with(
|
mock_session.get.assert_called_once_with(f"{BASE_URL}/plans/{plan_id}")
|
||||||
f"{BASE_URL}/plans/{plan_id}", params={"key": API_KEY}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_plan_calls_raise_for_status(
|
def test_get_plan_calls_raise_for_status(
|
||||||
|
|
@ -198,9 +202,7 @@ def test_get_plan_raw_calls_correct_url(
|
||||||
# Act
|
# Act
|
||||||
client.get_plan_raw(plan_id)
|
client.get_plan_raw(plan_id)
|
||||||
# Assert
|
# Assert
|
||||||
mock_session.get.assert_called_once_with(
|
mock_session.get.assert_called_once_with(f"{BASE_URL}/plans/{plan_id}")
|
||||||
f"{BASE_URL}/plans/{plan_id}", params={"key": API_KEY}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_plan_raw_calls_raise_for_status(
|
def test_get_plan_raw_calls_raise_for_status(
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue