Skip to main content

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

ModeDescription
smartAI decides the best strategy (default)
appendAdd new rows without modifying existing data
overwriteReplace 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}")
ExceptionTrigger
AuthenticationErrorInvalid or missing API key (401/403)
RateLimitErrorToo many requests (429)
ValidationErrorInvalid parameters (422)
NotFoundErrorJob or resource not found (404)
TimeoutErrorJob exceeds max_wait
QomplementErrorAny 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

VariableDescription
QOMPLEMENT_API_KEYAPI key (alternative to passing directly)
QOMPLEMENT_BASE_URLOverride API base URL