Skip to main content

estravon-backend-benchmarks

Prerequisite: you need estravon-backend installed and reachable with the engines you want to compare configured – MinerU installed locally (pip install "estravon-backend[mineru]"), and/or MISTRAL_API_KEY / DATALAB_API_KEY / REPLICATE_API_TOKEN set as environment variables in the shell/process that calls compare() – e.g. export MISTRAL_API_KEY=... before running your script, or os.environ["MISTRAL_API_KEY"] = ... before calling compare(). This package orchestrates estravon-backend; it never extracts anything on its own, and it never reads or passes engine credentials itself – see “A note on API keys” below for exactly how they reach the engine. See estravon-backend’s docs/API.md for the engine-decision table and how to get each engine’s key.

Picking up the .env file from estravon-backend’s own setup: estravon-backend’s README has you create a .env file (e.g. MISTRAL_API_KEY=your_key_here) in that repo’s root, and estravon loads it automatically – but only from its own process’s current working directory at startup. This package spawns estravon as a subprocess from wherever your notebook’s kernel happens to be running, which usually isn’t that directory – so the reliable way to make the same key visible here is to load that .env explicitly, once, before calling compare():

from pathlib import Path
from dotenv import load_dotenv

load_dotenv(Path("~/path/to/estravon-backend/.env").expanduser())

python-dotenv ships as a dependency of estravon-backend itself, so if you’ve already installed that (this package’s own prerequisite, above), it’s already available – no separate install. .expanduser() resolves ~ portably on Linux/macOS/Windows; for a literal $HOME-style variable instead, use os.path.expandvars(...). Once loaded, the variables are in your notebook process’s own environment, and LocalEngineProcess (Mode A) inherits them when it spawns estravon – it doesn’t matter what that subprocess’s own working directory ends up being.

Install

!pip install estravon-backend-benchmarks

Also installable via git, e.g. for the latest unreleased commit on main, or for contributing (editing a notebook under nbs/):

pip install git+https://github.com/tiberavonltd/estravon-backend-benchmarks.git

To contribute, clone and install in dev mode instead:

git clone https://github.com/tiberavonltd/estravon-backend-benchmarks.git
cd estravon-backend-benchmarks
pip install -e ".[dev]"
nbdev-install-hooks   # keeps notebook diffs clean on commit

See CONTRIBUTING.md for the edit-notebook -> nbdev-export -> nbdev-test loop (nbdev 3.x only ships hyphenated console scripts – nbdev_install_hooks with an underscore will not be found).

Quickstart

compare() has two modes (see estravon-backend’s docs/API.md section “Engine selection” for why there’s no single-URL multi-engine mode – engine choice is fixed per running instance, on purpose):

  • Mode A (below, the common case): pass engines=[...] and this package spawns one pinned estravon --backend <engine> --port <N> subprocess per engine for you – nothing to configure beyond having estravon-backend installed with the relevant keys/local models available.
  • Mode B: pass engine_urls={"mistral": "http://host:port", ...} instead, if you already have separately-running single-engine instances.

A note on API keys – two different things share the name “api_key”:

  • Engine credentials (MISTRAL_API_KEY, DATALAB_API_KEY, REPLICATE_API_TOKEN) are read by estravon-backend itself from the environment – this package never touches them. In Mode A, LocalEngineProcess spawns estravon --backend <engine> ... as a plain subprocess that inherits your calling process’s environment, so setting them before you call compare() is enough; there’s no parameter for them here because there doesn’t need to be one.
  • compare()’s own api_key= parameter is a different thing entirely: it’s only used in Mode B, forwarded as the X-API-Key header to authenticate to a hosted estravon-backend instance (the same header the hosted service’s own billing/auth uses) – it has nothing to do with which engine that instance runs. In Mode A it’s hardcoded to None: locally spawned instances have no such auth layer.

The cell below is marked non-executing in this rendered copy of the notebook (no backend/engines are available in the environment that builds these docs) – otherwise it’s exactly what you’d run locally, unmodified: it uses get_artusi() (a real, public-domain 1891 cookbook PDF, downloaded and cached on first call – see estravon_bench.io) instead of a placeholder path, so there’s nothing to swap in before trying it.

from estravon_bench.compare import compare
from estravon_bench.io import get_artusi

result = compare(
    pdf_path=str(get_artusi()),   # public-domain 1891 cookbook -- downloaded/cached on first call
    page_range="1-4",
    engines=["mineru", "mistral"],   # whichever engines you have configured
    mode="balanced",
)
print(result.to_markdown_table())

This prints a side-by-side table:

| engine | time (s) | cost (usd) | local | pages | status |
|---|---|---|---|---|---|
| mineru | 34.10 | free (local) | yes | 4 | ok |
| mistral | 2.30 | $0.0080 | no | 4 | ok |

