Skip to main content

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.

Python Version License Code style: ruff PyPI - Version PyPI - MCP Server

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-id and api-auth-signature headers
  • ๐Ÿ›ก๏ธ 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 code
  • search(code_prefix) - Find products starting with prefix
  • exists(code) - Check if product exists
  • get_all() - List all products
  • create(...) - Create new product
  • delete(product_id) - Delete product

Customers

  • get(code) - Get customer by code
  • get_all() - List all customers
  • exists(code) - Check if customer exists
  • find_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 supplier
  • exists(code) - Check if supplier exists
  • get_all() - List all suppliers
  • create([suppliers]) - Batch create suppliers
  • delete(code) - Delete supplier

Sales Orders

  • get_for_product(product_id) - Get orders for specific product
  • delete_for_product(product_id) - Delete all orders for product
  • get_all() - List all orders
  • create(...) - Create order
  • delete(...) - Delete orders

Purchase Orders

  • find_by_reference(reference_number) - Get order by reference
  • exists(reference_number) - Check if order exists
  • get_all() - List all orders
  • create(...) - Create order
  • delete(...) - Delete orders

Inventory

  • set_for_product(product_id, stock_on_hand, stock_on_order, ...) - Set inventory levels
  • set(request) - Batch set inventory

Locations

  • get_all() - List all locations
  • create(...) - 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:

  1. get_product - Retrieve product by code
  2. search_products - Search products by prefix
  3. get_customer - Retrieve customer by code
  4. list_customers - List all customers
  5. 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

Contributing

Contributions are welcome! Please see:

License

MIT License - see LICENSE for details.

Acknowledgments

Support

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stocktrim_openapi_client-0.9.1.tar.gz (351.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stocktrim_openapi_client-0.9.1-py3-none-any.whl (154.0 kB view details)

Uploaded Python 3

File details

Details for the file stocktrim_openapi_client-0.9.1.tar.gz.

File metadata

  • Download URL: stocktrim_openapi_client-0.9.1.tar.gz
  • Upload date:
  • Size: 351.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for stocktrim_openapi_client-0.9.1.tar.gz
Algorithm Hash digest
SHA256 00408e7b33a7183fa3e78f7a49e2f943a7cc7f250a6a2821cefa1814dd2760eb
MD5 15c24b78973a0415ed44cff2412675a4
BLAKE2b-256 dc807134899847aa56aca14fc1ffbfc37764d2c4be435a1f06bddac9d12a974e

See more details on using hashes here.

Provenance

The following attestation bundles were made for stocktrim_openapi_client-0.9.1.tar.gz:

Publisher: release.yml on dougborg/stocktrim-openapi-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file stocktrim_openapi_client-0.9.1-py3-none-any.whl.

File metadata

File hashes

Hashes for stocktrim_openapi_client-0.9.1-py3-none-any.whl
Algorithm Hash digest
SHA256 01524bfd9af67bd53e9b37e6d81f5385b0b9090da6903e1ba2ea5e1e25a4237f
MD5 32172f3764eb5a0c80ac3ede31bc90fc
BLAKE2b-256 9ca94c37bdce6134c9bf0d00a8581f2e923dc66f5a815302b8501a8952499ee3

See more details on using hashes here.

Provenance

The following attestation bundles were made for stocktrim_openapi_client-0.9.1-py3-none-any.whl:

Publisher: release.yml on dougborg/stocktrim-openapi-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page