Metadata-Version: 2.4
Name: labelinn
Version: 2.1.0
Summary: Official Python SDK for the LabelInn Cloud Print API. Send labels to Zebra, TSC, and Honeywell thermal printers from any system.
Author-email: LabelInn <support@labelinn.com>
License: MIT
Project-URL: Homepage, https://labelinn.com
Project-URL: Documentation, https://labelinn.com/developers
Project-URL: Repository, https://github.com/labelcraft31/labelinn-python
Project-URL: Issues, https://github.com/labelcraft31/labelinn-python/issues
Project-URL: Changelog, https://github.com/labelcraft31/labelinn-python/blob/main/CHANGELOG.md
Keywords: labelinn,label,printer,zebra,tsc,honeywell,zpl,barcode,thermal,cloud-print,shipping,warehouse,logistics,ecommerce
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Printing
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Hardware
Classifier: Typing :: Typed
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: responses>=0.23.0; extra == "dev"
Dynamic: license-file

# LabelInn Python SDK

[![PyPI version](https://img.shields.io/pypi/v/labelinn.svg)](https://pypi.org/project/labelinn/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![Python](https://img.shields.io/pypi/pyversions/labelinn.svg)](https://pypi.org/project/labelinn/)

Official Python SDK for the [LabelInn](https://labelinn.com) Cloud Print API. Send labels to thermal printers (Zebra, TSC, Honeywell), manage your fleet, and build print automation workflows.

## Installation

```bash
pip install labelinn
```

## Quick Start

```python
from labelinn import LabelInn

# Use a test key for development (no real prints)
client = LabelInn("sk_test_xxxxx")

# Print a ZPL label
job = client.print.create(
    printer_id="prt_abc123",
    payload_type="zpl",
    payload_data="^XA^FO50,50^ADN,36,20^FDHello World^FS^XZ",
)
print(f"Job {job['id']} → {job['status']}")
```

## Authentication

Get your API key from **LabelInn → Settings → API Keys**.

| Key prefix    | Mode    | Description                        |
|---------------|---------|------------------------------------|
| `sk_test_xxx` | Sandbox | No real prints, separate quota     |
| `sk_live_xxx` | Live    | Sends jobs to physical printers    |

```python
# Test mode — safe for development
dev = LabelInn("sk_test_xxxxx")
print(dev.is_test_mode)  # True

# Live mode — real prints
prod = LabelInn("sk_live_xxxxx")
```

## Print Jobs

### Send a ZPL label

```python
job = client.print.create(
    printer_id="prt_abc123",
    payload_type="zpl",
    payload_data="^XA^FO50,50^ADN,36,20^FDShipping Label^FS^XZ",
    copies=2,
    job_name="Order #1234",
)
```

### Send an image label

```python
job = client.print.create(
    printer_id="prt_abc123",
    payload_type="image",
    image_url="https://example.com/labels/shipping.png",
)
```

### Print from a template

```python
job = client.print.create(
    printer_id="prt_abc123",
    payload_type="template",
    design_id="dsg_shipping_v2",
    data={
        "order_id": "ORD-9876",
        "customer": "Ali Yilmaz",
        "barcode": "TR123456789",
    },
)
```

### Idempotency (prevent duplicate prints)

```python
job = client.print.create(
    printer_id="prt_abc123",
    payload_type="zpl",
    payload_data="^XA...^XZ",
    idempotency_key="order-9876-label",
)
# Calling again with the same key returns the original job
```

### List & manage jobs

```python
# List recent jobs
result = client.print.list(limit=10)

# Filter by status
result = client.print.list(status="failed")

# Get job details
job = client.print.get("job_abc123")

# Cancel a queued job
client.print.cancel("job_abc123")

# Reprint with different printer
client.print.reprint("job_abc123", printer_id="prt_backup")
```

## Fleet Management

```python
# List all printers
result = client.fleet.list()

# Filter by status
result = client.fleet.list(status="online")

# Get printer details
printer = client.fleet.get("prt_abc123")

# Quick status check
status = client.fleet.status("prt_abc123")
```

## Designs (Templates)

```python
# List designs
result = client.designs.list()

# Get design with elements
design = client.designs.get("dsg_abc123")

# Get template variables
variables = client.designs.list_variables("dsg_abc123")

# Clone a design
clone = client.designs.clone("dsg_abc123")

# Print directly
client.designs.print(
    "dsg_abc123",
    printer_id="prt_abc123",
    data={"order_id": "ORD-5555", "tracking_number": "TR999"},
    copies=1,
)
```

## Webhooks

```python
# Subscribe to events
webhook = client.webhooks.create(
    url="https://yourapp.com/webhooks/labelinn",
    events=["print.job.completed", "print.job.failed", "printer.status.changed"],
    description="Production monitoring",
)

# Save the signing secret!
print("Secret:", webhook["signing_secret"])

# List subscriptions
result = client.webhooks.list()

# Send a test ping
client.webhooks.test(webhook["id"])

# Unsubscribe
client.webhooks.delete(webhook["id"])
```

### Verifying webhook signatures

```python
from labelinn.webhooks import verify_signature

# In your Flask handler:
@app.route("/webhooks/labelinn", methods=["POST"])
def handle_webhook():
    is_valid = verify_signature(
        payload=request.data.decode(),
        signature=request.headers["X-LabelInn-Signature"],
        secret=WEBHOOK_SECRET,
    )
    if not is_valid:
        return "Invalid signature", 401

    event = request.json
    print(f"Event: {event['event']}")
    return "ok", 200
```

## Data Connect

Data Connect lets you ingest data from any enterprise system (SAP, Oracle, CSV exports, custom APIs) and print labels from it. Supports XML/IDoc, CSV/TSV, and JSON/NDJSON formats with auto-detection.

### Ingest Data

```python
# From a JSON payload
result = client.connect.ingest(
    source_id="src_abc123",
    payload='[{"sku": "A001", "name": "Widget"}, {"sku": "A002", "name": "Gadget"}]',
    format="json",
)
print(f"Ingested {result['records_count']} records")

# From XML/IDoc
result = client.connect.ingest(
    source_id="src_sap",
    payload=xml_string,
    format="xml",
)
```

### Test Parse (Dry Run)

```python
parsed = client.connect.test_parse(payload=csv_string, format="csv")
print(f"Detected {len(parsed['records'])} records")
for field in parsed["schema"]:
    print(f"  {field['path']} ({field['type']})")
```

### Manage Sources

```python
# Create a source
source = client.connect.create_source(name="SAP Orders", format="xml")

# List all sources
sources = client.connect.list_sources()

# Get source details
detail = client.connect.get_source("src_abc123")

# Update a source
client.connect.update_source("src_abc123", name="SAP Orders v2")

# Delete a source
client.connect.delete_source("src_abc123")
```

### Schema & Records

```python
# Get detected schema
schema = client.connect.get_schema("src_abc123")
for field in schema["fields"]:
    print(f"{field['path']} ({field['type']}): {field['sample']}")

# List ingested records
records = client.connect.list_records("src_abc123", limit=50)
```

### Field Mappings

```python
# Get current mappings
mappings = client.connect.get_mappings("src_abc123")

# Update mappings
client.connect.update_mappings("src_abc123", {"sku": "product_code", "name": "product_name"})
```

### Print from Connector

```python
result = client.connect.print(
    source_id="src_abc123",
    design_id="dsg_shipping",
    printer_id="prt_warehouse1",
    copies=1,
)
print(f"Created {result['count']} print jobs")
```

## Rate Limits

Every response includes rate limit info:

```python
result = client.print.list()
print(result["_rate_limit"])
# {"limit": 2000, "remaining": 1847, "reset": 3600}
```

| Plan       | Daily Limit |
|------------|-------------|
| Pro        | 2,000       |
| Enterprise | 50,000      |
| Test keys  | 500 minimum |

When rate-limited, the SDK raises `RateLimitError`:

```python
from labelinn import RateLimitError

try:
    client.print.create(...)
except RateLimitError as e:
    print(f"Rate limited. Retry in {e.retry_after}s")
```

## Error Handling

```python
from labelinn import LabelInnError

try:
    client.print.create(...)
except LabelInnError as e:
    print(f"[{e.status}] {e.code}: {e.message}")
    # e.raw contains the full response body
```

## CLI Tool

The SDK includes a command-line tool:

```bash
# Set your API key
export LABELINN_API_KEY=sk_test_xxxxx

# Verify connectivity
labelinn test

# List printers
labelinn printers

# Print a ZPL label
labelinn print prt_abc123 --zpl "^XA^FO50,50^ADN,36,20^FDHello^FS^XZ"

# Print from a template
labelinn print prt_abc123 --design dsg_shipping --data '{"name": "Ali"}'

# List jobs
labelinn jobs

# --- Data Connect ---
# List connected data sources
labelinn connect sources

# Ingest data from a file
labelinn connect ingest conn_abc123 --file data.csv

# Test-parse a local file
labelinn connect parse --file data.csv --format csv

# Get help
labelinn --help
```

## Configuration

```python
client = LabelInn(
    "sk_test_xxxxx",
    base_url="https://labelinn.com/v1",  # default
    timeout=30,                           # 30s default
)
```

## Requirements

- Python 3.8+
- `requests` (only dependency)

## Contributing

Contributions are welcome! Please open an issue or submit a pull request on [GitHub](https://github.com/ArisHub/labelinn-python).

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/my-feature`)
3. Install dev dependencies: `pip install -e ".[dev]"`
4. Run tests: `pytest`
5. Submit a Pull Request

## Links

- [LabelInn Website](https://labelinn.com)
- [API Documentation](https://labelinn.com/developers)
- [Node.js SDK](https://github.com/ArisHub/labelinn-node)
- [Changelog](./CHANGELOG.md)
- [Report a Bug](https://github.com/ArisHub/labelinn-python/issues)

## License

MIT — see [LICENSE](./LICENSE) for details.
