Skip to main content

Python SDK for the Enconvert file conversion API

Project description

enconvert

Python SDK for the Enconvert file conversion API.

Convert URLs to PDFs, capture screenshots, extract Markdown, crawl whole websites, transform images, and convert documents — all with a single API call. Python 3.9+.

Install

pip install enconvert

Quick Start

from enconvert import Enconvert

client = Enconvert(api_key="sk_...")

URL to PDF

result = client.convert_url_to_pdf("https://example.com", save_to="page.pdf")
print(result.presigned_url)

URL to Screenshot

result = client.convert_url_to_screenshot(
    "https://example.com",
    viewport_width=1440,
    save_to="screenshot.png",
)

URL to Markdown

Extract clean GitHub-Flavored Markdown from any URL — strips nav/footer/ads/scripts, keeps the main article content, and adds YAML frontmatter (title, description, url, links, images).

result = client.convert_url_to_markdown(
    "https://example.com/article",
    save_to="article.md",
)

Website to PDF / Screenshot (whole-site batch)

Discover every page of a website (via sitemap, or full crawl on Pro/Business plans), convert each one in the background, and receive a single ZIP. Requires a private API key with crawl access.

batch = client.convert_website_to_pdf(
    "https://example.com",
    crawl_mode="sitemap",             # "auto" (default) | "sitemap" | "full"
    exclude_patterns=["/blog/tag/"],  # full crawl mode only
)
print(batch.batch_id, batch.url_count, batch.discovery_method)

# Block until done and save the ZIP:
status = client.wait_for_batch(batch.batch_id, save_to="site.zip")
print(status.completed, "of", status.total, "pages converted")

# Or poll yourself:
s = client.get_batch_status(batch.batch_id)
if s.status != "processing":
    print(s.zip_download_url)

convert_website_to_screenshot works the same way and produces a ZIP of PNGs.

Image Conversion

result = client.convert_image(
    "photo.heic",
    output_format="webp",
    save_to="photo.webp",
)

Any pair among jpeg, png, svg, heic, webp — plus PDF rasterization:

client.convert_image("scan.pdf", output_format="jpeg", save_to="scan.jpeg")

Document Conversion

client.convert_document("report.docx", save_to="report.pdf")
client.convert_document("data.json", output_format="yaml", save_to="data.yaml")
client.convert_document("notes.md", output_format="html", save_to="notes.html")

Supported inputs: doc/docx, xls/xlsx, ppt/pptx, odt, ods, odp, ots, pages, numbers, epub, html, markdown, csv, json, xml, yaml, toml

The SDK validates every {input}-to-{output} pair against the conversions the API actually implements and raises immediately — with the list of valid outputs for that input — instead of sending a doomed request. Introspect programmatically:

from enconvert import IMPLEMENTED_CONVERSIONS, valid_outputs_for

valid_outputs_for("json")  # ["csv", "toml", "xml", "yaml"]
valid_outputs_for("pdf")   # ["jpeg"]

Supported conversions

Input Outputs
json csv, toml, xml, yaml
xml csv, json
yaml json
csv json, xml
toml json
markdown html, pdf
html pdf
doc, excel, ppt, odt, ods, odp, ots, pages, numbers, epub pdf
jpeg, png, svg, heic, webp each other (all 20 pairs)
pdf jpeg

Job Status (async polling)

status = client.get_job_status("job_abc123")
if status.status == "success":
    print(status.presigned_url)

PDF Options

from enconvert import PdfHeaderFooter, PdfMargins, PdfOptions

result = client.convert_url_to_pdf(
    "https://example.com",
    pdf_options=PdfOptions(
        page_size="A4",              # or custom dimensions via page_width + page_height
        orientation="landscape",
        margins=PdfMargins(top=10, bottom=10, left=15, right=15),
        header=PdfHeaderFooter(content="Quarterly Report", height=15),
        footer=PdfHeaderFooter(content="Confidential", height=12),
    ),
    save_to="report.pdf",
)

Authenticated Pages (plan-gated)

All URL and website conversions accept HTTP Basic Auth, cookies, and custom headers for pages behind a login:

from enconvert import BrowserCookie, HttpBasicAuth

client.convert_url_to_pdf(
    "https://internal.example.com/report",
    auth=HttpBasicAuth(username="user", password="pass"),
    # or cookies / headers:
    cookies=[BrowserCookie(name="session", value="abc123", domain="internal.example.com")],
    headers={"X-Tenant": "acme"},
    save_to="report.pdf",
)

Do not combine auth with an Authorization header — the API rejects the conflict.

Error Handling

from enconvert import Enconvert, APIError, AuthenticationError, RateLimitError

try:
    client.convert_url_to_pdf("https://example.com")
except AuthenticationError:
    print("Invalid API key")
except RateLimitError:
    print("Too many requests — slow down")
except APIError as e:
    print(f"API error [{e.status_code}]: {e.message}")

Configuration

client = Enconvert(
    api_key="sk_...",
    timeout=300.0,  # seconds, default
    base_url="https://api.enconvert.com",  # default
)

V2 API (client.v2)

The V2 namespace turns web pages into agent-ready data: render, search, extract, ingest, and monitor. All V2 endpoints require a private API key and are plan-gated — a disabled feature or exhausted monthly quota raises QuotaError (HTTP 402).

