Skip to main content

hexread

License: MIT

hexread is the official Python client for HexRead - convert PDFs and images to Markdown. It is a thin API client: it talks to the HexRead API at https://api.hexread.com/v1 and never processes documents locally.

API access requires a paid HexRead plan. The free trial is web only, so no API key can be issued for it. Keys are created and revoked in your HexRead dashboard.

Install

pip install hexread

Python 3.10+. The only runtime dependency is httpx.

Quick start

import hexread

res = hexread.convert("report.pdf")  # -> ConvertResult
print(res)                           # str(res) is res.markdown

Use a client when you want metadata, several files, or a custom timeout:

from hexread import HexRead

client = HexRead()  # key from the argument, the environment, or the CLI credential
res = client.convert("report.pdf", progress=True)

print(res.model, res.route_reason, res.pages_remaining)
for page in res.pages:
    print(page.index, page.markdown[:80])

for res in client.convert_many(["a.pdf", "b.png"], max_workers=2):
    print(res)  # str(res) is res.markdown; a failed file yields the exception

print(client.usage().pages_remaining)

AsyncHexRead has the same surface with await:

import asyncio
from hexread import AsyncHexRead

async def main():
    async with AsyncHexRead() as client:
        res = await client.convert("report.pdf")
        print(res.markdown)

asyncio.run(main())

Options

Argument On Meaning
api_key HexRead(...) key for this client; wins over the environment and the CLI credential
base_url HexRead(...) API base URL (default https://api.hexread.com/v1)
timeout HexRead(...) request timeout in seconds
max_retries HexRead(...) retries for the failures a repeat can fix (default 4)
model client and convert() parser to request; auto (the default) lets the server route
lang client and convert() OCR language hint, passed through to the parser
prefer convert() "sync" or "async"; by default the client decides
name convert() the file name to report when you pass bytes or an open file
progress convert(), convert_many() print a progress line while the conversion runs
on_progress convert() callback receiving Progress(phase, pages_done, pages_total, source)
max_workers convert_many() files converted in parallel (default 2)
raise_on_error convert_many() True aborts the batch on the first failure instead of returning it in place

Naming a model requires a plan that allows it; auto is always allowed. client.usage().available_models lists the ones you may request.

The result object

convert() returns a ConvertResult:

Field Type What
markdown str the whole document as Markdown
pages list[Page] one entry per page, in order
pages[i].index int zero-based page index, as returned by the API
pages[i].number int the 1-based page number
pages[i].markdown str that page's Markdown
model str the parser that produced this result
route_reason str why auto picked that parser; empty when you named a model
page_count int pages converted
pages_remaining int | None pages left in the current allowance window
source str the path or name you passed in
job_id str set when the conversion took the async path, otherwise empty
meta Meta pages, sha256, timing_ms, backend, model, route_reason
str(result) str the same string as .markdown

Account meters come from client.usage():

u = client.usage()

u.tier                # your plan
u.pages_used          # pages converted in the current window
u.pages_remaining     # pages left before the cap
u.pages_allowance     # the window's allowance
u.concurrency_limit   # conversions this plan may run at once
u.api_access          # True on a plan that may call the API
u.available_models    # models you may request explicitly
u.resets_at           # when the window rolls over

Credentials

Resolved in this order; the first one found wins.

Order Source
1 api_key= passed to HexRead() or AsyncHexRead()
2 HEXREAD_API_KEY
3 the credential file written by hexread login (hexread/credential in your OS config directory)
Environment variable Meaning
HEXREAD_API_KEY API key for this process (nothing is written to disk)
HEXREAD_BASE_URL API base URL (default https://api.hexread.com/v1; HEXREAD_API is a legacy alias)

Errors

Every exception subclasses HexReadError and carries .message, .status, .type, .code, .request_id and .retry_after. The class is keyed on the API's error type, not the HTTP status.

Exception Raised when
MissingAPIKeyError no credential was found in any of the three sources above
AuthenticationError the key is malformed, revoked, or rejected
PermissionError authenticated but not allowed: plan gate, scope, or a model outside the plan
QuotaError the page allowance for the current period is used up
RateLimitError too many requests; .retry_after holds the wait in seconds
ValidationError the request or the file was rejected
NotFoundError unknown job or endpoint
ConflictError the job is in a conflicting state
GoneError the result is gone (results are not retained)
PayloadTooLargeError the upload exceeds the size limit
CapacityError transient: no capacity right now, retry later
CanceledError the job was canceled
ServerError the API failed

MissingAPIKeyError subclasses AuthenticationError, so one except covers both. hexread.PermissionError shadows the builtin inside from hexread import *; import the module or alias it if that matters to you.

One more class covers a rare case: ResultDeliveryError means a result was fetched but could not be handed back (a disk write failed, say). It carries the text on .markdown, because a result is delivered once and the API cannot serve it again.

Related packages

Package Import Purpose
llama-index-readers-hexread llama_index.readers.hexread LlamaIndex reader
langchain-hexread langchain_hexread LangChain document loader

License

Licensed under the MIT License, © HexWorld Solutions GmbH.

The HexRead service and its documentation live at hexread.com; this repository contains the open-source client only.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hexread-0.1.0.tar.gz (22.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hexread-0.1.0-py3-none-any.whl (28.9 kB view details)

Uploaded Python 3

File details

Details for the file hexread-0.1.0.tar.gz.

File metadata

  • Download URL: hexread-0.1.0.tar.gz
  • Upload date:
  • Size: 22.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hexread-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7544ae7da51fb3c3825d09795f5128d9c6a4438765ab615a5a55ecc7e0ea6b99
MD5 d760e0cf845117b56947f84b5964ff36
BLAKE2b-256 ae1d4721713b12026bd52c04378e26a4ea3c717c801d2913fd54f8e782e9e1f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for hexread-0.1.0.tar.gz:

Publisher: release.yml on HexWorldEU/hexread-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hexread-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: hexread-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 28.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hexread-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8af174af89d53965a488a4a5ab43ecc739efe7c4a13f482dc0cbeeef56682b67
MD5 3f510ed52255b1c92d5b9a7da83fce0f
BLAKE2b-256 b88a0748b061d3809fc6efe05e133ed55f86a8d7eec5ab9740329ac4e2194441

See more details on using hashes here.

Provenance

The following attestation bundles were made for hexread-0.1.0-py3-none-any.whl:

Publisher: release.yml on HexWorldEU/hexread-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page