katana_public_api_client¶
katana_public_api_client
¶
Katana Public API Client - Python client for Katana Manufacturing ERP.
Classes¶
APIError(message, status_code, error_response=None)
¶
Bases: Exception
Base exception for API errors.
Parameters:
-
message(str) –Human-readable error message
-
status_code(int) –HTTP status code
-
error_response(ErrorResponse | DetailedErrorResponse | None, default:None) –The error response object from the API
Source code in katana_public_api_client/utils.py
Functions¶
AuthenticatedClient
¶
A Client which has been authenticated for use on secured endpoints
The following are accepted as keyword arguments and will be used to construct httpx Clients internally:
``base_url``: The base URL for the API, all requests are made to a relative path to this URL
``cookies``: A dictionary of cookies to be sent with every request
``headers``: A dictionary of headers to be sent with every request
``timeout``: The maximum amount of a time a request can take. API functions will raise
httpx.TimeoutException if this is exceeded.
``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production,
but can be set to False for testing purposes.
``follow_redirects``: Whether or not to follow redirects. Default value is False.
``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor.
Functions¶
__aenter__()
async
¶
Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)
__aexit__(*args, **kwargs)
async
¶
Exit a context manager for underlying httpx.AsyncClient (see httpx docs)
__enter__()
¶
Enter a context manager for self.client—you cannot enter twice (see httpx docs)
__exit__(*args, **kwargs)
¶
Exit a context manager for internal httpx.Client (see httpx docs)
get_async_httpx_client()
¶
Get the underlying httpx.AsyncClient, constructing a new one if not previously set
Source code in katana_public_api_client/client.py
get_httpx_client()
¶
Get the underlying httpx.Client, constructing a new one if not previously set
Source code in katana_public_api_client/client.py
set_async_httpx_client(async_client)
¶
Manually the underlying httpx.AsyncClient
NOTE: This will override any other settings on the client, including cookies, headers, and timeout.
Source code in katana_public_api_client/client.py
set_httpx_client(client)
¶
Manually set the underlying httpx.Client
NOTE: This will override any other settings on the client, including cookies, headers, and timeout.
Source code in katana_public_api_client/client.py
with_cookies(cookies)
¶
Get a new client matching this one with additional cookies
Source code in katana_public_api_client/client.py
with_headers(headers)
¶
Get a new client matching this one with additional headers
Source code in katana_public_api_client/client.py
with_timeout(timeout)
¶
Get a new client matching this one with a new timeout (in seconds)
Source code in katana_public_api_client/client.py
AuthenticationError(message, status_code, error_response=None)
¶
Bases: APIError
Raised when authentication fails (401).
Source code in katana_public_api_client/utils.py
Client
¶
A class for keeping track of data related to the API
The following are accepted as keyword arguments and will be used to construct httpx Clients internally:
``base_url``: The base URL for the API, all requests are made to a relative path to this URL
``cookies``: A dictionary of cookies to be sent with every request
``headers``: A dictionary of headers to be sent with every request
``timeout``: The maximum amount of a time a request can take. API functions will raise
httpx.TimeoutException if this is exceeded.
``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production,
but can be set to False for testing purposes.
``follow_redirects``: Whether or not to follow redirects. Default value is False.
``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor.
Functions¶
__aenter__()
async
¶
Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)
__aexit__(*args, **kwargs)
async
¶
Exit a context manager for underlying httpx.AsyncClient (see httpx docs)
__enter__()
¶
Enter a context manager for self.client—you cannot enter twice (see httpx docs)
__exit__(*args, **kwargs)
¶
Exit a context manager for internal httpx.Client (see httpx docs)
get_async_httpx_client()
¶
Get the underlying httpx.AsyncClient, constructing a new one if not previously set
Source code in katana_public_api_client/client.py
get_httpx_client()
¶
Get the underlying httpx.Client, constructing a new one if not previously set
Source code in katana_public_api_client/client.py
set_async_httpx_client(async_client)
¶
Manually the underlying httpx.AsyncClient
NOTE: This will override any other settings on the client, including cookies, headers, and timeout.
Source code in katana_public_api_client/client.py
set_httpx_client(client)
¶
Manually set the underlying httpx.Client
NOTE: This will override any other settings on the client, including cookies, headers, and timeout.
Source code in katana_public_api_client/client.py
with_cookies(cookies)
¶
Get a new client matching this one with additional cookies
Source code in katana_public_api_client/client.py
with_headers(headers)
¶
Get a new client matching this one with additional headers
Source code in katana_public_api_client/client.py
with_timeout(timeout)
¶
Get a new client matching this one with a new timeout (in seconds)
Source code in katana_public_api_client/client.py
KatanaClient(api_key=None, base_url=None, timeout=30.0, max_retries=5, max_pages=100, logger=None, **httpx_kwargs)
¶
Bases: AuthenticatedClient
The pythonic Katana API client with automatic resilience and pagination.
This client inherits from AuthenticatedClient and can be passed directly to generated API methods without needing the .client property.
Features: - Automatic retries on network errors and server errors (5xx) - Automatic rate limit handling with Retry-After header support - Smart auto-pagination that detects and handles paginated responses automatically - Rich logging and observability - Minimal configuration - just works out of the box
Usage
Auto-pagination happens automatically - just call the API¶
async with KatanaClient() as client: from katana_public_api_client.api.product import get_all_products
# This automatically collects all pages if pagination is detected
response = await get_all_products.asyncio_detailed(
client=client, # Pass client directly - no .client needed!
limit=50 # All pages collected automatically
)
# Get specific page only (add page=X to disable auto-pagination)
response = await get_all_products.asyncio_detailed(
client=client,
page=1, # Get specific page
limit=100 # Set page size
)
# Control max pages globally
client_limited = KatanaClient(max_pages=5) # Limit to 5 pages max
Parameters:
-
api_key(str | None, default:None) –Katana API key. If None, will try to load from KATANA_API_KEY env var, .env file, or ~/.netrc file (in that order).
-
base_url(str | None, default:None) –Base URL for the Katana API. Defaults to https://api.katanamrp.com/v1
-
timeout(float, default:30.0) –Request timeout in seconds. Defaults to 30.0.
-
max_retries(int, default:5) –Maximum number of retry attempts for failed requests. Defaults to 5.
-
max_pages(int, default:100) –Maximum number of pages to collect during auto-pagination. Defaults to 100.
-
logger(Logger | None, default:None) –Logger instance for capturing client operations. If None, creates a default logger.
-
**httpx_kwargs(Any, default:{}) –Additional arguments passed to the base AsyncHTTPTransport. Common parameters include: - http2 (bool): Enable HTTP/2 support - limits (httpx.Limits): Connection pool limits - verify (bool | str | ssl.SSLContext): SSL certificate verification - cert (str | tuple): Client-side certificates - trust_env (bool): Trust environment variables for proxy configuration - event_hooks (dict): Custom event hooks (will be merged with built-in hooks)
Raises:
-
ValueError–If no API key is provided via api_key param, KATANA_API_KEY env var, .env file, or ~/.netrc file.
Note
Transport-related parameters (http2, limits, verify, etc.) are correctly passed to the innermost AsyncHTTPTransport layer, ensuring they take effect even with the layered transport architecture.
Example
async with KatanaClient() as client: ... # All API calls through client get automatic resilience ... response = await some_api_method.asyncio_detailed(client=client)
Source code in katana_public_api_client/katana_client.py
803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 | |
Attributes¶
inventory
property
¶
Access inventory and stock operations.
Returns:
-
Inventory–Inventory instance for stock levels, movements, and adjustments.
Example
async with KatanaClient() as client: ... # Check stock levels ... stock = await client.inventory.check_stock("WIDGET-001") ... low_stock = await client.inventory.list_low_stock(threshold=10)
materials
property
¶
Access material catalog operations.
Returns:
-
Materials–Materials instance for material CRUD operations.
Example
async with KatanaClient() as client: ... materials = await client.materials.list() ... material = await client.materials.get(123)
products
property
¶
Access product catalog operations.
Returns:
-
Products–Products instance for product CRUD and search operations.
Example
async with KatanaClient() as client: ... # Product CRUD ... products = await client.products.list(is_sellable=True) ... product = await client.products.get(123) ... results = await client.products.search("widget")
services
property
¶
Access service catalog operations.
Returns:
-
Services–Services instance for service CRUD operations.
Example
async with KatanaClient() as client: ... services = await client.services.list() ... service = await client.services.get(123)
variants
property
¶
Access variant catalog operations.
Returns:
-
Variants–Variants instance for variant CRUD operations.
Example
async with KatanaClient() as client: ... variants = await client.variants.list() ... variant = await client.variants.get(123)
Functions¶
RateLimitError(message, status_code, error_response=None)
¶
Bases: APIError
Raised when rate limit is exceeded (429).
Source code in katana_public_api_client/utils.py
ServerError(message, status_code, error_response=None)
¶
Bases: APIError
Raised when server error occurs (5xx).
Source code in katana_public_api_client/utils.py
ValidationError(message, status_code, error_response=None)
¶
Bases: APIError
Raised when request validation fails (422).
Parameters:
-
message(str) –Human-readable error message
-
status_code(int) –HTTP status code (should be 422)
-
error_response(DetailedErrorResponse | None, default:None) –The detailed error response with validation details
Source code in katana_public_api_client/utils.py
Functions¶
__str__()
¶
Format validation error with code-specific details.
Source code in katana_public_api_client/utils.py
Functions¶
get_error_message(response)
¶
Extract error message from an error response.
Parameters:
-
response(Response[T]) –The Response object (typically an error response)
Returns:
-
str | None–Error message string, or None if no error message found
Example
Source code in katana_public_api_client/utils.py
get_variant_display_name(variant)
¶
Build the full variant display name matching Katana UI format.
Format: "{Product/Material Name} / {Config Value 1} / {Config Value 2} / ..."
Example: "Mayhem 140 / Liquid Black / Large / 5 Star"
When the variant has been fetched with extend=product_or_material, the API returns variants with a nested product_or_material object (Product or Material). This function extracts the base product/material name and appends config attribute values separated by " / ".
Parameters:
-
variant(Variant) –Variant object (ideally with product_or_material populated)
Returns:
-
str–Formatted variant name with config values, or empty string if no name available
Example
from katana_public_api_client import KatanaClient
from katana_public_api_client.api.variant import get_variant
from katana_public_api_client.utils import get_variant_display_name
async with KatanaClient() as client:
response = await get_variant.asyncio_detailed(client=client, id=123)
variant = unwrap(response)
display_name = get_variant_display_name(variant)
print(display_name) # "Mayhem 140 / Liquid Black / Large / 5 Star"
Source code in katana_public_api_client/utils.py
handle_response(response, *, on_success=None, on_error=None, raise_on_error=False)
¶
Handle a response with custom success and error handlers.
This function provides a convenient way to handle both success and error cases with custom callbacks.
Parameters:
-
response(Response[T]) –The Response object from an API call
-
on_success(Callable[[T], Any] | None, default:None) –Callback function to call with parsed data on success
-
on_error(Callable[[APIError], Any] | None, default:None) –Callback function to call with APIError on error
-
raise_on_error(bool, default:False) –If True, raise the error even if on_error is provided
Returns:
-
Any–Result of on_success callback, result of on_error callback, or None
Example
def handle_products(product_list):
print(f"Got {len(product_list.data)} products")
return product_list.data
def handle_error(error):
print(f"Error: {error}")
return []
response = await get_all_products.asyncio_detailed(client=client)
products = handle_response(
response, on_success=handle_products, on_error=handle_error
)
Source code in katana_public_api_client/utils.py
is_error(response)
¶
Check if a response was an error (4xx or 5xx status code).
Parameters:
Returns:
-
bool–True if status code is 4xx or 5xx, False otherwise
Source code in katana_public_api_client/utils.py
is_success(response)
¶
Check if a response was successful (2xx status code).
Parameters:
Returns:
-
bool–True if status code is 2xx, False otherwise
Example
Source code in katana_public_api_client/utils.py
unwrap(response, *, raise_on_error=True)
¶
Unwrap a Response object and return the parsed data or raise an error.
This is the main utility function for handling API responses. It automatically raises appropriate exceptions for error responses and returns the parsed data for successful responses.
Parameters:
-
response(Response[T]) –The Response object from an API call
-
raise_on_error(bool, default:True) –If True, raise exceptions on error status codes. If False, return None on errors.
Returns:
-
T | None–The parsed response data
Raises:
-
AuthenticationError–When status is 401
-
ValidationError–When status is 422
-
RateLimitError–When status is 429
-
ServerError–When status is 5xx
-
APIError–For other error status codes
Example
from katana_public_api_client import KatanaClient
from katana_public_api_client.api.product import get_all_products
from katana_public_api_client.utils import unwrap
async with KatanaClient() as client:
response = await get_all_products.asyncio_detailed(client=client)
product_list = unwrap(
response
) # Raises on error, returns parsed data
products = product_list.data # List of Product objects
Source code in katana_public_api_client/utils.py
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | |
unwrap_data(response, *, raise_on_error=True, default=None)
¶
Unwrap a Response and extract the data list from list responses.
This is a convenience function that unwraps the response and extracts
the .data field from list response objects (like ProductListResponse,
WebhookListResponse, etc.).
Parameters:
-
response(Response[T]) –The Response object from an API call
-
raise_on_error(bool, default:True) –If True, raise exceptions on error status codes. If False, return default on errors.
-
default(list[DataT] | None, default:None) –Default value to return if data is not available
Returns:
-
Any | None–List of data objects, or default if not available
Example
from katana_public_api_client import KatanaClient
from katana_public_api_client.api.product import get_all_products
from katana_public_api_client.utils import unwrap_data
async with KatanaClient() as client:
response = await get_all_products.asyncio_detailed(client=client)
products = unwrap_data(response) # Directly get list of Products
for product in products:
print(product.name)