katana_public_api_client.katana_client¶
katana_public_api_client.katana_client
¶
KatanaClient - The pythonic Katana API client with automatic resilience.
This client uses httpx's native transport layer to provide automatic retries, rate limiting, error handling, and pagination for all API calls without any decorators or wrapper methods needed.
Attributes¶
Classes¶
ErrorLoggingTransport(wrapped_transport=None, logger=None, **kwargs)
¶
Bases: AsyncHTTPTransport
Transport layer that adds detailed error logging for 4xx client errors.
This transport wraps another AsyncHTTPTransport and intercepts responses to log detailed error information using the generated error models.
Parameters:
-
wrapped_transport(AsyncHTTPTransport | None, default:None) –The transport to wrap. If None, creates a new AsyncHTTPTransport.
-
logger(Logger | None, default:None) –Logger instance for capturing error details. If None, creates a default logger.
-
**kwargs(Any, default:{}) –Additional arguments passed to AsyncHTTPTransport if wrapped_transport is None.
Source code in katana_public_api_client/katana_client.py
Functions¶
handle_async_request(request)
async
¶
Handle request and log detailed error information for 4xx responses.
Source code in katana_public_api_client/katana_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 - Auto-pagination ON by default for GET requests (collects all pages automatically) - Uses 250 items per page (Katana's max) for efficient pagination - Rich logging and observability - Minimal configuration - just works out of the box
Auto-pagination behavior:
- ON by default for GET requests with NO page parameter
- Uses 250 items per page when no limit specified by caller
- If caller specifies a limit, that limit is used per page
- ANY explicit page parameter disables auto-pagination (e.g., page=1)
- Disabled per-request via extensions: extensions={"auto_pagination": False}
- Control max pages via max_pages constructor parameter
- Limit total items via extensions: extensions={"max_items": 200}
Usage
async with KatanaClient() as client: from katana_public_api_client.api.product import get_all_products
# Auto-pagination is ON - all pages collected automatically
# Uses 250 items per page for efficiency
response = await get_all_products.asyncio_detailed(
client=client, # Pass client directly - no .client needed!
)
# Use a custom limit per page (100 instead of 250)
response = await get_all_products.asyncio_detailed(
client=client,
limit=100, # Use 100 per page
)
# Get a specific page only (ANY page param disables auto-pagination)
response = await get_all_products.asyncio_detailed(
client=client,
page=2, # Get page 2 only
limit=50
)
# Limit total items collected (via httpx client)
httpx_client = client.get_async_httpx_client()
response = await httpx_client.get(
"/products",
extensions={"max_items": 200} # Stop after 200 items
)
# 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) –Any object whose debug/info/warning/error methods accept (msg, *args, **kwargs) — the standard logging.Logger call convention (e.g. logging.Logger, structlog.BoundLogger). If None, creates a default stdlib 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
1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 | |
Attributes¶
api
property
¶
Thin CRUD wrappers for all API resources. Returns raw attrs models.
Example
async with KatanaClient() as client: ... products = await client.api.products.list(is_sellable=True) ... product = await client.api.products.get(123) ... await client.api.products.delete(123)
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¶
PaginationTransport(wrapped_transport=None, max_pages=100, logger=None, **kwargs)
¶
Bases: AsyncHTTPTransport
Transport layer that adds automatic pagination for GET requests.
This transport wraps another transport and automatically collects all pages for GET requests by default.
Auto-pagination behavior:
- ON by default for GET requests with NO page parameter in URL
- Uses 250 items per page (Katana's max) when no limit specified by caller
- If caller specifies a limit, that limit is used (caller's choice)
- ANY explicit page parameter in URL disables auto-pagination (e.g., ?page=1)
- Disabled when request has extensions={"auto_pagination": False}
- Only applies to GET requests (POST, PUT, etc. are never paginated)
Controlling pagination limits:
- max_pages (constructor): Maximum number of pages to fetch
- max_items (extension): Maximum total items to collect, e.g.,
extensions={"max_items": 200} stops after 200 items
Parameters:
-
wrapped_transport(AsyncHTTPTransport | None, default:None) –The transport to wrap. If None, creates a new AsyncHTTPTransport.
-
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 pagination operations. If None, creates a default logger.
-
**kwargs(Any, default:{}) –Additional arguments passed to AsyncHTTPTransport if wrapped_transport is None.
Source code in katana_public_api_client/katana_client.py
Functions¶
handle_async_request(request)
async
¶
Handle request with automatic pagination for GET requests.
Auto-pagination is ON by default for GET requests. It is disabled when:
- extensions={"auto_pagination": False} is set, OR
- ANY explicit page parameter is in the URL (e.g., ?page=1 or ?page=2)
To get auto-pagination, simply don't pass a page parameter. The transport will automatically use 250 items per page (Katana's max) unless you specify a limit, in which case your limit will be respected.
Source code in katana_public_api_client/katana_client.py
RateLimitAwareRetry(*args, **kwargs)
¶
Bases: Retry
Custom Retry class that allows non-idempotent methods (POST, PATCH) to be retried ONLY when receiving a 429 (Too Many Requests) status code.
For all other retryable status codes (502, 503, 504), only idempotent methods (HEAD, GET, PUT, DELETE, OPTIONS, TRACE) will be retried.
This ensures we don't accidentally retry non-idempotent operations after server errors, but we DO retry them when we're being rate-limited.
Source code in katana_public_api_client/katana_client.py
Functions¶
increment()
¶
Return a new retry instance with the attempt count incremented.
Source code in katana_public_api_client/katana_client.py
is_retryable_method(method)
¶
Allow all methods to pass through the initial check.
Store the method for later use in is_retryable_status_code.
Source code in katana_public_api_client/katana_client.py
is_retryable_status_code(status_code)
¶
Check if a status code is retryable for the current method.
For 429 (rate limiting), allow all methods. For other errors (502, 503, 504), only allow idempotent methods.
Source code in katana_public_api_client/katana_client.py
Functions¶
ResilientAsyncTransport(max_retries=5, max_pages=100, logger=None, **kwargs)
¶
Factory function that creates a chained transport with error logging, pagination, and retry capabilities.
This function chains multiple transport layers: 1. AsyncHTTPTransport (base HTTP transport) 2. ErrorLoggingTransport (logs detailed 4xx errors) 3. PaginationTransport (auto-collects paginated responses) 4. RetryTransport (handles retries with Retry-After header support)
Parameters:
-
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 operations. If None, creates a default logger.
-
**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
Returns:
-
RetryTransport–A RetryTransport instance wrapping all the layered transports.
Note
When using a custom transport, parameters like http2, limits, and verify must be passed to this factory function (which passes them to the base AsyncHTTPTransport), not to the httpx.Client/AsyncClient constructor.
Example
Source code in katana_public_api_client/katana_client.py
992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 | |