LocalParse — Python client
Official Python client for the LocalParse API. LocalParse gives you two products under one API:
- Parse — turn any document into clean Markdown, JSON, or text.
Drop-in LlamaParse-compatible, plus a deterministic accuracy layer:
table-detection recovery (catches tables a layout model misses) and
oracle-free financial-identity checks (flags
Totals that don't reconcile). - Extract (Beta) — pull structured JSON out of parsed documents using your own JSON Schema. Server-side schema validation guarantees the returned object matches.
Install
pip install localparse
Quickstart — Parse
from localparse import LocalParse
client = LocalParse(api_key="lp-...") # or set LOCALPARSE_API_KEY
result = client.parse("invoice.pdf", result_type="markdown")
print(result.markdown)
# Accuracy signal that plain OCR/LLM parsers don't give you:
print(result.identity_check) # {tables_checked, violations, ...} or None
print(result.recovered_tables) # tables recovered by detect_repair
Fetch JSON or the ingestion-ready structured contract instead:
result = client.parse("10k.pdf", result_type="json")
for page in result.pages:
...
structured = client.parse("10k.pdf", result_type="structured")
Quickstart — Extract (Beta)
Parse first to get clean markdown, then extract the fields you actually care about:
md = client.parse("invoice.pdf").markdown
invoice = client.extract(md, {
"type": "object",
"properties": {
"vendor": {"type": "string"},
"invoice_no": {"type": "string"},
"total": {"type": "number"},
"due_on": {"type": "string", "description": "ISO 8601 date"},
},
"required": ["vendor", "total"],
})
print(invoice["vendor"], invoice["total"])
The server validates the model's output against your schema before returning:
a non-conforming response surfaces as SchemaConformanceError rather than as
silently broken data. Pre-flight safety failures (bad schema shape, depth/width
caps, external $ref) surface as SchemaValidationError.
Webhooks (skip polling)
Pass webhook_url and our worker POSTs the result to your endpoint the moment
it's ready — Stripe-shape HMAC-SHA256 signed so you can verify it came from us:
client.submit_extract(
md,
schema,
webhook_url="https://yourapp.com/localparse/webhook",
)
Grab your signing secret from Account → Webhooks in the dashboard (one per account, rotatable), then verify inbound requests with the bundled helper:
from localparse import verify_webhook, InvalidWebhookSignature
@app.post("/localparse/webhook")
def receive(request):
try:
event = verify_webhook(
body = request.body, # raw bytes
signature_header = request.headers["X-LocalParse-Signature"],
secret = os.environ["LOCALPARSE_WEBHOOK_SECRET"],
)
except InvalidWebhookSignature:
return 400
if event["status"] == "SUCCESS":
ingest(event["data"])
else:
log_failure(event["id"], event["error_message"])
return 200
verify_webhook rejects modified bodies, bad signatures, missing headers, and
timestamps older than 5 minutes (replay protection). Webhook URLs must be https
and must not resolve to private/loopback IPs (SSRF guard runs at submit-time).
Retry policy: first attempt is inline, then 10s → 60s → 300s → 1800s (5 total)
before the delivery is marked failed in the Jobs dashboard.
Persist a whole folder (incremental)
Ingest a data room into a named case; re-runs only parse new/changed files (unchanged files are skipped by content hash):
results = client.parse_folder(
"./data-room",
case_id="acme",
resume=True,
on_progress=lambda path, res: print("parsed" if res else "skipped", path),
)
Full control (async jobs)
job = client.upload("big.pdf", result_type="json", case_id="acme")
job = client.wait(job.id)
if job.is_success:
result = client.get_result(job.id, "json")
Configuration
| Argument | Default | Meaning |
|---|---|---|
api_key |
LOCALPARSE_API_KEY env |
Bearer token for the API. |
base_url |
https://api.localparse.com |
Point at a self-hosted instance if needed. |
timeout |
60 |
Per-request HTTP timeout (seconds). |
poll_interval |
2.0 |
Seconds between status polls in parse/wait. |
max_wait |
900 |
Max seconds to wait for a job before JobTimeoutError. |
Errors
AuthenticationError (401/403), QuotaExceededError (402), NotFoundError (404),
RateLimitError (429, with .retry_after), APIError (other non-2xx),
JobFailedError (job ended ERROR/CANCELED), JobTimeoutError,
SchemaValidationError (400 — bad data_schema),
SchemaConformanceError (422 — model output didn't match the schema) —
all subclass LocalParseError.
Metadata
Release files for localparse 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| localparse-0.4.0.tar.gz | 18.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| localparse-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.1 kB
Release files / localparse-0.4.0.tar.gz
| Download URL | localparse-0.4.0.tar.gz |
|---|---|
| Size | 18.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4dac1cdabbee1b406d765696e61feaf278466a0816c0ecec5b537cf3fd73a2b6
|
|
BLAKE2b-256 checksum How to use checksums |
0f57847459ab65b3a2d5f623bd81832d13dfef48fa323ec1de3edd3b699bcba0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / localparse-0.4.0-py3-none-any.whl
| Download URL | localparse-0.4.0-py3-none-any.whl |
|---|---|
| Size | 17.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
517ae4d43440a2a23a1e64e6deb49cc854275a7acd861e7b2fd7f8ebae4d3894
|
|
BLAKE2b-256 checksum How to use checksums |
ba7de0827939c965b6183fe13fccedfb25c42cb0c0b6d642a12795619da3ff97
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|