API Reference
This page provides detailed API documentation for using apiout programmatically.
Modules
apiout.cli
apiout.fetcher
API fetching and client management for apiout.
This module provides functionality for: - Fetching data from API endpoints defined in TOML configurations - Managing shared client instances across multiple API calls - Processing post-processors that combine multiple API results - Serializing API responses according to configuration
- apiout.fetcher.resolve_serializer(api_config: dict[str, Any], global_serializers: dict[str, Any] | None = None, client_ref: str | None = None) dict[str, Any][source]
Resolve serializer configuration from API config with client-scoped namespace support.
Resolution order: 1. Inline dict (api_config[“serializer”] is dict) - highest priority 2. Explicit dotted reference (e.g., “client.serializer_name”) 3. Client-scoped lookup (e.g., serializers.{client_ref}.{name}) 4. Global lookup (e.g., serializers.{name}) 5. Empty dict (no serializer found)
- Args:
api_config: API configuration dict containing optional ‘serializer’ key global_serializers: Optional dict of named serializer configurations client_ref: Optional client reference name for scoped serializer lookup
- Returns:
Resolved serializer configuration dict, or empty dict if none found
- Examples:
>>> # Global serializer >>> api_config = {"serializer": "my_serializer"} >>> global_serializers = {"my_serializer": {"fields": {"name": "name"}}} >>> resolve_serializer(api_config, global_serializers) {'fields': {'name': 'name'}}
>>> # Client-scoped serializer >>> api_config = {"serializer": "data", "client": "btc_price"} >>> global_serializers = {"btc_price.data": {"fields": {"value": "usd"}}} >>> resolve_serializer(api_config, global_serializers, client_ref="btc_price") {'fields': {'value': 'usd'}}
>>> # Explicit dotted reference >>> api_config = {"serializer": "btc_price.data"} >>> global_serializers = {"btc_price.data": {"fields": {"value": "usd"}}} >>> resolve_serializer(api_config, global_serializers) {'fields': {'value': 'usd'}}
- apiout.fetcher.fetch_api_data(api_config: dict[str, Any], global_serializers: dict[str, Any] | None = None, shared_clients: dict[str, Any] | None = None, client_configs: dict[str, Any] | None = None, user_params: dict[str, str] | None = None) Any[source]
Fetch data from an API endpoint based on configuration.
Dynamically imports a module, instantiates or reuses a client class, and calls the specified method. Supports shared client instances when using client references.
- Args:
- api_config: API configuration dict with keys:
module: Python module to import (required)
method: Method name to call on client (required)
client: Reference to a client config name (optional)
client_class: Class name to instantiate (default: “Client”)
init_params: Params for client initialization (optional)
url: URL parameter to pass to method (optional)
params: Additional parameters for method (optional)
- method_params: Default values for method parameters (optional)
serializer: Serializer config or reference (optional)
global_serializers: Named serializer configurations shared_clients: Dict to store/retrieve shared client instances client_configs: Dict of named client configurations user_params: Dict of user-provided runtime parameters
- Returns:
Serialized API response data, or error dict if fetch failed
- Example:
>>> api_config = { ... "module": "requests", ... "client_class": "Session", ... "method": "get", ... "url": "https://api.example.com/data" ... } >>> result = fetch_api_data(api_config)
- apiout.fetcher.process_post_processor(post_processor_config: dict[str, Any], api_results: dict[str, Any], global_serializers: dict[str, Any] | None = None) Any[source]
Process data from multiple APIs using a post-processor class.
Post-processors combine results from multiple API calls by instantiating a class with the API results as arguments, or calling a method on an instance with the results.
- Args:
- post_processor_config: Post-processor configuration dict with keys:
module: Python module to import (required)
class: Class name to instantiate (required)
inputs: List of API result names to pass as args (required)
method: Method name to call on instance (optional)
serializer: Serializer config or reference (optional)
api_results: Dict of API results by name global_serializers: Named serializer configurations
- Returns:
Serialized post-processor result, or error dict if processing failed
- Example:
>>> post_processor_config = { ... "module": "mymodule", ... "class": "DataCombiner", ... "inputs": ["api1", "api2"] ... } >>> api_results = {"api1": {"value": 1}, "api2": {"value": 2}} >>> result = process_post_processor(post_processor_config, api_results)
- class apiout.fetcher.ApiClient(config_paths: str | Path | list[str | Path], user_params: dict[str, str] | None = None)[source]
Bases:
objectStateful API client with configuration management and result caching.
ApiClient provides a high-level interface for loading API configurations from TOML files, fetching data from multiple APIs with shared client instances, and caching results for repeated access without re-fetching.
Supports: - Loading single or multiple TOML configuration files - Automatic merging of APIs, serializers, and post-processors - Shared client instance management via client references - Result caching with success/failure tracking - Timestamp tracking for each API call
- Attributes:
config_paths: List of loaded configuration file paths apis: List of API configurations from all loaded files serializers: Dict of named serializer configurations post_processors: List of post-processor configurations clients: Dict of named client configurations shared_clients: Dict of shared client instances by reference name results: Dict of API results by name (cached after fetch) status: Dict of status info by name (success, error, timestamp) last_fetch_time: Timestamp of the most recent fetch() call
- Example:
>>> # Single config file >>> client = ApiClient("config.toml") >>> results = client.fetch() >>> cached = client.get_results() >>> >>> # Multiple config files >>> client = ApiClient(["api_config.toml", "serializers.toml"]) >>> results = client.fetch() >>> status = client.get_status() >>> successful = client.get_successful_results()
- __init__(config_paths: str | Path | list[str | Path], user_params: dict[str, str] | None = None)[source]
Initialize ApiClient with one or more configuration files.
- Args:
- config_paths: Single path or list of paths to TOML configuration files.
All configs are loaded and merged during initialization.
user_params: Optional dict of user-provided runtime parameters
- fetch() dict[str, Any][source]
Fetch data from all configured APIs and post-processors.
Executes all API calls using shared client instances where configured, then runs post-processors on the results. Updates results, status, and last_fetch_time attributes.
- Returns:
Dict mapping API/post-processor names to their results
- Example:
>>> client = ApiClient("config.toml") >>> results = client.fetch() >>> print(results["my_api"]) {'data': 'value'}
- get_results() dict[str, Any][source]
Get cached results without re-fetching.
- Returns:
Dict of cached results from the last fetch() call
- Example:
>>> client = ApiClient("config.toml") >>> client.fetch() >>> cached = client.get_results() # No network call
- get_status() dict[str, dict][source]
Get status information for all APIs and post-processors.
- Returns:
Dict mapping names to status dicts with keys: - success: bool indicating if fetch/processing succeeded - error: error message if failed, None otherwise - timestamp: Unix timestamp of the operation
- Example:
>>> client = ApiClient("config.toml") >>> client.fetch() >>> status = client.get_status() >>> print(status["my_api"]) {'success': True, 'error': None, 'timestamp': 1234567890.123}
apiout.serializer
- apiout.serializer.traverse_path(obj: Any, path_parts: list[str], parse_json: bool = False) Any[source]
apiout.generator
- apiout.generator.analyze_object(obj: Any, max_depth: int = 3, current_depth: int = 0, visited: set[int] | None = None) dict[str, Any][source]
- apiout.generator.generate_serializer_config(analysis: dict[str, Any], prefix: str = '') dict[str, Any][source]
- apiout.generator.generate_toml_serializer(name: str, fields: dict[str, Any], indent: int = 0) str[source]
- apiout.generator.introspect_and_generate(module_name: str, client_class: str, method_name: str, url: str | None = None, params: dict[str, Any] | None = None, init_params: dict[str, Any] | None = None, serializer_name: str = 'generated', method_params: dict[str, Any] | None = None) str[source]
- apiout.generator.generate_api_toml(name: str, module_name: str, client_class: str, method_name: str, client_ref: str | None = None, init_params: dict[str, Any] | None = None, url: str | None = None, params: dict[str, Any] | None = None, method_params: dict[str, Any] | None = None) str[source]
- apiout.generator.introspect_post_processor_and_generate(module_name: str, class_name: str, method_name: str, input_modules: list[dict[str, Any]], serializer_name: str = 'generated') str[source]
Generate serializer for a post-processor by calling it with sample data.
- Args:
module_name: Module containing the post-processor class class_name: Post-processor class name method_name: Optional method to call on the instance input_modules: List of dicts with ‘module’, ‘client_class’,
‘method’, optional ‘init_params’, ‘url’, ‘params’ keys
serializer_name: Name for the generated serializer
Functions
fetch_api_data
- apiout.fetcher.fetch_api_data(api_config: dict[str, Any], global_serializers: dict[str, Any] | None = None, shared_clients: dict[str, Any] | None = None, client_configs: dict[str, Any] | None = None, user_params: dict[str, str] | None = None) Any[source]
Fetch data from an API endpoint based on configuration.
Dynamically imports a module, instantiates or reuses a client class, and calls the specified method. Supports shared client instances when using client references.
- Args:
- api_config: API configuration dict with keys:
module: Python module to import (required)
method: Method name to call on client (required)
client: Reference to a client config name (optional)
client_class: Class name to instantiate (default: “Client”)
init_params: Params for client initialization (optional)
url: URL parameter to pass to method (optional)
params: Additional parameters for method (optional)
- method_params: Default values for method parameters (optional)
serializer: Serializer config or reference (optional)
global_serializers: Named serializer configurations shared_clients: Dict to store/retrieve shared client instances client_configs: Dict of named client configurations user_params: Dict of user-provided runtime parameters
- Returns:
Serialized API response data, or error dict if fetch failed
- Example:
>>> api_config = { ... "module": "requests", ... "client_class": "Session", ... "method": "get", ... "url": "https://api.example.com/data" ... } >>> result = fetch_api_data(api_config)
Fetches data from an API using the provided configuration.
Parameters:
api_config(Dict[str, Any]): API configuration dictionaryglobal_serializers(Optional[Dict[str, Any]]): Global serializer configurationsuser_params(Optional[Dict[str, str]]): Runtime parameters to override method_params
Returns:
Any: Serialized API response or error dictionary
Example:
from apiout.fetcher import fetch_api_data
config = {
"name": "test",
"module": "requests",
"client_class": "Session",
"method": "get",
"url": "https://api.example.com",
"params": {}
}
result = fetch_api_data(config)
resolve_serializer
- apiout.fetcher.resolve_serializer(api_config: dict[str, Any], global_serializers: dict[str, Any] | None = None, client_ref: str | None = None) dict[str, Any][source]
Resolve serializer configuration from API config with client-scoped namespace support.
Resolution order: 1. Inline dict (api_config[“serializer”] is dict) - highest priority 2. Explicit dotted reference (e.g., “client.serializer_name”) 3. Client-scoped lookup (e.g., serializers.{client_ref}.{name}) 4. Global lookup (e.g., serializers.{name}) 5. Empty dict (no serializer found)
- Args:
api_config: API configuration dict containing optional ‘serializer’ key global_serializers: Optional dict of named serializer configurations client_ref: Optional client reference name for scoped serializer lookup
- Returns:
Resolved serializer configuration dict, or empty dict if none found
- Examples:
>>> # Global serializer >>> api_config = {"serializer": "my_serializer"} >>> global_serializers = {"my_serializer": {"fields": {"name": "name"}}} >>> resolve_serializer(api_config, global_serializers) {'fields': {'name': 'name'}}
>>> # Client-scoped serializer >>> api_config = {"serializer": "data", "client": "btc_price"} >>> global_serializers = {"btc_price.data": {"fields": {"value": "usd"}}} >>> resolve_serializer(api_config, global_serializers, client_ref="btc_price") {'fields': {'value': 'usd'}}
>>> # Explicit dotted reference >>> api_config = {"serializer": "btc_price.data"} >>> global_serializers = {"btc_price.data": {"fields": {"value": "usd"}}} >>> resolve_serializer(api_config, global_serializers) {'fields': {'value': 'usd'}}
Resolves serializer configuration from API config and global serializers.
Parameters:
api_config(Dict[str, Any]): API configuration dictionaryglobal_serializers(Optional[Dict[str, Any]]): Global serializer configurations
Returns:
Dict[str, Any]: Resolved serializer configuration
serialize_response
- apiout.serializer.serialize_response(responses: Any, serializer_config: dict[str, Any]) Any[source]
Serializes API response using the provided serializer configuration.
Parameters:
responses(Any): API response object(s)serializer_config(Dict[str, Any]): Serializer configuration
Returns:
Any: Serialized response
serialize_value
Converts a Python object to a JSON-serializable value.
Parameters:
obj(Any): Object to serialize
Returns:
Any: JSON-serializable value
apply_field_mapping
Applies field mapping configuration to an object.
Parameters:
obj(Any): Object to processfield_config(Dict[str, Any]): Field mapping configuration
Returns:
Any: Mapped result
call_method_or_attr
Calls a method or accesses an attribute on an object.
Parameters:
obj(Any): Object to accessname(str): Method or attribute name
Returns:
Any: Result of method call or attribute value
introspect_and_generate
- apiout.generator.introspect_and_generate(module_name: str, client_class: str, method_name: str, url: str | None = None, params: dict[str, Any] | None = None, init_params: dict[str, Any] | None = None, serializer_name: str = 'generated', method_params: dict[str, Any] | None = None) str[source]
Introspects an API response and generates a TOML serializer configuration.
Parameters:
module(str): Python module nameclient_class(str): Client class namemethod(str): Method name to callurl(str): API URLparams(Dict[str, Any]): API parametersname(str): Serializer name
Returns:
str: TOML serializer configuration
analyze_object
- apiout.generator.analyze_object(obj: Any, max_depth: int = 3, current_depth: int = 0, visited: set[int] | None = None) dict[str, Any][source]
Analyzes an object’s structure and returns metadata about its attributes and methods.
Parameters:
obj(Any): Object to analyzedepth(int): Maximum recursion depthvisited(Optional[Set[int]]): Set of visited object IDs
Returns:
Dict[str, Any]: Object analysis metadata
generate_serializer_config
- apiout.generator.generate_serializer_config(analysis: dict[str, Any], prefix: str = '') dict[str, Any][source]
Generates a serializer configuration dictionary from object analysis.
Parameters:
analysis(Dict[str, Any]): Object analysis metadataname(str): Serializer name
Returns:
str: TOML serializer configuration
Classes
Configuration Structure
API Configuration
- {
“name”: str, # Required: API identifier “module”: str, # Required: Python module name “client_class”: str, # Optional: Client class name (default: “Client”) “method”: str, # Required: Method name to call “url”: str, # Required: API URL “serializer”: str | dict, # Optional: Serializer reference or config “params”: dict, # Optional: API parameters “method_params”: dict # Optional: Default method parameters
}
Serializer Configuration
{
"fields": {
"output_field": str, # Simple attribute mapping
"nested_field": {
"method": str, # Method to call
"fields": dict # Nested field mappings
},
"collection": {
"iterate": {
"count": str, # Method returning count
"item": str, # Method taking index
"fields": dict # Fields for each item
}
}
}
}
Error Handling
Common Error Types
Import Errors
{
"error": "Failed to import module: ModuleNotFoundError: No module named 'xxx'"
}
Attribute Errors
{
"error": "Failed to access class or method: 'module' object has no attribute 'Class'"
}
API Call Errors
{
"error": "Failed to fetch data: <exception details>"
}
Usage Examples
Programmatic Usage
Basic Fetch
from apiout.fetcher import fetch_api_data
api_config = {
"name": "weather",
"module": "openmeteo_requests",
"client_class": "Client",
"method": "weather_api",
"url": "https://api.open-meteo.com/v1/forecast",
"params": {
"latitude": 52.52,
"longitude": 13.41,
"current": ["temperature_2m"]
}
}
result = fetch_api_data(api_config)
print(result)
With Serializer
from apiout.fetcher import fetch_api_data
api_config = {
"name": "weather",
"module": "openmeteo_requests",
"method": "weather_api",
"url": "https://api.open-meteo.com/v1/forecast",
"serializer": "openmeteo",
"params": {"latitude": 52.52, "longitude": 13.41}
}
global_serializers = {
"openmeteo": {
"fields": {
"latitude": "Latitude",
"longitude": "Longitude",
"current": {
"method": "Current",
"fields": {"time": "Time"}
}
}
}
}
result = fetch_api_data(api_config, global_serializers)
print(result)
Custom Serialization
from apiout.serializer import serialize_response, apply_field_mapping
# Assuming you have a response object
response = api_call()
# Define field mapping
field_config = {
"id": "Id",
"name": "Name",
"data": {
"method": "GetData",
"fields": {
"value": "Value",
"timestamp": "Timestamp"
}
}
}
# Apply mapping
result = apply_field_mapping(response, field_config)
print(result)
Generate Configuration
from apiout.generator import introspect_and_generate
config = introspect_and_generate(
module="openmeteo_requests",
client_class="Client",
method="weather_api",
url="https://api.open-meteo.com/v1/forecast",
params={"latitude": 52.52, "longitude": 13.41},
name="openmeteo"
)
print(config) # TOML serializer configuration