mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Merge pull request #1166 from Hestia-Homes/main
Pashub fetcher dynamically instantiates sharepoint client based on received sharepoint site
This commit is contained in:
commit
d65d7dcf51
11 changed files with 63 additions and 9 deletions
4
.github/workflows/_deploy_lambda.yml
vendored
4
.github/workflows/_deploy_lambda.yml
vendored
|
|
@ -76,6 +76,8 @@ on:
|
|||
required: false
|
||||
TF_VAR_social_housing_wave_3_sharepoint_id:
|
||||
required: false
|
||||
TF_VAR_eco_sharepoint_id:
|
||||
required: false
|
||||
TF_VAR_pashub_email:
|
||||
required: false
|
||||
TF_VAR_pashub_password:
|
||||
|
|
@ -159,6 +161,7 @@ jobs:
|
|||
TF_VAR_osmosis_acd_sharepoint_id: ${{ secrets.TF_VAR_osmosis_acd_sharepoint_id }}
|
||||
TF_VAR_private_pay_sharepoint_id: ${{ secrets.TF_VAR_private_pay_sharepoint_id }}
|
||||
TF_VAR_social_housing_wave_3_sharepoint_id: ${{ secrets.TF_VAR_social_housing_wave_3_sharepoint_id }}
|
||||
TF_VAR_eco_sharepoint_id: ${{ secrets.TF_VAR_eco_sharepoint_id }}
|
||||
TF_VAR_pashub_email: ${{ secrets.TF_VAR_pashub_email }}
|
||||
TF_VAR_pashub_password: ${{ secrets.TF_VAR_pashub_password }}
|
||||
TF_VAR_pashub_coordination_email: ${{ secrets.TF_VAR_pashub_coordination_email }}
|
||||
|
|
@ -210,6 +213,7 @@ jobs:
|
|||
TF_VAR_osmosis_acd_sharepoint_id: ${{ secrets.TF_VAR_osmosis_acd_sharepoint_id }}
|
||||
TF_VAR_private_pay_sharepoint_id: ${{ secrets.TF_VAR_private_pay_sharepoint_id }}
|
||||
TF_VAR_social_housing_wave_3_sharepoint_id: ${{ secrets.TF_VAR_social_housing_wave_3_sharepoint_id }}
|
||||
TF_VAR_eco_sharepoint_id: ${{ secrets.TF_VAR_eco_sharepoint_id }}
|
||||
TF_VAR_pashub_email: ${{ secrets.TF_VAR_pashub_email }}
|
||||
TF_VAR_pashub_password: ${{ secrets.TF_VAR_pashub_password }}
|
||||
TF_VAR_pashub_coordination_email: ${{ secrets.TF_VAR_pashub_coordination_email }}
|
||||
|
|
|
|||
1
.github/workflows/deploy_terraform.yml
vendored
1
.github/workflows/deploy_terraform.yml
vendored
|
|
@ -448,6 +448,7 @@ jobs:
|
|||
TF_VAR_osmosis_acd_sharepoint_id: ${{ secrets.OSMOSIS_ACD_SHAREPOINT_ID }}
|
||||
TF_VAR_private_pay_sharepoint_id: ${{ secrets.PRIVATE_PAY_SHAREPOINT_ID }}
|
||||
TF_VAR_social_housing_wave_3_sharepoint_id: ${{ secrets.SOCIAL_HOUSING_WAVE_3_SHAREPOINT_ID }}
|
||||
TF_VAR_eco_sharepoint_id: ${{ secrets.TF_VAR_eco_sharepoint_id }}
|
||||
TF_VAR_pashub_email: ${{ secrets.PASHUB_EMAIL }}
|
||||
TF_VAR_pashub_password: ${{ secrets.PASHUB_PASSWORD }}
|
||||
TF_VAR_pashub_coordination_email: ${{ secrets.PASHUB_COORDINATION_EMAIL }}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ class Settings(BaseSettings):
|
|||
OSMOSIS_ACD_SHAREPOINT_ID: Optional[str] = None
|
||||
PRIVATE_PAY_SHAREPOINT_ID: Optional[str] = None
|
||||
SOCIAL_HOUSING_WAVE_3_SHAREPOINT_ID: Optional[str] = None
|
||||
ECO_SHAREPOINT_ID: Optional[str] = None
|
||||
OPENAI_API_KEY: Optional[str] = None
|
||||
|
||||
# Pas Hub
|
||||
|
|
|
|||
|
|
@ -40,10 +40,6 @@ def handler(body: Dict[str, Any], context: Any) -> List[str]:
|
|||
if (not pashub_email) or (not pashub_password):
|
||||
raise ValueError("Pas Hub credentials not provided")
|
||||
|
||||
sharepoint_client = DomnaSharepointClient(
|
||||
sharepoint_location=DomnaSites.SOCIAL_HOUSING_WAVE_3
|
||||
)
|
||||
|
||||
if coordination_hub_email and coordination_hub_password:
|
||||
_coord_email, _coord_password = (
|
||||
coordination_hub_email,
|
||||
|
|
@ -57,6 +53,16 @@ def handler(body: Dict[str, Any], context: Any) -> List[str]:
|
|||
payload = PashubToAraTriggerRequest.model_validate(body)
|
||||
logger.debug("Successfully validated request body")
|
||||
|
||||
sharepoint_client: Optional[DomnaSharepointClient] = None
|
||||
if payload.sharepoint_site is not None:
|
||||
try:
|
||||
resolved_site = DomnaSites[payload.sharepoint_site]
|
||||
sharepoint_client = DomnaSharepointClient(sharepoint_location=resolved_site)
|
||||
except KeyError:
|
||||
logger.warning(
|
||||
f"Unrecognised sharepoint_site '{payload.sharepoint_site}'; skipping SharePoint upload"
|
||||
)
|
||||
|
||||
service = PashubService(
|
||||
pashub_client=get_pashub_client(pashub_email, pashub_password),
|
||||
sharepoint_client=sharepoint_client,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class PashubService:
|
|||
def __init__(
|
||||
self,
|
||||
pashub_client: PashubClient,
|
||||
sharepoint_client: DomnaSharepointClient,
|
||||
sharepoint_client: Optional[DomnaSharepointClient],
|
||||
s3_bucket: str,
|
||||
coordination_client_factory: Optional[Callable[[], PashubClient]] = None,
|
||||
) -> None:
|
||||
|
|
@ -111,7 +111,7 @@ class PashubService:
|
|||
default_file_type=FileTypeEnum.OTHER.value,
|
||||
)
|
||||
|
||||
if request.sharepoint_link and request.address:
|
||||
if self._sharepoint_client and request.sharepoint_link and request.address:
|
||||
folder_name = request.address.split("|")[0].strip()
|
||||
folders = self._sharepoint_client.get_folders_in_path(request.sharepoint_link)
|
||||
match = next(
|
||||
|
|
@ -207,6 +207,7 @@ class PashubService:
|
|||
property_folder_path: str,
|
||||
files: List[DownloadedFile],
|
||||
) -> None:
|
||||
assert self._sharepoint_client is not None
|
||||
for df in files:
|
||||
filename = os.path.basename(df.file_path)
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ class PashubToAraTriggerRequest(BaseModel):
|
|||
hubspot_listing_id: Optional[int] = None
|
||||
hubspot_deal_id: Optional[str] = None
|
||||
|
||||
sharepoint_site: Optional[str] = None
|
||||
|
||||
get_other_files: bool = False
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -616,6 +616,33 @@ def test_sharepoint_skips_upload_when_folder_not_found() -> None:
|
|||
mock_logger.warning.assert_called()
|
||||
|
||||
|
||||
def test_sharepoint_skips_upload_when_sharepoint_client_is_none() -> None:
|
||||
# Arrange
|
||||
mock_client = MagicMock(spec=PashubClient)
|
||||
mock_client.get_uprn_by_job_id.return_value = None
|
||||
mock_client.get_evidence_files_by_job_id.return_value = make_downloaded(
|
||||
core=["/tmp/core.pdf"]
|
||||
)
|
||||
|
||||
service = PashubService(
|
||||
pashub_client=mock_client,
|
||||
sharepoint_client=None,
|
||||
s3_bucket="test-bucket",
|
||||
)
|
||||
|
||||
# Act — should not raise AttributeError on None._sharepoint_client
|
||||
with patch("backend.pashub_fetcher.pashub_service.os.remove"):
|
||||
result = service.run(
|
||||
make_request(
|
||||
sharepoint_link="Retrofit/Properties",
|
||||
address="123 Main St | deal",
|
||||
)
|
||||
)
|
||||
|
||||
# Assert
|
||||
assert result == ["/tmp/core.pdf"]
|
||||
|
||||
|
||||
def test_run_warns_and_continues_when_site_notes_parsing_fails() -> None:
|
||||
mock_client = MagicMock(spec=PashubClient)
|
||||
mock_client.get_uprn_by_job_id.return_value = None
|
||||
|
|
|
|||
|
|
@ -52,12 +52,16 @@ EXCEL_PATH: str = os.path.join(
|
|||
"local_run_02-06-2026/ECO_Approach_Coordination_Design_KN.xlsx",
|
||||
)
|
||||
|
||||
SHAREPOINT_PROPERTIES_FOLDER: str = ""
|
||||
SHAREPOINT_PROPERTIES_FOLDER: str = (
|
||||
"Housing Associations/- Client Shared Folders/Abri/Abri Property Folders (Full PAS Info)"
|
||||
)
|
||||
|
||||
SHAREPOINT_SITE: str = "ECO"
|
||||
|
||||
|
||||
def _build_requests(excel_path: str) -> list[PashubToAraTriggerRequest]:
|
||||
wb = load_workbook(excel_path, data_only=True)
|
||||
ws = wb.worksheets[0]
|
||||
ws = wb.worksheets[1]
|
||||
|
||||
headers: dict[str, int] = {}
|
||||
for col in range(1, ws.max_column + 1):
|
||||
|
|
@ -102,6 +106,7 @@ def _build_requests(excel_path: str) -> list[PashubToAraTriggerRequest]:
|
|||
address=address,
|
||||
deal_stage=deal_stage,
|
||||
sharepoint_link=SHAREPOINT_PROPERTIES_FOLDER or None,
|
||||
sharepoint_site=SHAREPOINT_SITE,
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -123,7 +128,7 @@ def main() -> None:
|
|||
for request in trigger_requests:
|
||||
action: str = "DRY RUN" if DRY_RUN else "SENDING"
|
||||
logger.info(
|
||||
f"[{action}] deal_id={request.hubspot_deal_id} pashub_link={request.pashub_link}"
|
||||
f"[{action}] deal_id={request.hubspot_deal_id} pashub_link={request.pashub_link} sharepoint_link={request.sharepoint_link}"
|
||||
)
|
||||
|
||||
if not DRY_RUN:
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ module "lambda" {
|
|||
OSMOSIS_ACD_SHAREPOINT_ID = var.osmosis_acd_sharepoint_id
|
||||
PRIVATE_PAY_SHAREPOINT_ID = var.private_pay_sharepoint_id
|
||||
SOCIAL_HOUSING_WAVE_3_SHAREPOINT_ID = var.social_housing_wave_3_sharepoint_id
|
||||
ECO_SHAREPOINT_ID = var.eco_sharepoint_id
|
||||
PASHUB_EMAIL = var.pashub_email
|
||||
PASHUB_PASSWORD = var.pashub_password
|
||||
PASHUB_COORDINATION_EMAIL = var.pashub_coordination_email
|
||||
|
|
|
|||
|
|
@ -92,6 +92,11 @@ variable "social_housing_wave_3_sharepoint_id" {
|
|||
sensitive = true
|
||||
}
|
||||
|
||||
variable "eco_sharepoint_id" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "pashub_email" {
|
||||
type = string
|
||||
sensitive = true
|
||||
|
|
|
|||
|
|
@ -9,3 +9,4 @@ class DomnaSites(Enum):
|
|||
OSMOSIS_ACD = os.getenv("OSMOSIS_ACD_SHAREPOINT_ID")
|
||||
PRIVATE_PAY = os.getenv("PRIVATE_PAY_SHAREPOINT_ID")
|
||||
SOCIAL_HOUSING_WAVE_3 = os.getenv("SOCIAL_HOUSING_WAVE_3_SHAREPOINT_ID")
|
||||
ECO = os.getenv("ECO_SHAREPOINT_ID")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue