A modern, pythonic StockTrim Inventory Management API client with automatic retries, rate limiting, and smart pagination
Project description
StockTrim OpenAPI Client
A production-ready Python client library and MCP server for the StockTrim Inventory Management API.
Features
Client Library
- ๐ฏ Domain Helpers: Ergonomic wrapper methods for common operations (15+ convenience functions)
- ๐ Transport-Layer Resilience: Automatic retries with exponential backoff built into HTTP transport
- โก Modern Python: Fully async/await with comprehensive type hints (ty strict)
- ๐ Custom Authentication: Automatic handling of StockTrim
api-auth-idandapi-auth-signatureheaders - ๐ก๏ธ Typed Exceptions: Structured error handling (AuthenticationError, ValidationError, ServerError, etc.)
- ๐ฆ OpenAPI Generated: Always up-to-date with the latest StockTrim API
MCP Server
- ๐ค AI Integration: Natural language interface for Claude and other AI assistants
- โก FastMCP: High-performance Model Context Protocol implementation
- ๐ง Production Ready: 5 tools across product, customer, and inventory domains
- ๐ฏ Type-Safe: Full Pydantic validation for all operations
- ๐ Well-Documented: Comprehensive usage examples and troubleshooting
Installation
Client Library
# With UV (recommended)
uv add stocktrim-openapi-client
# With pip
pip install stocktrim-openapi-client
# With Poetry
poetry add stocktrim-openapi-client
MCP Server
# With UV
uv add stocktrim-mcp-server
# With pip
pip install stocktrim-mcp-server
Quick Start
Using Domain Helpers (Recommended)
from stocktrim_public_api_client import StockTrimClient
async with StockTrimClient(
api_auth_id="your_tenant_id",
api_auth_signature="your_tenant_name"
) as client:
# Product operations
product = await client.products.find_by_code("WIDGET-001")
widgets = await client.products.search("WIDGET")
exists = await client.products.exists("WIDGET-001")
# Customer operations
customer = await client.customers.get("CUST-001")
customer = await client.customers.find_or_create(
"CUST-002",
name="New Customer",
email="customer@example.com"
)
# Inventory operations
await client.inventory.set_for_product(
product_id="123",
stock_on_hand=50.0,
stock_on_order=100.0,
location_code="WAREHOUSE-A"
)
Using Generated API Methods
from stocktrim_public_api_client import StockTrimClient
from stocktrim_public_api_client.generated.api.products import get_api_products
from stocktrim_public_api_client.utils import unwrap
async with StockTrimClient(
api_auth_id="your_tenant_id",
api_auth_signature="your_tenant_name"
) as client:
# Direct API call with automatic retries and auth
response = await get_api_products.asyncio_detailed(client=client)
# Unwrap response or raise typed exception
products = unwrap(response) # Raises AuthenticationError, ServerError, etc.
MCP Server
# Set environment variables
export STOCKTRIM_API_AUTH_ID=your_tenant_id
export STOCKTRIM_API_AUTH_SIGNATURE=your_tenant_name
# Run server
uvx stocktrim-mcp-server
For Claude Desktop integration, see MCP Server README.
Domain Helpers
The client provides convenient helper classes that wrap the generated API:
Products
find_by_code(code)- Get product by exact codesearch(code_prefix)- Find products starting with prefixexists(code)- Check if product existsget_all()- List all productscreate(...)- Create new productdelete(product_id)- Delete product
Customers
get(code)- Get customer by codeget_all()- List all customersexists(code)- Check if customer existsfind_or_create(code, **defaults)- Get or create customer (idempotent)update(customer)- Update customer
Suppliers
find_by_code(code)- Get supplier by code (handles API inconsistencies)create_one(supplier)- Create single supplierexists(code)- Check if supplier existsget_all()- List all supplierscreate([suppliers])- Batch create suppliersdelete(code)- Delete supplier
Sales Orders
get_for_product(product_id)- Get orders for specific productdelete_for_product(product_id)- Delete all orders for productget_all()- List all orderscreate(...)- Create orderdelete(...)- Delete orders
Purchase Orders
find_by_reference(reference_number)- Get order by referenceexists(reference_number)- Check if order existsget_all()- List all orderscreate(...)- Create orderdelete(...)- Delete orders
Inventory
set_for_product(product_id, stock_on_hand, stock_on_order, ...)- Set inventory levelsset(request)- Batch set inventory
Locations
get_all()- List all locationscreate(...)- Create location
See docs/user-guide/helper-methods.md for complete documentation.
Error Handling
The client provides typed exceptions for structured error handling:
from stocktrim_public_api_client.utils import (
unwrap,
AuthenticationError,
ValidationError,
NotFoundError,
ServerError
)
try:
product = unwrap(response)
except AuthenticationError:
print("Invalid credentials")
except ValidationError as e:
print(f"Validation failed: {e.validation_errors}")
except NotFoundError:
print("Product not found")
except ServerError as e:
print(f"Server error: {e.status_code}")
Configuration
Environment Variables
# Required
STOCKTRIM_API_AUTH_ID=your_tenant_id
STOCKTRIM_API_AUTH_SIGNATURE=your_tenant_name
# Optional
STOCKTRIM_BASE_URL=https://api.stocktrim.com # Default
Programmatic Configuration
async with StockTrimClient(
api_auth_id="your_tenant_id",
api_auth_signature="your_tenant_name",
base_url="https://api.stocktrim.com",
timeout=30.0,
max_retries=5
) as client:
# Use client
pass
Architecture
Transport-Layer Resilience
Resilience features are implemented at the HTTP transport level:
- Automatic retries on 5xx errors for idempotent methods (GET, HEAD, OPTIONS, TRACE)
- Exponential backoff with jitter to prevent thundering herd
- Error logging with detailed response parsing
- Custom authentication injection without modifying generated code
This approach ensures:
- โ All generated API methods automatically get resilience features
- โ No code changes needed when regenerating from OpenAPI spec
- โ Type safety preserved throughout
- โ Optimal performance (resilience at lowest level)
Domain Helpers
Helper classes provide:
- Clear intent with intuitive method names
- API inconsistency handling (e.g., single vs list returns)
- Common patterns for frequent workflows
- Reduced boilerplate for simple operations
- Full type safety with comprehensive hints
MCP Server Tools
The MCP server provides 5 tools for AI assistant integration:
- get_product - Retrieve product by code
- search_products - Search products by prefix
- get_customer - Retrieve customer by code
- list_customers - List all customers
- set_product_inventory - Update inventory levels
Example conversation with Claude:
You: What products do we have starting with "WID"?
Claude: [uses search_products("WID")]
Found 3 products:
- WIDGET-001: Standard Widget ($10.00)
- WIDGET-002: Premium Widget ($15.00)
- WIDGET-SPECIAL: Custom Widget ($25.00)
See stocktrim_mcp_server/README.md for detailed usage.
Development
Setup
# Clone repository
git clone https://github.com/dougborg/stocktrim-openapi-client.git
cd stocktrim-openapi-client
# Install UV (if needed)
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
# Install dependencies
uv sync --all-extras
# Install pre-commit hooks
uv run pre-commit install
Common Tasks
# Run tests
uv run poe test
# Run linting
uv run poe lint
# Format code
uv run poe format
# Type check
uv run ty check
# Regenerate client from OpenAPI spec
uv run poe regenerate-client
# Build documentation
uv run poe docs-build
# Run all checks (format + lint + test)
uv run poe check
Testing
# All tests
uv run poe test
# With coverage
uv run poe test-coverage
# Unit tests only
uv run poe test-unit
# Integration tests only
uv run poe test-integration
Project Structure
stocktrim-openapi-client/
โโโ stocktrim_public_api_client/ # Client library
โ โโโ stocktrim_client.py # Main client with transport layer
โ โโโ helpers/ # Domain helper classes
โ โ โโโ products.py
โ โ โโโ customers.py
โ โ โโโ suppliers.py
โ โ โโโ sales_orders.py
โ โ โโโ purchase_orders.py
โ โ โโโ inventory.py
โ โ โโโ locations.py
โ โโโ utils.py # Response unwrapping & exceptions
โ โโโ generated/ # OpenAPI-generated code
โ โโโ api/ # API endpoint methods
โ โโโ models/ # Data models
โ โโโ client.py # Base client
โโโ stocktrim_mcp_server/ # MCP server package
โ โโโ src/stocktrim_mcp_server/
โ โโโ server.py # FastMCP server
โ โโโ tools/ # MCP tool implementations
โโโ tests/ # Test suite
โโโ scripts/ # Development scripts
โโโ docs/ # Documentation
Documentation
- Full Documentation: https://dougborg.github.io/stocktrim-openapi-client/
- Client Guide: docs/user-guide/client-guide.md
- Helper Methods: docs/user-guide/helper-methods.md
- Testing Guide: docs/user-guide/testing.md
- MCP Server: stocktrim_mcp_server/README.md
Contributing
Contributions are welcome! Please see:
- Development Setup above
- Code of Conduct
- API Feedback - Constructive feedback for StockTrim developers
License
MIT License - see LICENSE for details.
Acknowledgments
- Built with httpx for modern async HTTP
- Generated with openapi-python-client
- MCP server built with FastMCP
- Architecture patterns inspired by katana-openapi-client
Support
- Issues: GitHub Issues
- Source: GitHub Repository
- StockTrim: www.stocktrim.com
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file stocktrim_openapi_client-0.6.0.tar.gz.
File metadata
- Download URL: stocktrim_openapi_client-0.6.0.tar.gz
- Upload date:
- Size: 318.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f597f1720e5c5d26328fd1f5116e49f149e28725cae5c701a74afface5937e71
|
|
| MD5 |
2654ea9a861e177fb87961061ece6cf3
|
|
| BLAKE2b-256 |
f7f84fb4c70b05b38449a1998b135488764552847d1d7e3d3e4c852e469b88a0
|
Provenance
The following attestation bundles were made for stocktrim_openapi_client-0.6.0.tar.gz:
Publisher:
release.yml on dougborg/stocktrim-openapi-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stocktrim_openapi_client-0.6.0.tar.gz -
Subject digest:
f597f1720e5c5d26328fd1f5116e49f149e28725cae5c701a74afface5937e71 - Sigstore transparency entry: 663107936
- Sigstore integration time:
-
Permalink:
dougborg/stocktrim-openapi-client@3ff95cd3a14197de25a55babd7c9ab30b753c9be -
Branch / Tag:
refs/heads/main - Owner: https://github.com/dougborg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3ff95cd3a14197de25a55babd7c9ab30b753c9be -
Trigger Event:
push
-
Statement type:
File details
Details for the file stocktrim_openapi_client-0.6.0-py3-none-any.whl.
File metadata
- Download URL: stocktrim_openapi_client-0.6.0-py3-none-any.whl
- Upload date:
- Size: 153.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c1f0f6f3260b3a4d86e7313f94f9eddae9255124225c6121898f6e3ce51c2e9
|
|
| MD5 |
be429b35a4ecb945452cb480726d14f1
|
|
| BLAKE2b-256 |
c91a27cfa6834d75f21212bf39ed421d948f81a63e5413552b21594e9b477675
|
Provenance
The following attestation bundles were made for stocktrim_openapi_client-0.6.0-py3-none-any.whl:
Publisher:
release.yml on dougborg/stocktrim-openapi-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stocktrim_openapi_client-0.6.0-py3-none-any.whl -
Subject digest:
5c1f0f6f3260b3a4d86e7313f94f9eddae9255124225c6121898f6e3ce51c2e9 - Sigstore transparency entry: 663107947
- Sigstore integration time:
-
Permalink:
dougborg/stocktrim-openapi-client@3ff95cd3a14197de25a55babd7c9ab30b753c9be -
Branch / Tag:
refs/heads/main - Owner: https://github.com/dougborg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3ff95cd3a14197de25a55babd7c9ab30b753c9be -
Trigger Event:
push
-
Statement type: