import logging from typing import Dict from pyinfra.config import CONFIG from pyinfra.exceptions import InvalidStorageItemFormat from pyinfra.server.packing import string_to_bytes logger = logging.getLogger() def build_storage_upload_info(analysis_payload, request_metadata): storage_upload_info = {**request_metadata, "id": analysis_payload["metadata"].get("id", 0)} storage_upload_info["fileId"] = build_file_path( storage_upload_info, storage_upload_info.get("operation", CONFIG.service.response_folder) ) return storage_upload_info def build_file_path(storage_upload_info, folder): return f"{storage_upload_info['fileId']}" + (f"/{folder}" if folder else "") def standardize(storage_item) -> Dict: """Storage items can be a blob or a blob with metadata. Standardizes to the latter. Cases: 1) backend upload: data as bytes 2) Some Python service's upload: data as bytes of a json string "{'data': , 'metadata': }", where value of key 'data' was encoded with bytes_to_string(...) Returns: {"data": bytes, "metadata": dict} """ def is_blob_without_metadata(storage_item): return isinstance(storage_item, bytes) def is_blob_with_metadata(storage_item: Dict): return isinstance(storage_item, dict) if is_blob_without_metadata(storage_item): return wrap(storage_item) elif is_blob_with_metadata(storage_item): validate(storage_item) return storage_item else: # Fallback / used for testing with simple data logger.warning("Encountered storage data in unexpected format.") assert isinstance(storage_item, str) return wrap(string_to_bytes(storage_item)) def wrap(data): return {"data": data, "metadata": {}} def validate(storage_item): if not ("data" in storage_item and "metadata" in storage_item): raise InvalidStorageItemFormat(f"Expected a mapping with keys 'data' and 'metadata', got {storage_item}.")