Python SDK
Official Python SDK for thelawin.dev.
Requires Python 3.9+
Installation
Beta-Phase
Während der Beta sind die SDKs über GitHub verfügbar. PyPI-Veröffentlichung folgt mit dem stabilen Release.
bash
# Via GitHub
pip install git+https://github.com/steviee/thelawin-clients.git#subdirectory=python
# Oder in requirements.txt
thelawin @ git+https://github.com/steviee/thelawin-clients.git#subdirectory=pythonQuick Start
python
from thelawin import ThelawinClient
client = ThelawinClient(api_key="env_sandbox_xxx")
result = (client.invoice()
.number("2026-001")
.date("2026-01-15")
.seller(name="Acme GmbH", vat_id="DE123456789", city="Berlin", country="DE")
.buyer(name="Customer AG", city="München", country="DE")
.add_item(description="Consulting Services", quantity=8, unit="HUR", unit_price=150, vat_rate=19)
.template("minimal")
.generate())
if result.success:
result.save_pdf("./invoice.pdf")
print(f"Generated: {result.filename}")
else:
for error in result.errors:
print(f"{error.path}: {error.message}")Async Support
python
from thelawin import AsyncThelawinClient
async with AsyncThelawinClient(api_key="env_sandbox_xxx") as client:
result = await (client.invoice()
.number("2026-001")
.date("2026-01-15")
.seller(name="Acme GmbH", vat_id="DE123456789", city="Berlin", country="DE")
.buyer(name="Customer AG", city="München", country="DE")
.add_item(description="Consulting", quantity=8, unit="HUR", unit_price=150, vat_rate=19)
.generate())
if result.success:
await result.save_pdf_async("./invoice.pdf")Client Options
python
client = ThelawinClient(
api_key="env_sandbox_xxx",
base_url="https://api.thelawin.dev", # optional
timeout=30.0 # optional, seconds
)Builder API
Invoice Details
python
client.invoice()
.number("2026-001") # Required
.date("2026-01-15") # Required, str or date
.due_date("2026-02-15") # Optional
.currency("EUR") # Default: "EUR"Parties
python
.seller(
name="Acme GmbH", # Required
vat_id="DE123456789", # Required
street="Hauptstraße 1",
city="Berlin", # Required
postal_code="10115",
country="DE" # Required
)
.buyer(
name="Customer AG", # Required
vat_id="DE987654321",
city="München", # Required
country="DE" # Required
)Line Items
python
.add_item(
description="Consulting", # Required
quantity=8, # Required
unit="HUR", # Required
unit_price=150.00, # Required
vat_rate=19.0 # Required
)Customization
python
.template("minimal") # "minimal", "classic", "compact"
.locale("de") # "en", "de", "fr", "es", "it"
.accent_color("#8b5cf6")
.footer_text("Thank you!")Logo
python
# From file (auto Base64)
.logo_file("./logo.png")
.logo_file("./logo.png", width_mm=30)
# From Base64
.logo_base64("iVBORw0KGgo...", width_mm=30)Result Handling
python
result = builder.generate()
if result.success:
print(result.filename) # "invoice-2026-001.pdf"
print(result.validation) # ValidationResult(status="valid", ...)
# Save to file
result.save_pdf("./invoice.pdf")
# Get bytes
pdf_bytes = result.to_bytes()
# Get data URL
data_url = result.to_data_url()
else:
for error in result.errors:
print(f"{error.path}: {error.message}")Error Handling
python
from thelawin import (
ThelawinApiError,
ThelawinNetworkError,
ThelawinQuotaExceededError
)
try:
result = client.invoice().generate()
except ThelawinQuotaExceededError:
print("Quota exceeded, upgrade your plan")
except ThelawinNetworkError as e:
print(f"Network error: {e}")
except ThelawinApiError as e:
print(f"API error {e.status_code}: {e.message}")Type Hints
Full type hints are included for IDE autocomplete:
python
from thelawin import InvoiceResult, InvoiceSuccess, InvoiceFailure, ValidationError
def handle_result(result: InvoiceResult) -> None:
if isinstance(result, InvoiceSuccess):
result.save_pdf("./invoice.pdf")
elif isinstance(result, InvoiceFailure):
for error in result.errors:
print(error.message)Context Manager
python
# Sync
with ThelawinClient(api_key="...") as client:
result = client.invoice().generate()
# Async
async with AsyncThelawinClient(api_key="...") as client:
result = await client.invoice().generate()