Skip to main content

Ethos Python Package

This directory contains the ethos-pdf Python package source for Ethos.

Install the published evaluation wheel from PyPI with:

python3 -m pip install ethos-pdf==0.5.0

v0.5.0 includes JSON verification and evidence-anchor wrapper calls through a caller-provided ethos CLI binary. The Python wheel does not bundle the CLI or PDFium.

The package exposes a public semver API beginning at 0.1.0 for Python >=3.8. Patch releases must not break public function signatures, exception classes, or documented return shapes. Minor releases may add backward-compatible API, and major releases may break API after a release-scope decision.

Public API:

  • EthosCli
  • EthosPythonSurfaceError
  • EthosNotFoundError
  • EthosTimeoutError
  • EthosCommandError
  • PdfiumNotFoundError
  • InvalidPdfError
  • CorruptPdfError
  • ParseTimeoutError
  • EthosOutputError
  • CitationEmissionError
  • parse_pdf_json
  • parse_pdf_markdown
  • parse_pdf_text
  • crop_element
  • verify
  • proof_summary
  • app_answer_release_decision
  • anchor
  • build_citation_emission
  • build_langchain_context
  • build_llamaindex_context
  • citation_json_bytes
  • emit_langchain_citations
  • emit_llamaindex_citations
  • hydrate_citations

The CLI wrapper remains intentionally thin: it shells out to a caller-provided local ethos CLI binary and returns ethos doc parse output, source-bound ethos crop_element JSON, ethos verify JSON reports, or ethos evidence anchor JSON reports. The citation-emission helpers below are pure Python and do not invoke that binary. The wheel does not bundle PDFium, does not publish hosted surfaces, and does not expand parser behavior. The Rust CLI remains the verification source of truth.

The package name is historical continuity naming. JSON verification and evidence-anchor calls do not require PDF parsing, but the package is still named ethos-pdf.

PDFium-backed parse and crop paths require caller-provided PDFium through ETHOS_PDFIUM_LIBRARY_PATH. Importing ethos_pdf does not require PDFium. If PDFium is missing, the wrapper raises PdfiumNotFoundError and preserves the underlying CLI stderr so callers can show the setup guidance from QUICKSTART.md or docs/pdfium-manual-setup.md.

Python wheels do not run post-install hooks. Run python -m ethos_pdf after installation to print the paved scripts/fetch-pdfium.sh setup path; the command prints guidance only and never downloads or changes PDFium.

Exceptions

All wrapper-owned exceptions inherit from EthosPythonSurfaceError.

Subprocess failures inherit from EthosCommandError and expose command, returncode, stdout, and stderr. When the CLI emits its stable JSON error envelope on stderr, the wrapper maps by error.code; otherwise it falls back to the documented exit code:

CLI condition Exit Python exception
missing caller-provided PDFium any non-zero exit with PDFium setup stderr PdfiumNotFoundError
invalid_pdf 3 InvalidPdfError
corrupt_pdf 4 CorruptPdfError
parse_timeout 10 ParseTimeoutError
any other non-zero CLI exit other EthosCommandError

Wrapper-side timeouts raised by subprocess.run(..., timeout=...) use EthosTimeoutError. Missing input files raise Python FileNotFoundError before invoking the CLI.

JSON Verify And Evidence Anchor

Use the binary constructor alias when a caller manages the CLI path explicitly:

from ethos_pdf import EthosCli

ethos = EthosCli(binary="/path/to/ethos")

report = ethos.verify(
    source="source.ethos.json",
    citations="citations.json",
    grounding=None,
    config=None,
    fail_on_ungrounded=False,
    output_format="json",
    timeout=30,
)

anchor_report = ethos.anchor(
    source="source.ethos.json",
    evidence_refs="evidence_refs.json",
    grounding=None,
    output_format="json",
    timeout=30,
)

verify(...) maps source to the positional CLI input, maps citations to --citations, maps grounding to an adapter id such as opendataloader-json, maps config to --config, and maps fail_on_ungrounded=True to --fail-on-ungrounded.

anchor(...) maps source to the positional CLI input, maps evidence_refs to --evidence-refs, and maps grounding to an adapter id. It does not expose a fail flag in the v0.2 preparation surface. Non-bound evidence-anchor outcomes are returned as structured reports, not exceptions.

Verify exit semantics:

  • exit 0 with JSON returns a report;
  • exit 1 with JSON returns a negative verification report when fail_on_ungrounded=True;
  • exit >=2 raises EthosCommandError or a more specific subclass.

Use proof_summary(report) when a product or API wrapper needs the same derived status as the Rust VerificationReport::proof_summary() helper:

from ethos_pdf import EthosCli, proof_summary

ethos = EthosCli(binary="/path/to/ethos")
report = ethos.verify("source.ethos.json", citations="citations.json")
summary = proof_summary(report)
print(summary["proof_status"])

The summary is not a replacement for the canonical verification report. It deterministically derives proof_status, request_certified, reusable grounded check ids, needs-review check ids, and proof limitations from the report that ethos verify already emitted.

Use app_answer_release_decision(...) when an application has already labeled claim relevance, synthesis, and support, and wants the conservative release policy from docs/app-answer-release-contract.md:

