katana-openapi-client


Namekatana-openapi-client JSON
Version 0.5.1 PyPI version JSON
download
home_pageNone
SummaryA modern, pythonic Katana Manufacturing ERP API client with automatic retries, rate limiting, and smart pagination
upload_time2025-08-09 14:31:13
maintainerDoug Borg
docs_urlNone
authorDoug Borg
requires_python<3.14,>=3.11
licenseMIT
keywords katana manufacturing erp api-client openapi async retry pagination rate-limiting httpx
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Katana Manufacturing ERP - Python API Client

A modern, pythonic Python client for the
[Katana Manufacturing ERP API](https://help.katanamrp.com/api). Built from a
comprehensive OpenAPI 3.1.0 specification with 100% endpoint coverage and automatic
resilience.

[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![Poetry](https://img.shields.io/badge/dependency--management-poetry-blue.svg)](https://python-poetry.org/)
[![OpenAPI 3.1.0](https://img.shields.io/badge/OpenAPI-3.1.0-green.svg)](https://spec.openapis.org/oas/v3.1.0)

## โœจ Features

- **๐ŸŽฏ Production Ready**: Automatic retries, rate limiting, and error handling
- **๐Ÿš€ Zero Configuration**: Works out of the box with environment variables
- **๐Ÿ“ฆ Complete API Coverage**: All 76+ Katana API endpoints with full type hints
- **๐Ÿ”„ Smart Pagination**: Automatic pagination with built-in safety limits
- **๐Ÿ›ก๏ธ Transport-Layer Resilience**: httpx-native approach, no decorators needed
- **โšก Async/Sync Support**: Use with asyncio or traditional synchronous code
- **๐Ÿ” Rich Observability**: Built-in logging and metrics

## ๐Ÿš€ Quick Start

### Installation

```bash
# Clone the repository
git clone https://github.com/dougborg/katana-openapi-client.git
cd katana-openapi-client

# Install with Poetry (recommended)
poetry install

# Or with pip
pip install -e .
```

### ๐Ÿ“‹ Configuration

Create a `.env` file with your Katana API credentials:

```bash
KATANA_API_KEY=your-api-key-here
# Optional: defaults to https://api.katanamrp.com/v1
KATANA_BASE_URL=https://api.katanamrp.com/v1
```

### Basic Usage

#### KatanaClient (Recommended)

The modern, pythonic client with automatic resilience:

```python
import asyncio

from katana_public_api_client import KatanaClient
from katana_public_api_client.generated.api.product import get_all_products
from katana_public_api_client.generated.api.sales_order import get_all_sales_orders

async def main():
    # Automatic configuration from .env file
    async with KatanaClient() as client:
        response = await get_all_products.asyncio_detailed(
            client=client,
            limit=50
        )
        print(f"Status: {response.status_code}")
        print(f"Products: {len(response.parsed.data)}")

        # Automatic pagination happens transparently
        all_products_response = await get_all_products.asyncio_detailed(
            client=client,
            is_sellable=True
        )
        print(f"Total sellable products: {len(all_products_response.parsed.data)}")

        # Direct API usage with automatic resilience
        orders_response = await get_all_sales_orders.asyncio_detailed(
            client=client,
            status="open"
        )
        orders = orders_response.parsed.data if orders_response.parsed else []
        print(f"Open orders: {len(orders)}")

asyncio.run(main())
```

#### Generated Client (Direct)

For maximum control and custom resilience patterns:

```python
import asyncio

from katana_public_api_client import AuthenticatedClient
from katana_public_api_client.generated.api.product import get_all_products

async def main():
    client = AuthenticatedClient(
        base_url="https://api.katanamrp.com/v1",
        token="your-api-key"
    )

    async with client:
        response = await get_all_products.asyncio_detailed(
            client=client,
            limit=50
        )
        if response.status_code == 200:
            products = response.parsed.data
            print(f"Found {len(products)} products")

asyncio.run(main())
```

## ๐Ÿ“Š API Coverage

The client provides access to all major Katana functionality:

| Category                 | Endpoints | Description                                 |
| ------------------------ | --------- | ------------------------------------------- |
| **Products & Inventory** | 25+       | Products, variants, materials, stock levels |
| **Orders**               | 20+       | Sales orders, purchase orders, fulfillment  |
| **Manufacturing**        | 15+       | BOMs, manufacturing orders, operations      |
| **Business Relations**   | 10+       | Customers, suppliers, addresses             |
| **Configuration**        | 6+        | Locations, webhooks, custom fields          |

**Total**: 76+ endpoints with 150+ fully-typed data models.

## ๐ŸŽฏ Why KatanaClient?

### Automatic Resilience

Every API call through `KatanaClient` automatically includes:

- **Smart Retries**: Exponential backoff for network errors and 5xx responses
- **Rate Limit Handling**: Automatic retry with `Retry-After` header support
- **Error Recovery**: Intelligent retry logic that doesn't retry 4xx client errors
- **Observability**: Rich logging for debugging and monitoring

### Pythonic Design

```python
# No decorators, no wrapper methods needed
async with KatanaClient() as client:
    # Just use the generated API methods directly
    response = await get_all_products.asyncio_detailed(
        client=client,
        limit=100
    )
    # Automatic retries, rate limiting, logging - all transparent!
```

### Transport-Layer Architecture

Uses httpx's native transport layer for resilience - the most pythonic approach:

- **Zero Dependencies**: Built on httpx's standard extension points
- **Maximum Compatibility**: Works with any httpx-based code
- **Easy Testing**: Simple to mock and test
- **Performance**: Minimal overhead compared to decorators

## ๐Ÿ”ง Advanced Usage

### Custom Configuration

```python
import logging

from katana_public_api_client import KatanaClient

# Custom configuration
async with KatanaClient(
    api_key="custom-key",
    base_url="https://custom.katana.com/v1",
    timeout=60.0,
    max_retries=3,
    logger=logging.getLogger("katana")
) as client:
    # Your API calls here
    pass
```

### Automatic Pagination

```python
from katana_public_api_client import KatanaClient
from katana_public_api_client.generated.api.product import get_all_products

async with KatanaClient() as client:
    # Get all products with automatic pagination
    all_products_response = await get_all_products.asyncio_detailed(
        client=client,
        is_sellable=True
    )
    sellable_products = all_products_response.parsed.data
    print(f"Found {len(sellable_products)} sellable products")
```

### Direct API Usage

```python
from katana_public_api_client import KatanaClient
from katana_public_api_client.generated.api.inventory import get_all_inventory_points
from katana_public_api_client.generated.api.manufacturing_order import get_all_manufacturing_orders
from katana_public_api_client.generated.api.product import get_all_products, get_product
from katana_public_api_client.generated.api.sales_order import get_all_sales_orders, get_sales_order

async with KatanaClient() as client:
    # Direct API methods with automatic pagination and resilience
    products = await get_all_products.asyncio_detailed(
        client=client, is_sellable=True
    )
    orders = await get_all_sales_orders.asyncio_detailed(
        client=client, status="open"
    )
    inventory = await get_all_inventory_points.asyncio_detailed(
        client=client
    )
    manufacturing = await get_all_manufacturing_orders.asyncio_detailed(
        client=client, status="planned"
    )

    # Individual item lookup
    product = await get_product.asyncio_detailed(
        client=client, id=123
    )
    order = await get_sales_order.asyncio_detailed(
        client=client, id=456
    )
```

## ๏ฟฝ Project Structure

```text
katana-openapi-client/
โ”œโ”€โ”€ katana-openapi.yaml          # OpenAPI 3.1.0 specification
โ”œโ”€โ”€ katana_public_api_client/    # Generated Python client
โ”‚   โ”œโ”€โ”€ katana_client.py         # KatanaClient with transport-layer resilience
โ”‚   โ”œโ”€โ”€ client.py                # Base generated client classes
โ”‚   โ”œโ”€โ”€ api/                     # 76+ API endpoint modules
โ”‚   โ”œโ”€โ”€ models/                  # 150+ data models
โ”‚   โ””โ”€โ”€ types.py                 # Type definitions
โ”œโ”€โ”€ docs/                        # Documentation
โ”œโ”€โ”€ tests/                       # Test suite
โ””โ”€โ”€ scripts/                     # Development utilities
```

## ๐Ÿงช Testing

```bash
# Run all tests
poetry run poe test

# Run with coverage
poetry run poe test-coverage

# Run specific test categories
poetry run poe test-unit           # Unit tests only
poetry run poe test-integration    # Integration tests only
```

## ๐Ÿ“š Documentation

- [**KatanaClient Guide**](docs/KATANA_CLIENT_GUIDE.md) - Complete KatanaClient usage
  guide
- [**API Reference**](docs/API_REFERENCE.md) - Generated API documentation
- [**Migration Guide**](docs/MIGRATION_GUIDE.md) - Upgrading from previous versions
- [**Testing Guide**](docs/TESTING_GUIDE.md) - Testing patterns and examples

## ๐Ÿ”„ Development

### Quick Start

```bash
# Install dependencies
poetry install

# Install pre-commit hooks (important!)
poetry run poe pre-commit-install

# See all available tasks
poetry run poe help

# Quick development check
poetry run poe check

# Auto-fix common issues
poetry run poe fix
```

## ๐Ÿ”„ Development Workflow

### Development Setup

```bash
# Install dependencies
poetry install

# Install pre-commit hooks (important!)
poetry run poe pre-commit-install

# See all available tasks
poetry run poe help

# Quick development check
poetry run poe check

# Auto-fix common issues
poetry run poe fix
```

### Code Quality Tasks

```bash
# Formatting
poetry run poe format              # Format all code and documentation
poetry run poe format-check        # Check formatting without changes
poetry run poe format-python       # Format Python code only

# Linting and Type Checking
poetry run poe lint                 # Run all linters (ruff, mypy, yaml)
poetry run poe lint-ruff           # Fast linting with ruff
poetry run poe lint-mypy           # Type checking with mypy

# Testing
poetry run poe test                 # Run all tests
poetry run poe test-coverage       # Run tests with coverage
poetry run poe test-unit           # Unit tests only
poetry run poe test-integration    # Integration tests only
```

### OpenAPI and Client Generation

```bash
# Regenerate client from OpenAPI spec
poetry run poe regenerate-client

# Validate OpenAPI specification
poetry run poe validate-openapi

# Full preparation workflow
poetry run poe prepare             # Format + lint + test + validate
```

### Pre-commit Hooks

```bash
# Install pre-commit hooks (run once after clone)
poetry run poe pre-commit-install

# Run pre-commit on all files manually
poetry run poe pre-commit-run

# Update pre-commit hook versions
poetry run poe pre-commit-update
```

### CI/Development Workflows

```bash
# Full CI pipeline (what runs in GitHub Actions)
poetry run poe ci

# Pre-commit preparation
poetry run poe prepare

# Clean build artifacts
poetry run poe clean
```

## Configuration

All tool configurations are consolidated in `pyproject.toml` following modern Python
packaging standards:

- **Poetry**: Package metadata and dependencies
- **Ruff**: Code formatting and linting (replaces Black, isort, flake8)
- **MyPy**: Type checking configuration
- **Pytest**: Test discovery and execution settings
- **Coverage**: Code coverage reporting
- **Poe**: Task automation and scripts
- **Semantic Release**: Automated versioning and releases

## ๐Ÿ“ License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for
details.

## ๐Ÿค Contributing

Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for
details on our code of conduct and the process for submitting pull requests.


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "katana-openapi-client",
    "maintainer": "Doug Borg",
    "docs_url": null,
    "requires_python": "<3.14,>=3.11",
    "maintainer_email": "dougborg@dougborg.org",
    "keywords": "katana, manufacturing, erp, api-client, openapi, async, retry, pagination, rate-limiting, httpx",
    "author": "Doug Borg",
    "author_email": "dougborg@dougborg.org",
    "download_url": "https://files.pythonhosted.org/packages/cb/74/702921127b16cca9888f702b1ae478040a769e02d580a690573775f02fdd/katana_openapi_client-0.5.1.tar.gz",
    "platform": null,
    "description": "# Katana Manufacturing ERP - Python API Client\n\nA modern, pythonic Python client for the\n[Katana Manufacturing ERP API](https://help.katanamrp.com/api). Built from a\ncomprehensive OpenAPI 3.1.0 specification with 100% endpoint coverage and automatic\nresilience.\n\n[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)\n[![Poetry](https://img.shields.io/badge/dependency--management-poetry-blue.svg)](https://python-poetry.org/)\n[![OpenAPI 3.1.0](https://img.shields.io/badge/OpenAPI-3.1.0-green.svg)](https://spec.openapis.org/oas/v3.1.0)\n\n## \u2728 Features\n\n- **\ud83c\udfaf Production Ready**: Automatic retries, rate limiting, and error handling\n- **\ud83d\ude80 Zero Configuration**: Works out of the box with environment variables\n- **\ud83d\udce6 Complete API Coverage**: All 76+ Katana API endpoints with full type hints\n- **\ud83d\udd04 Smart Pagination**: Automatic pagination with built-in safety limits\n- **\ud83d\udee1\ufe0f Transport-Layer Resilience**: httpx-native approach, no decorators needed\n- **\u26a1 Async/Sync Support**: Use with asyncio or traditional synchronous code\n- **\ud83d\udd0d Rich Observability**: Built-in logging and metrics\n\n## \ud83d\ude80 Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/dougborg/katana-openapi-client.git\ncd katana-openapi-client\n\n# Install with Poetry (recommended)\npoetry install\n\n# Or with pip\npip install -e .\n```\n\n### \ud83d\udccb Configuration\n\nCreate a `.env` file with your Katana API credentials:\n\n```bash\nKATANA_API_KEY=your-api-key-here\n# Optional: defaults to https://api.katanamrp.com/v1\nKATANA_BASE_URL=https://api.katanamrp.com/v1\n```\n\n### Basic Usage\n\n#### KatanaClient (Recommended)\n\nThe modern, pythonic client with automatic resilience:\n\n```python\nimport asyncio\n\nfrom katana_public_api_client import KatanaClient\nfrom katana_public_api_client.generated.api.product import get_all_products\nfrom katana_public_api_client.generated.api.sales_order import get_all_sales_orders\n\nasync def main():\n    # Automatic configuration from .env file\n    async with KatanaClient() as client:\n        response = await get_all_products.asyncio_detailed(\n            client=client,\n            limit=50\n        )\n        print(f\"Status: {response.status_code}\")\n        print(f\"Products: {len(response.parsed.data)}\")\n\n        # Automatic pagination happens transparently\n        all_products_response = await get_all_products.asyncio_detailed(\n            client=client,\n            is_sellable=True\n        )\n        print(f\"Total sellable products: {len(all_products_response.parsed.data)}\")\n\n        # Direct API usage with automatic resilience\n        orders_response = await get_all_sales_orders.asyncio_detailed(\n            client=client,\n            status=\"open\"\n        )\n        orders = orders_response.parsed.data if orders_response.parsed else []\n        print(f\"Open orders: {len(orders)}\")\n\nasyncio.run(main())\n```\n\n#### Generated Client (Direct)\n\nFor maximum control and custom resilience patterns:\n\n```python\nimport asyncio\n\nfrom katana_public_api_client import AuthenticatedClient\nfrom katana_public_api_client.generated.api.product import get_all_products\n\nasync def main():\n    client = AuthenticatedClient(\n        base_url=\"https://api.katanamrp.com/v1\",\n        token=\"your-api-key\"\n    )\n\n    async with client:\n        response = await get_all_products.asyncio_detailed(\n            client=client,\n            limit=50\n        )\n        if response.status_code == 200:\n            products = response.parsed.data\n            print(f\"Found {len(products)} products\")\n\nasyncio.run(main())\n```\n\n## \ud83d\udcca API Coverage\n\nThe client provides access to all major Katana functionality:\n\n| Category                 | Endpoints | Description                                 |\n| ------------------------ | --------- | ------------------------------------------- |\n| **Products & Inventory** | 25+       | Products, variants, materials, stock levels |\n| **Orders**               | 20+       | Sales orders, purchase orders, fulfillment  |\n| **Manufacturing**        | 15+       | BOMs, manufacturing orders, operations      |\n| **Business Relations**   | 10+       | Customers, suppliers, addresses             |\n| **Configuration**        | 6+        | Locations, webhooks, custom fields          |\n\n**Total**: 76+ endpoints with 150+ fully-typed data models.\n\n## \ud83c\udfaf Why KatanaClient?\n\n### Automatic Resilience\n\nEvery API call through `KatanaClient` automatically includes:\n\n- **Smart Retries**: Exponential backoff for network errors and 5xx responses\n- **Rate Limit Handling**: Automatic retry with `Retry-After` header support\n- **Error Recovery**: Intelligent retry logic that doesn't retry 4xx client errors\n- **Observability**: Rich logging for debugging and monitoring\n\n### Pythonic Design\n\n```python\n# No decorators, no wrapper methods needed\nasync with KatanaClient() as client:\n    # Just use the generated API methods directly\n    response = await get_all_products.asyncio_detailed(\n        client=client,\n        limit=100\n    )\n    # Automatic retries, rate limiting, logging - all transparent!\n```\n\n### Transport-Layer Architecture\n\nUses httpx's native transport layer for resilience - the most pythonic approach:\n\n- **Zero Dependencies**: Built on httpx's standard extension points\n- **Maximum Compatibility**: Works with any httpx-based code\n- **Easy Testing**: Simple to mock and test\n- **Performance**: Minimal overhead compared to decorators\n\n## \ud83d\udd27 Advanced Usage\n\n### Custom Configuration\n\n```python\nimport logging\n\nfrom katana_public_api_client import KatanaClient\n\n# Custom configuration\nasync with KatanaClient(\n    api_key=\"custom-key\",\n    base_url=\"https://custom.katana.com/v1\",\n    timeout=60.0,\n    max_retries=3,\n    logger=logging.getLogger(\"katana\")\n) as client:\n    # Your API calls here\n    pass\n```\n\n### Automatic Pagination\n\n```python\nfrom katana_public_api_client import KatanaClient\nfrom katana_public_api_client.generated.api.product import get_all_products\n\nasync with KatanaClient() as client:\n    # Get all products with automatic pagination\n    all_products_response = await get_all_products.asyncio_detailed(\n        client=client,\n        is_sellable=True\n    )\n    sellable_products = all_products_response.parsed.data\n    print(f\"Found {len(sellable_products)} sellable products\")\n```\n\n### Direct API Usage\n\n```python\nfrom katana_public_api_client import KatanaClient\nfrom katana_public_api_client.generated.api.inventory import get_all_inventory_points\nfrom katana_public_api_client.generated.api.manufacturing_order import get_all_manufacturing_orders\nfrom katana_public_api_client.generated.api.product import get_all_products, get_product\nfrom katana_public_api_client.generated.api.sales_order import get_all_sales_orders, get_sales_order\n\nasync with KatanaClient() as client:\n    # Direct API methods with automatic pagination and resilience\n    products = await get_all_products.asyncio_detailed(\n        client=client, is_sellable=True\n    )\n    orders = await get_all_sales_orders.asyncio_detailed(\n        client=client, status=\"open\"\n    )\n    inventory = await get_all_inventory_points.asyncio_detailed(\n        client=client\n    )\n    manufacturing = await get_all_manufacturing_orders.asyncio_detailed(\n        client=client, status=\"planned\"\n    )\n\n    # Individual item lookup\n    product = await get_product.asyncio_detailed(\n        client=client, id=123\n    )\n    order = await get_sales_order.asyncio_detailed(\n        client=client, id=456\n    )\n```\n\n## \ufffd Project Structure\n\n```text\nkatana-openapi-client/\n\u251c\u2500\u2500 katana-openapi.yaml          # OpenAPI 3.1.0 specification\n\u251c\u2500\u2500 katana_public_api_client/    # Generated Python client\n\u2502   \u251c\u2500\u2500 katana_client.py         # KatanaClient with transport-layer resilience\n\u2502   \u251c\u2500\u2500 client.py                # Base generated client classes\n\u2502   \u251c\u2500\u2500 api/                     # 76+ API endpoint modules\n\u2502   \u251c\u2500\u2500 models/                  # 150+ data models\n\u2502   \u2514\u2500\u2500 types.py                 # Type definitions\n\u251c\u2500\u2500 docs/                        # Documentation\n\u251c\u2500\u2500 tests/                       # Test suite\n\u2514\u2500\u2500 scripts/                     # Development utilities\n```\n\n## \ud83e\uddea Testing\n\n```bash\n# Run all tests\npoetry run poe test\n\n# Run with coverage\npoetry run poe test-coverage\n\n# Run specific test categories\npoetry run poe test-unit           # Unit tests only\npoetry run poe test-integration    # Integration tests only\n```\n\n## \ud83d\udcda Documentation\n\n- [**KatanaClient Guide**](docs/KATANA_CLIENT_GUIDE.md) - Complete KatanaClient usage\n  guide\n- [**API Reference**](docs/API_REFERENCE.md) - Generated API documentation\n- [**Migration Guide**](docs/MIGRATION_GUIDE.md) - Upgrading from previous versions\n- [**Testing Guide**](docs/TESTING_GUIDE.md) - Testing patterns and examples\n\n## \ud83d\udd04 Development\n\n### Quick Start\n\n```bash\n# Install dependencies\npoetry install\n\n# Install pre-commit hooks (important!)\npoetry run poe pre-commit-install\n\n# See all available tasks\npoetry run poe help\n\n# Quick development check\npoetry run poe check\n\n# Auto-fix common issues\npoetry run poe fix\n```\n\n## \ud83d\udd04 Development Workflow\n\n### Development Setup\n\n```bash\n# Install dependencies\npoetry install\n\n# Install pre-commit hooks (important!)\npoetry run poe pre-commit-install\n\n# See all available tasks\npoetry run poe help\n\n# Quick development check\npoetry run poe check\n\n# Auto-fix common issues\npoetry run poe fix\n```\n\n### Code Quality Tasks\n\n```bash\n# Formatting\npoetry run poe format              # Format all code and documentation\npoetry run poe format-check        # Check formatting without changes\npoetry run poe format-python       # Format Python code only\n\n# Linting and Type Checking\npoetry run poe lint                 # Run all linters (ruff, mypy, yaml)\npoetry run poe lint-ruff           # Fast linting with ruff\npoetry run poe lint-mypy           # Type checking with mypy\n\n# Testing\npoetry run poe test                 # Run all tests\npoetry run poe test-coverage       # Run tests with coverage\npoetry run poe test-unit           # Unit tests only\npoetry run poe test-integration    # Integration tests only\n```\n\n### OpenAPI and Client Generation\n\n```bash\n# Regenerate client from OpenAPI spec\npoetry run poe regenerate-client\n\n# Validate OpenAPI specification\npoetry run poe validate-openapi\n\n# Full preparation workflow\npoetry run poe prepare             # Format + lint + test + validate\n```\n\n### Pre-commit Hooks\n\n```bash\n# Install pre-commit hooks (run once after clone)\npoetry run poe pre-commit-install\n\n# Run pre-commit on all files manually\npoetry run poe pre-commit-run\n\n# Update pre-commit hook versions\npoetry run poe pre-commit-update\n```\n\n### CI/Development Workflows\n\n```bash\n# Full CI pipeline (what runs in GitHub Actions)\npoetry run poe ci\n\n# Pre-commit preparation\npoetry run poe prepare\n\n# Clean build artifacts\npoetry run poe clean\n```\n\n## Configuration\n\nAll tool configurations are consolidated in `pyproject.toml` following modern Python\npackaging standards:\n\n- **Poetry**: Package metadata and dependencies\n- **Ruff**: Code formatting and linting (replaces Black, isort, flake8)\n- **MyPy**: Type checking configuration\n- **Pytest**: Test discovery and execution settings\n- **Coverage**: Code coverage reporting\n- **Poe**: Task automation and scripts\n- **Semantic Release**: Automated versioning and releases\n\n## \ud83d\udcdd License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for\ndetails.\n\n## \ud83e\udd1d Contributing\n\nContributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for\ndetails on our code of conduct and the process for submitting pull requests.\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A modern, pythonic Katana Manufacturing ERP API client with automatic retries, rate limiting, and smart pagination",
    "version": "0.5.1",
    "project_urls": {
        "Bug Tracker": "https://github.com/dougborg/katana-openapi-client/issues",
        "Changelog": "https://github.com/dougborg/katana-openapi-client/blob/main/docs/CHANGELOG.md",
        "Documentation": "https://dougborg.github.io/katana-openapi-client/",
        "Homepage": "https://github.com/dougborg/katana-openapi-client",
        "Repository": "https://github.com/dougborg/katana-openapi-client"
    },
    "split_keywords": [
        "katana",
        " manufacturing",
        " erp",
        " api-client",
        " openapi",
        " async",
        " retry",
        " pagination",
        " rate-limiting",
        " httpx"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "e028ae3cec48635c9c745f0f910b6b45498a1b9dbecfca694aa81fdfe51e1551",
                "md5": "135803717c217421460004d30656f199",
                "sha256": "07a5e21cc080986af067ea8955e584053964d0f68ae385a2ab9bd313e2a7e36e"
            },
            "downloads": -1,
            "filename": "katana_openapi_client-0.5.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "135803717c217421460004d30656f199",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<3.14,>=3.11",
            "size": 485879,
            "upload_time": "2025-08-09T14:31:12",
            "upload_time_iso_8601": "2025-08-09T14:31:12.025905Z",
            "url": "https://files.pythonhosted.org/packages/e0/28/ae3cec48635c9c745f0f910b6b45498a1b9dbecfca694aa81fdfe51e1551/katana_openapi_client-0.5.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "cb74702921127b16cca9888f702b1ae478040a769e02d580a690573775f02fdd",
                "md5": "69d8628b157574814d3bba4db8edf2bf",
                "sha256": "7aea88b75f67a33aa3d22e468536dff5a77896905f8535a179dbc012be5e2820"
            },
            "downloads": -1,
            "filename": "katana_openapi_client-0.5.1.tar.gz",
            "has_sig": false,
            "md5_digest": "69d8628b157574814d3bba4db8edf2bf",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<3.14,>=3.11",
            "size": 180443,
            "upload_time": "2025-08-09T14:31:13",
            "upload_time_iso_8601": "2025-08-09T14:31:13.655292Z",
            "url": "https://files.pythonhosted.org/packages/cb/74/702921127b16cca9888f702b1ae478040a769e02d580a690573775f02fdd/katana_openapi_client-0.5.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-09 14:31:13",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "dougborg",
    "github_project": "katana-openapi-client",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "katana-openapi-client"
}
        
Elapsed time: 1.60421s