Then look at each engine’s actual output:

for r in result:
    print(f"--- {r.engine} ---")
    print(r.markdown[:500] if r.ok else f"ERROR: {r.error}")

print(result.diff("mineru", "mistral"))   # optional -- line diff for eyeballing

⚠️ The two-step fetch is handled for youClient.fetch_markdown() already does the md_url → actual text round trip described in estravon-backend’s docs/API.md. If you’re extending client.py yourself, that’s the detail to know about; compare()’s own callers never see a bare URL.

Honest-cost labelling: local=True engines (MinerU today) show cost_usd=0.0 and the table renders “free (local)” – that means zero dollars, not zero effort or best value. A free engine that’s ten times slower is not automatically the right choice.

Scope: this is an evaluation aid for comparing engines on your own PDFs apples-to-apples – not a production layer, and not a leaderboard. It compares your PDF on your configured engines; it makes no claim about which engine is best in general.

Images

Engines that extract images (Datalab and Mistral, real-verified; any future engine automatically once it returns image_urls) have them fetched for you – result.images is a {filename: bytes} dict per engine, populated by compare() the same way result.markdown is. to_markdown_table()’s images column shows the count per engine at a glance.

No automated image comparison here – engines encode/crop/caption images differently even for “the same” figure, so this package limits itself to presence/count and letting you look:

from IPython.display import Image

row = result.get("mistral")
for filename, data in row.images.items():
    print(filename, f"{len(data)} bytes")
    display(Image(data=data))

Combining results from separate compare() calls

Running one engine at a time (different session, different machine, resource constraints) instead of passing engines=[...] all at once? Merge the results back into one ComparisonResultList afterwards – + and .merge() both return a new list without touching the originals; .extend() mutates the first list in place if you’d rather accumulate into one object as you go:

from estravon_bench.compare import compare
from estravon_bench.io import get_artusi
from estravon_bench.report import ComparisonResultList

pdf = str(get_artusi())
mineru_result  = compare(pdf, "1-4", engines=["mineru"])
mistral_result = compare(pdf, "1-4", engines=["mistral"])

combined = mineru_result + mistral_result                      # new list, both inputs untouched
# equivalent, and reads better for more than two lists:
combined = ComparisonResultList.merge(mineru_result, mistral_result)

mineru_result.extend(mistral_result)   # or: mutate mineru_result in place instead

print(combined.to_markdown_table())

Saving and loading a comparison run

ComparisonResultList.save(dir_path) writes the whole list to disk as plain files – manifest.json plus one subdirectory per engine holding result.md and an images/ folder – not a database or a binary format, so any file browser, git diff, or image viewer can inspect a saved run directly. ComparisonResultList.load(dir_path) reads it back into real ComparisonResult objects, markdown/images/metadata all restored exactly:

from estravon_bench.report import ComparisonResultList

result.save("runs/mineru_vs_mistral")

# ...later, or in a different session:
reloaded = ComparisonResultList.load("runs/mineru_vs_mistral")
print(reloaded.to_markdown_table())

Worked examples

Real, live-run engine comparisons – actual findings, not illustrative examples – live in a separate notebook: 06_worked_examples.ipynb.

Download files

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

Source Distribution

estravon_backend_benchmarks-0.2.2.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.

estravon_backend_benchmarks-0.2.2-py3-none-any.whl (25.8 kB view details)

Uploaded Python 3

File details

Details for the file estravon_backend_benchmarks-0.2.2.tar.gz.

File metadata

File hashes

Hashes for estravon_backend_benchmarks-0.2.2.tar.gz
Algorithm Hash digest
SHA256 8413b3510043c095a22c7995ac5eaac868d63961a558976818b267a359e00617
MD5 d2e9c72309f7fca9d479a4e50b1c0bec
BLAKE2b-256 67938e78a885fa802b4da9fbf99e71bcb0a9425468d201f8dac3b8266336c7d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for estravon_backend_benchmarks-0.2.2.tar.gz:

Publisher: publish.yml on tiberavonltd/estravon-backend-benchmarks

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

File details

Details for the file estravon_backend_benchmarks-0.2.2-py3-none-any.whl.

File metadata

File hashes

Hashes for estravon_backend_benchmarks-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 2e866c7c4290b8bbf4e43935139885d86ec32cb264ae4916141e5a036193a9b7
MD5 bf104e4aaad9655161336f4cae35fdee
BLAKE2b-256 e2529d7060b9e02ccb14791a937291afb91e227e8939bb8ab92f2c074f69ee2b

See more details on using hashes here.

Provenance

The following attestation bundles were made for estravon_backend_benchmarks-0.2.2-py3-none-any.whl:

Publisher: publish.yml on tiberavonltd/estravon-backend-benchmarks

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