from ethos_pdf import app_answer_release_decision, proof_summary

summary = proof_summary(report)
decision = app_answer_release_decision(
    "What was Q3 2025 revenue?",
    summary,
    [
        {
            "id": "claim-revenue",
            "text": "Revenue grew to $12.4M in Q3 2025.",
            "check_ids": ["v0001"],
            "question_relevance": "direct_answer",
            "claim_type": "source_fact",
            "claim_support": "supported",
        }
    ],
)
print(decision["app_status"])

The helper does not judge relevance, synthesis, or claim support. Callers supply those labels; the helper applies the release rule and requires referenced Ethos check IDs to be reusable before a claim can enter the final answer. For a grounded claim, missing claim_support becomes not_evaluated and requires review. The helper also rejects duplicate claim IDs so final_answer_claim_ids, review_claim_ids, and blocked_claim_ids stay unambiguous.

Citation emission

The source API builds the independently versioned citation-emission v1 artifact and hydrates it into verifier input. Registry publication remains a human release action. No CLI, PDFium, LangChain, or LlamaIndex package is imported by these helpers.

Retrieval objects must carry an explicit Ethos metadata contract. Each object's metadata mapping must contain one document_fingerprint and at least one source locator in page_refs, element_refs, span_refs, or table_cells. Reference fields are arrays of non-blank IDs. table_cells entries have exactly table_id, row, and col. All records in one call must use the same fingerprint. Numeric framework page indexes and other aliases are deliberately ignored; copy stable source IDs into these fields rather than asking the helper to guess.

For an existing LangChain retrieval result:

from ethos_pdf import citation_json_bytes, emit_langchain_citations

documents = retriever.invoke(question)
# Each Document.metadata follows the explicit contract above.
claims = structured_model_output["claims"]
citations = emit_langchain_citations(
    documents,
    structured_model_output["answer"],
    claims,
)
citations_bytes = citation_json_bytes(citations)

Use emit_llamaindex_citations(nodes, answer, claims) for TextNode or NodeWithScore results. Both adapters are duck typed and accept mapping equivalents, so applications do not add an Ethos framework dependency. build_langchain_context and build_llamaindex_context expose the trusted retrieval vocabulary separately; build_citation_emission builds model-facing v1 output; and hydrate_citations joins the two when an application needs separate callback and hydration steps.

Every malformed claim, missing or mixed fingerprint, unshown source ID, unexposed table cell, and configured claim-limit violation raises CitationEmissionError. Its stable code plus optional claim_index or record_index can be returned to a structured-output retry. The whole batch is rejected; helpers never repair, drop, or infer a locator. This validates citation structure and retrieval provenance only—verification still requires ethos verify, and grounding is not a semantic-truth judgment.

Runnable, provider-free walkthroughs are in examples/langchain-rag/README.md and examples/llamaindex-rag/README.md. Both preserve the verifier's intentional exit-1 report for a fabricated citation and require no model API key.

Evidence Handle Bridge

The v2 bridge exposes opaque evidence_id values to a structured model callback while trusted application code retains canonical locators and the document fingerprint. Build a context with build_evidence_handle_context, validate structured output with build_evidence_citation_emission, hydrate with hydrate_evidence_citations, and project retrieved, cited, and verified booleans with project_evidence_states.

Only structured claims[].evidence_id values are citations. The answer string is untrusted prose: never infer a citation from handle-shaped text, make it clickable, or give it verified styling. Badges, links, and statuses must come only from structured claims plus projected state. Unknown handle-shaped prose stays inert or is removed by a deterministic presentation sanitizer. A model can name a fabricated or conflicting handle in prose even when its structured claims are valid. Display labels and excerpts are untrusted presentation/context fields, carry no proof authority, and must be escaped or deterministically sanitized before rendering.

Run the focused tests with:

make python-surface-test

The tests use a fake local command, so they do not require PDFium.

Metadata

Release files for ethos-pdf 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ethos-pdf 0.6.0
File Size Uploaded
ethos_pdf-0.6.0.tar.gz 40.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ethos-pdf 0.6.0
File Interpreter ABI Platform
ethos_pdf-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 68.4 kB

Release files / ethos_pdf-0.6.0.tar.gz

Download URL ethos_pdf-0.6.0.tar.gz
Size 40.4 kB
Tags Source
SHA-256 checksum
How to use checksums
4b385f5a7f93bd6fcb8a56bb28a15c08c00372e3a845a9e0bd6bf4720120beec
BLAKE2b-256 checksum
How to use checksums
c0d99019b9fee0fe1404d0e26926ad33672e3d4e6f53d2cbdcc3b9b9e7fbedbb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / ethos_pdf-0.6.0-py3-none-any.whl

Download URL ethos_pdf-0.6.0-py3-none-any.whl
Size 28.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3de7353bf9fb1e9d31db0eae26dff0d5b678a1b240ffab5fcdda00987e373bbf
BLAKE2b-256 checksum
How to use checksums
d579a7cf8f3a0ab08ff3feec9b382ed2cf4a81f8e6421c47a119be4dcebd0bb3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

This release

0.6.0 This release

2 release files

0.5.0

1 release file

0.4.0

1 release file

0.3.0

1 release file

0.2.0

2 release files

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page