Python SDK
Official Python client for the qomplement API.
pip install qomplement
Source: github.com/Qomplement/qomplement-python Requires: Python 3.8+
Quick Start
from qomplement import Qomplement
client = Qomplement("sd_your_api_key")
result = client.extract("invoice.pdf")
print(result.fields) # {'invoice_number': '12345', 'total': '1500.50'}
print(result.document_type) # 'invoice'
print(result.confidence) # 94
Authentication
Pass your API key directly or set the QOMPLEMENT_API_KEY environment variable:
# Option 1: Direct
client = Qomplement("sd_your_api_key")
# Option 2: Environment variable
import os
os.environ["QOMPLEMENT_API_KEY"] = "sd_your_api_key"
client = Qomplement()
Get your API key at developers.qomplement.com/keys.
Extract
Extract structured data from any document (PDF, DOCX, XLSX, images, and 30+ formats).
result = client.extract("invoice.pdf")
print(result.fields) # Extracted key-value pairs
print(result.tables) # Tables found in document
print(result.document_type) # Detected document type
print(result.language) # Detected language
print(result.confidence) # 0-100 confidence score
print(result.pages_processed) # Number of pages
print(result.processing_time_ms)
Options
# Use High Precision model
result = client.extract("complex_doc.pdf", model="qomplement-OCR-XL-v1")
# Guided extraction with schema
result = client.extract("invoice.pdf", schema=[
{"name": "invoice_number", "type": "string"},
{"name": "total_amount", "type": "number"},
{"name": "date", "type": "date"},
])
# Get full AI detail (entities, summary)
result = client.extract("report.pdf", detail=True)
print(result.detail["entities"])
print(result.detail["summary"])
# Split into text chunks
result = client.extract("long_doc.pdf", chunk_size=1000, chunk_overlap=200)
for chunk in result.chunks:
print(chunk["text"])
# CSV or XML output
result = client.extract("invoice.pdf", output_format="csv")
Extract from bytes or file objects
# From bytes
with open("document.pdf", "rb") as f:
result = client.extract(f.read(), filename="document.pdf")
# From file object
with open("document.pdf", "rb") as f:
result = client.extract(f)
Fill PDF
Fill PDF forms using source documents, natural language instructions, or explicit mappings.
From a source document
result = client.fill_pdf(
"form.pdf",
source="invoice.pdf",
)
result.save("filled_form.pdf")
print(f"Filled {result.fields_filled}/{result.fields_total} fields")
With natural language instructions
result = client.fill_pdf(
"contract.pdf",
instructions="Fill client name as 'Acme Corporation' and date as January 15, 2026",
)
result.save("filled_contract.pdf")
With explicit field mappings
result = client.fill_pdf(
"form.pdf",
field_mappings={
"client_name": "Acme Corp",
"invoice_date": "2026-01-15",
"total": "1500.50",
},
)
result.save("filled_form.pdf")
Field details
for field in result.field_details:
print(f"{field.field_name}: {field.value} (confidence: {field.confidence})")
Fill Excel
Fill Excel templates using source documents or instructions.
# From source document
result = client.fill_excel(
"template.xlsx",
source="invoice.pdf",
)
result.save("filled_template.xlsx")
print(f"Wrote {result.cells_written} cells in {result.sheets_modified}")
# With instructions
result = client.fill_excel(
"template.xlsx",
instructions="Add company name as Acme Corp in the header, total as $1500",
)
result.save("filled.xlsx")
Fill modes
| Mode | Description |
|---|---|
smart | AI decides the best strategy (default) |
append | Add new rows without modifying existing data |
overwrite | Replace existing cell values |
result = client.fill_excel(
"template.xlsx",
source="invoice.pdf",
fill_mode="append",
)
Async Jobs
Large documents (>5 pages) are processed asynchronously. By default, the SDK waits for completion. Set wait=False to return immediately:
# Non-blocking
job = client.extract("large_document.pdf", wait=False)
print(job.id) # Job ID
print(job.status) # 'processing'
# Check later
job = client.get_job(job.id)
if job.status == "completed":
print(job.result)
# List your jobs
jobs = client.list_jobs(status="completed", type="extract", limit=10)
for j in jobs:
print(f"{j.id}: {j.type} — {j.status}")
# Download filled files
file_bytes = client.download(job.id)
with open("output.pdf", "wb") as f:
f.write(file_bytes)
Usage & Info
# Current month usage
usage = client.usage()
print(f"Requests: {usage.requests}")
print(f"Pages: {usage.pages_processed}")
print(f"PDFs filled: {usage.pdfs_filled}")
# Specific month
usage = client.usage(period="2026-02")
# Available models
models = client.models()
for m in models:
print(f"{m['id']}: {m['description']}")
# Supported formats (33+)
formats = client.formats()
print(formats["total_formats"])
Error Handling
from qomplement import (
Qomplement,
AuthenticationError,
RateLimitError,
ValidationError,
NotFoundError,
TimeoutError,
QomplementError,
)
client = Qomplement("sd_your_api_key")
try:
result = client.extract("document.pdf")
except AuthenticationError:
print("Invalid API key")
except RateLimitError as e:
print(f"Rate limited — retry after {e.retry_after}s")
except ValidationError as e:
print(f"Bad request: {e}")
except NotFoundError:
print("Resource not found")
except TimeoutError:
print("Job took too long")
except QomplementError as e:
print(f"API error {e.status_code}: {e}")
| Exception | Trigger |
|---|---|
AuthenticationError | Invalid or missing API key (401/403) |
RateLimitError | Too many requests (429) |
ValidationError | Invalid parameters (422) |
NotFoundError | Job or resource not found (404) |
TimeoutError | Job exceeds max_wait |
QomplementError | Any other API error |
Configuration
client = Qomplement(
"sd_your_api_key",
timeout=120, # Request timeout in seconds (default: 300)
max_wait=300, # Max async job wait in seconds (default: 600)
)
Environment variables
| Variable | Description |
|---|---|
QOMPLEMENT_API_KEY | API key (alternative to passing directly) |
QOMPLEMENT_BASE_URL | Override API base URL |