Source code for ABConnect.Builder

from copy import deepcopy
from typing import Any, Dict, List, Optional, Union
from ABConnect.common import load_json_resource


[docs] class APIRequestBuilder: """ Builder for API requests using static JSON configurations. """
[docs] def __init__( self, req_type: str = "Regular", base_data: Optional[Dict[str, Any]] = None ): if base_data: self.data = deepcopy(base_data) elif req_type == "3PL": base = load_json_resource("simple_request.json") extracontainers = load_json_resource("extra_containers.json") self.data = {**base, **extracontainers} else: self.data = load_json_resource("simple_request.json") self.transformations = {}
[docs] def load(self, base_data: Dict[str, Any]) -> "APIRequestBuilder": """ Loads new base data into the builder. """ self.data = deepcopy(base_data) return self
[docs] def update(self, path: Union[str, List[str]], value: Any) -> "APIRequestBuilder": """ Updates a nested dictionary or list structure by setting a value at the specified path. Args: path (Union[str, List[str]]): Dot-separated keys or list of keys/indexes. value (Any): The value to set. Returns: APIRequestBuilder: The updated instance. """ if isinstance(path, str): path = path.split(".") current = self.data for i, key in enumerate(path[:-1]): if key.isdigit(): key = int(key) if not isinstance(current, list): current = [] self._set_nested_value(self.data, path[:i], current) while len(current) <= key: current.append({}) elif key not in current or not isinstance(current[key], (dict, list)): current[key] = {} current = current[key] last_key = path[-1] if last_key.isdigit(): last_key = int(last_key) if not isinstance(current, list): current = [] self._set_nested_value(self.data, path[:-1], current) while len(current) <= last_key: current.append({}) if isinstance(value, dict) and isinstance(current[last_key], dict): current[last_key].update(value) else: current[last_key] = value else: if isinstance(value, dict) and isinstance(current.get(last_key), dict): current.setdefault(last_key, {}).update(value) else: current[last_key] = value return self
def _set_nested_value( self, data: Dict[str, Any], path: List[str], value: Any ) -> None: """ Sets a nested value in a dictionary based on a list of keys. """ for key in path[:-1]: if key.isdigit(): key = int(key) data = data.setdefault(key, {}) else: data = data.setdefault(key, {}) last_key = path[-1] if last_key.isdigit(): last_key = int(last_key) data[last_key] = value
[docs] def build(self) -> Dict[str, Any]: """ Returns the built API request data. """ return self.data