Perceive — render a URL into artifacts

op = client.v2.perceive(
    "https://example.com",
    outputs=["markdown", "screenshot", "structured"],
    extract=["tables", "metadata"],
)
print(op.outputs["markdown"].url)  # 15-min signed URL
print(op.structured)

# Re-sign artifact URLs later:
again = client.v2.get_perceive_operation(op.operation_id)

# Batch (<=10 URLs runs inline; larger returns "queued" — poll):
batch = client.v2.perceive_batch(
    ["https://a.com", "https://b.com"],
    outputs=["markdown"],
    output_mode="zip",
)
done = client.v2.get_perceive_batch(batch.job_id)

Discover — enumerate a site's URLs (no rendering)

found = client.v2.discover(
    "https://example.com",
    mode="hybrid",              # "sitemap" | "crawl" | "hybrid"
    max_urls=200,
    exclude_patterns=["/tag/"],
)
print(found.total, found.urls)

Lookup — web search with optional auto-perceive

search = client.v2.lookup(
    "best static site generators",
    category="web",             # web | news | images | scholar | patents | maps
    num_results=10,
    perceive_top=3,              # auto-render top 3 results (uses perceive quota)
)
for hit in search.results:
    print(hit.title, hit.url, hit.perceive.outputs if hit.perceive else None)

Distill — schema-driven structured extraction

from enconvert import CssField, CssSchema

extraction = client.v2.distill(
    urls=["https://example.com/pricing"],
    schema={"plans": "list of plan names with monthly prices"},
    css_schema=CssSchema(               # optional free CSS pass before the LLM tier
        base_selector=".plan-card",
        fields=[
            CssField(name="name", type="text", selector="h3"),
            CssField(name="price", type="text", selector=".price"),
        ],
    ),
)
print(extraction.results[0].data, extraction.results[0].extraction_tier)

# Or discover-then-distill:
from enconvert import DistillDiscoverFrom

client.v2.distill(
    discover_from=DistillDiscoverFrom(url="https://example.com", mode="sitemap", max_pages=10),
    schema={"title": "page title", "summary": "one-line summary"},
)

Ingest — site to RAG-ready JSONL (always async)

from enconvert import IngestChunkOptions

job = client.v2.ingest(
    mode="sitemap",
    url="https://docs.example.com",
    max_pages=100,
    chunk=IngestChunkOptions(max_words=512, sentence_overlap=1),
    webhook_url="https://my.app/hooks/enconvert",
)

status = client.v2.get_ingest_job(job.job_id)  # poll
if status.status == "completed":
    print(status.output_url)  # JSONL

client.v2.list_ingest_jobs(limit=20)
client.v2.cancel_ingest_job(job.job_id)  # idempotent

# Webhook signing (HMAC):
secret = client.v2.get_webhook_secret()
print(secret.secret, secret.signature_header)
client.v2.rotate_webhook_secret()             # invalidates old secret
client.v2.retry_ingest_webhook(job.job_id)    # re-deliver

Watch — recurring change monitoring

watcher = client.v2.create_watcher(
    "https://example.com/pricing",
    frequency_minutes=60,        # hourly floor
    diff_mode="auto",            # auto | text | structured | tables | metadata
    webhook_url="https://my.app/hooks/changes",
    notify_email=True,
)

client.v2.list_watchers()
client.v2.get_watcher(watcher.watcher_id)
client.v2.get_watcher_snapshots(watcher.watcher_id, limit=10)
client.v2.update_watcher(watcher.watcher_id, status="paused")
client.v2.update_watcher(watcher.watcher_id, webhook_url="")  # clears webhook
client.v2.delete_watcher(watcher.watcher_id)  # soft-delete, idempotent

V2 error handling

from enconvert import QuotaError

try:
    client.v2.ingest(urls=["https://example.com"])
except QuotaError:
    print("Upgrade plan or wait for quota reset")

Get an API Key

Sign up at enconvert.com to get your API key.

License

MIT

Project details


Download files

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

Source Distribution

enconvert-0.0.1.tar.gz (30.8 kB view details)

Uploaded Source

Built Distribution

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

enconvert-0.0.1-py3-none-any.whl (29.2 kB view details)

Uploaded Python 3

File details

Details for the file enconvert-0.0.1.tar.gz.

File metadata

  • Download URL: enconvert-0.0.1.tar.gz
  • Upload date:
  • Size: 30.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for enconvert-0.0.1.tar.gz
Algorithm Hash digest
SHA256 df395a41a1a8bae80a97409c87becf2443bda7fcf24cf57ddc2fc66db2aef078
MD5 1e59d0541985691de2a08482de3d8ad0
BLAKE2b-256 af81b9f39b121235b40d2ecc706a170f4631bcea6021b9290d70400350056172

See more details on using hashes here.

File details

Details for the file enconvert-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: enconvert-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 29.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for enconvert-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ad0a55ce87e3fab8fd22f7bd6f7310d7614519792e415f4059e775119452942c
MD5 8de340df7cdeb82dca73dd28d33cd777
BLAKE2b-256 97a47a376d7cf244ea4b69471c7de5bc59783beaaceeaa7b7c184d2da43531a8

See more details on using hashes here.

Supported by

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