Metadata-Version: 2.5
Name: labelixa
Version: 0.3.0
Summary: Render, validate and convert Zebra ZPL label code via the Labelixa API — no printer required.
Project-URL: Homepage, https://labelixa.com
Project-URL: Documentation, https://labelixa.com/docs/api
License-Expression: MIT
License-File: LICENSE
Keywords: barcode,epl,label,printing,thermal-printer,zebra,zpl
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Printing
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24
Description-Content-Type: text/markdown

# labelixa

Render, validate and convert **Zebra ZPL** label code from Python — no
printer required. Thin client for the [Labelixa](https://labelixa.com) API.

```bash
pip install labelixa
```

```python
from labelixa import Client

c = Client()                          # anonymous: free, rate-limited
# c = Client(api_key="lbx_...")       # your quota — https://labelixa.com/panel

zpl = "^XA^FO50,50^A0N,40^FDHello^FS^BY3^FO50,120^BCN,100,Y^FD12345678^FS^XZ"

# See what the label looks like
with open("label.png", "wb") as f:
    f.write(c.render_png(zpl, width_in=4, height_in=6))

# Lint before printing
report = c.validate(zpl)
for d in report["diagnostics"]:
    print(d["severity"], d["mesaj"], d["url"])   # wire field names are stable

# Multi-label PDF, ZPL -> EPL2 translation
pdf = c.render_pdf(zpl)
epl = c.to_epl(zpl)

# 0.2.0: barcode / language detection / printer compatibility
svg = c.barcode("HELLO-123", type="code128")
lang = c.language_detect(raw_label_code)      # confidence TIER, not %
risk = c.compatibility(zpl, "zebra/zd421")    # manufacturer/model; risk report, not "it works"
```

Quota errors are first-class:

```python
from labelixa import QuotaExceeded

try:
    c.render_png(zpl)
except QuotaExceeded as e:
    print(f"retry in {e.retry_after}s (hint: {e.action})")
```

## Reading a response

Response keys are stable wire names and most of them are Turkish; they
never change inside `/v1`. The English name of every key is listed at
<https://labelixa.com/docs/api#response-fields>. A real answer of
`c.validate(zpl)` (`POST /v1/diagnostics`) for a label whose `^FD` field is not
closed (abridged only where marked):

```jsonc
{
  "diagnostics": [
    {
      "code": "ZPL2001",
      "severity": "warning",
      "message_key": "diag.zpl2001",
      "line": 1, "col": 19, "end_line": 1, "end_col": 27,
      "args": { "komut": "^FD" },           // komut: command
      "quickfix": {                          // a one-click fix
        "offset": 26, "end_offset": 26,
        "yeni": "^FS"                        // yeni: replacement text to insert at offset
        // (abridged: also a short English title and its message key)
      },
      // mesaj: message (always English)
      "mesaj": "^FD field data is not terminated with ^FS; real printers may misread the commands that follow",
      "onizleme": { "x": 50, "y": 50 },      // onizleme: preview position, in dots
      "url": "https://labelixa.com/zpl/rules/ZPL2001"
    }
  ],
  "ozet": { "toplam": 1, "error": 0, "warning": 1, "info": 0 },  // ozet: summary, toplam: total
  "alanlar": [{ "line": 1, "x": 50, "y": 50 }],                 // alanlar: fields (each ^FD / ^FV)
  "rfid": []
}
```

An error is a status code plus a body. Render endpoints answer with one
line of plain text (`dpmm must be 6, 8, 12 or 24`); JSON endpoints carry
an English sentence and, where one exists, a stable machine-readable name
in `kod` (code) or `hata_tipi` (error type). When you read the raw body,
branch on that name, never on the sentence. This client raises `LabelixaError` with the status code and the sentence only; the status code is the stable signal it exposes.

```jsonc
// 401 Unauthorized
// WWW-Authenticate: ApiKey realm="labelixa"
{
  // (abridged: the English sentence "Invalid API key", which the client
  //  puts in the exception message)
  "kod": "gecersiz_anahtar"   // kod: code (the key sent belongs to no account)
}
```

When each error happens and how to fix it:
<https://labelixa.com/docs/api#errors>.

The API key is only sent over https (plain `http` is accepted for
`localhost` only; any other `http` base URL with a key raises
`ValueError`), and redirects are never followed, so a server cannot
forward the key to another host.

This SDK is a deliberately thin 1:1 wrapper over the documented REST
API — the [API reference](https://labelixa.com/docs/api) is the source
of truth. AI assistants can also use Labelixa directly over MCP:
point your client at `https://api.labelixa.com/mcp`.
