"""Lambda get-products-for-account.""" import json from typing import Any import boto3 import httpx from owsclient import M2MTokenManager, OwsClient from sentry_sdk import capture_message from src.config import ( ENVIRONMENT, LAMBDA_NAME, PAGE_LIMIT, S3_BUCKET, logger, secrets_manager_client, ) from src.ows_product import get_products_for_account ows_client = OwsClient( environment=ENVIRONMENT, service_name=LAMBDA_NAME, timeout=httpx.Timeout(30.0), m2m_token_manager=M2MTokenManager( secrets_manager=secrets_manager_client, environment=ENVIRONMENT, service_name=LAMBDA_NAME, ), ) s3 = boto3.resource("s3") PRODUCT_IDS_CHUNK_SIZE = 185 def handler(event: Any, context: Any) -> dict[str, str | int]: """Lambda entry point.""" account_type = event["account_type"] account_id = event["account_id"] execution_name = event["execution_name"] export_id = event["export_id"] asset_types = event["asset_types"] page_offset = 0 total_records = 1 json_data: list[dict[str, str | int | list[int] | list[str]]] = [] total_product_ids: list[int] = [] while page_offset < total_records: products_response = get_products_for_account( client=ows_client, account_type=account_type, account_id=int(account_id), page_limit=PAGE_LIMIT, offset=page_offset, ) response_body = products_response.content.decode("utf-8") if products_response.status_code != 200: log_msg = f"Error fetching products. {response_body}" logger.error(log_msg) capture_message(str(products_response), level="error") raise RuntimeError(log_msg) response_payload = json.loads(response_body) products = response_payload["items"] product_ids = [ product["product_id"] for product in products if product["context_type"] != "physical" ] if product_ids: total_product_ids.extend(product_ids) page_offset += PAGE_LIMIT total_records = response_payload["pagination"]["total_records"] json_data = split_product_ids_into_chunks( total_product_ids, PRODUCT_IDS_CHUNK_SIZE, execution_name, export_id, asset_types, ) upload_to_s3(f"{export_id}/{execution_name}/products.json", json.dumps(json_data)) return { "execution_name": execution_name, "export_id": export_id, "asset_types": asset_types, } def upload_to_s3(filename: str, json_data: str) -> None: s3.Object(S3_BUCKET, filename).put(Body=json_data, ContentType="application/json") def split_product_ids_into_chunks( total_product_ids: list[int], chunk_size: int, execution_name: str, export_id: str, asset_types: list[str], ) -> list[dict[str, str | int | list[int] | list[str]]]: return [ { "execution_name": execution_name, "export_id": export_id, "product_ids": total_product_ids[i : i + chunk_size], "asset_types": asset_types, "part_index": int(i / chunk_size) + 1, } for i in range(0, len(total_product_ids), chunk_size) ]