"""Module to interact with ows-masters-registry to update masters registry.""" import json from typing import Tuple import config from owsclient import M2MTokenManager from owsclient import OwsClient from src.utils import constants logger = config.setup_logger(__name__) m2m_token_manager = M2MTokenManager( secrets_manager=config.secrets_manager_client, environment=config.ENVIRONMENT, service_name=config.SERVICE_NAME, ) ows_client = OwsClient( environment=config.ENVIRONMENT, service_name=config.SERVICE_NAME, m2m_token_manager=m2m_token_manager if config.ENVIRONMENT != config.TEST_ENVIRONMENT else None, ) def post_upcs(upcs: list[str]) -> Tuple[str, str, dict[str, str]]: """Post a batch of UPCs to the masters registry, skipping UPCs with validation errors.""" remaining_upcs = list(upcs) skipped_upcs = {} while remaining_upcs: response = ows_client.post( constants.OWS_MASTERS_REGISTRY, path='/ownership/upcs', headers={'Orchard-User-Id': 'oa:179'}, json={'upcs': remaining_upcs}, ) if response.status_code != 400: response.raise_for_status() return str(response.status_code), response.text, skipped_upcs try: failed = {item['upc']: item.get('error_message', 'Unknown error') for item in json.loads(response.text) if 'upc' in item} except Exception: failed = {} if not failed: logger.error(f'Masters registry error {response.status_code}: {response.text}') response.raise_for_status() logger.warning(f'Skipping {len(failed)} UPCs due to validation errors: {response.text}') skipped_upcs.update(failed) remaining_upcs = [upc for upc in remaining_upcs if upc not in failed] return '200', f'Completed. Skipped {len(skipped_upcs)} UPCs: {list(skipped_upcs)}', skipped_upcs def update_registry(upcs: list) -> Tuple[list[Tuple[str, str]], dict]: """Bulk update UPCs into the masters registry, batching if needed. Args: upcs (list): List of UPC codes to send. Returns: Tuple of (list of (status_code, response_text) per batch, dict of skipped UPC -> error message). """ batches = [upcs[i:i + config.MAX_UPCS_COUNT] for i in range(0, len(upcs), config.MAX_UPCS_COUNT)] logger.info(f'Updating registry for {len(upcs)} UPCs in {len(batches)} batch(es).') results = [] all_skipped_upcs = {} for batch in batches: try: status, text, skipped_upcs = post_upcs(batch) all_skipped_upcs.update(skipped_upcs) results.append((status, text)) except Exception as e: results.append(('ERROR', repr(e))) failed = [r for r in results if r[0] == 'ERROR'] logger.info(f'Registry update complete: {len(results) - len(failed)} succeeded, {len(failed)} failed.') return results, all_skipped_upcs