Skip to main content

Python SDK for the FormaTex LaTeX-to-PDF API

Project description

FormaTex Python SDK

Official Python client for the FormaTex LaTeX-to-PDF API.

Installation

pip install FormaTex

Requires Python ≥ 3.9.

Quick Start

from FormaTex import FormaTexClient

with FormaTexClient("fx_your_api_key") as client:
    result = client.compile(
        r"\documentclass{article}\begin{document}Hello, world!\end{document}"
    )
    # result.pdf       → bytes
    # result.engine    → "pdflatex"
    # result.duration_ms → 412
    with open("output.pdf", "wb") as f:
        f.write(result.pdf)

Compilation

Sync (immediate response)

# Choose your engine
result = client.compile(latex, engine="pdflatex")   # default
result = client.compile(latex, engine="xelatex")    # Unicode + modern fonts
result = client.compile(latex, engine="lualatex")   # Lua scripting
result = client.compile(latex, engine="latexmk")    # automatic multi-pass

# Smart compile: auto-detects the right engine + attempts auto-fix
result = client.compile_smart(latex)

# Compile directly to a file
client.compile_to_file(latex, "output.pdf")
client.compile_to_file(latex, "output.pdf", engine="xelatex")
client.compile_to_file(latex, "output.pdf", smart=True)

Async (long-running documents)

from FormaTex import FormaTexClient

with FormaTexClient("fx_your_api_key") as client:
    # Submit and get a job ID immediately
    job = client.async_compile(latex, engine="pdflatex")
    print(job.job_id, job.status)  # "abc-123", "pending"

    # Option 1: blocking wait (polls automatically)
    result = client.wait_for_job(job.job_id)
    with open("output.pdf", "wb") as f:
        f.write(result.pdf)

    # Option 2: manual polling loop
    import time
    while True:
        status = client.get_job(job.job_id)
        if status.status == "completed":
            pdf = client.get_job_pdf(job.job_id)  # one-time download
            break
        elif status.status == "failed":
            print("Failed:", status.error)
            break
        time.sleep(2)

    # Retrieve just the log
    log = client.get_job_log(job.job_id)

    # Clean up server-side (optional, PDF auto-deletes after download)
    client.delete_job(job.job_id)

Multi-File Projects

Use file_entry to attach companion files (images, .bib, .cls, etc.):

from pathlib import Path
from FormaTex import FormaTexClient, file_entry

latex = r"""
\documentclass{article}
\usepackage{graphicx}
\begin{document}
\includegraphics[width=\linewidth]{logo.png}
\bibliography{refs}
\end{document}
"""

with FormaTexClient("fx_your_api_key") as client:
    result = client.compile(
        latex,
        engine="pdflatex",
        files=[
            file_entry("logo.png", Path("assets/logo.png")),   # auto-read from disk
            file_entry("refs.bib", Path("references.bib")),
        ],
    )
    Path("output.pdf").write_bytes(result.pdf)

file_entry(name, content) accepts:

  • Path — reads the file automatically
  • bytes — raw binary data, base64-encoded for you
  • str — already base64-encoded content passed through as-is

Lint (Static Analysis)

Run chktex without consuming compilation quota:

from FormaTex import FormaTexClient

latex = r"""
\documentclass{article}
\begin{document}
Hello world.
\end{document}
"""

with FormaTexClient("fx_your_api_key") as client:
    result = client.lint(latex)

    print(f"Valid: {result.valid}")
    print(f"Errors: {result.error_count}, Warnings: {result.warning_count}")

    for d in result.diagnostics:
        print(f"  Line {d.line}:{d.column} [{d.severity}] {d.message}")

Integrate into CI:

result = client.lint(source)
if not result.valid:
    raise SystemExit(f"LaTeX lint failed: {result.error_count} error(s)")

Convert to Word (DOCX)

with FormaTexClient("fx_your_api_key") as client:
    result = client.convert(latex)
    Path("document.docx").write_bytes(result.docx)

    # Or write directly to a file
    client.convert_to_file(latex, "document.docx")

Syntax Check

Free endpoint — does not count against your quota:

check = client.check_syntax(latex)
print(check.valid, check.errors)

Usage Stats & Engines

usage = client.get_usage()
print(f"{usage.compilations_used}/{usage.compilations_limit} compilations this month")
print(f"Overage: {usage.overage}")

engines = client.list_engines()
for e in engines:
    print(e["name"], e["available"])

Error Handling

from FormaTex import (
    FormaTexClient,
    AuthenticationError,
    CompilationError,
    RateLimitError,
    PlanLimitError,
)

with FormaTexClient("fx_your_api_key") as client:
    try:
        result = client.compile(latex)
    except AuthenticationError:
        print("Invalid API key")
    except CompilationError as e:
        print(f"Compilation failed: {e}")
        print(f"Compiler log:\n{e.log}")
    except RateLimitError as e:
        print(f"Rate limited — retry after {e.retry_after}s")
    except PlanLimitError:
        print("Plan limit exceeded, upgrade at https://FormaTex.com/pricing")

Self-Hosted / Custom URL

client = FormaTexClient("fx_key", base_url="https://latex.your-company.com")

Type Reference

All types are importable directly from FormaTex:

Type Description
CompileResult Sync compile result: pdf, engine, duration_ms, size_bytes, log, job_id
AsyncJob Submitted async job: job_id, status
JobResult Polled job state: job_id, status, log, duration_ms, error, success
LintResult Lint output: diagnostics, duration_ms, error_count, warning_count, valid
LintDiagnostic Single finding: line, column, severity, message, source, code
SyntaxResult Syntax check: valid, errors
ConvertResult DOCX output: docx (bytes), size_bytes
UsageStats Quota: compilations_used, compilations_limit, overage, period_start, period_end

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

formatex-1.0.2.tar.gz (16.4 kB view details)

Uploaded Source

Built Distribution

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

formatex-1.0.2-py3-none-any.whl (3.3 kB view details)

Uploaded Python 3

File details

Details for the file formatex-1.0.2.tar.gz.

File metadata

  • Download URL: formatex-1.0.2.tar.gz
  • Upload date:
  • Size: 16.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for formatex-1.0.2.tar.gz
Algorithm Hash digest
SHA256 06cb9642ab2719b655821facdccdb8dd097cfe01bd69a1c67e28343ded11b893
MD5 559dd2cf6bca8425cca9cfd7087fbcee
BLAKE2b-256 dd589680a43413c792e2a1655ab9ffde9091d05ffdf6010593c8e0b769d2931e

See more details on using hashes here.

Provenance

The following attestation bundles were made for formatex-1.0.2.tar.gz:

Publisher: publish.yml on forma-tex/python-sdk

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

File details

Details for the file formatex-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: formatex-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 3.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for formatex-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5869dc52551186e6e4d905590aa82d69bb039dce4d57ae0acbd9cc307756c562
MD5 036ad8ce782d8fb2d573654499ea2143
BLAKE2b-256 ca8e484bb89a3ed653f384ede340733e7f5838bf6815c58931a2016bacd3c2ae

See more details on using hashes here.

Provenance

The following attestation bundles were made for formatex-1.0.2-py3-none-any.whl:

Publisher: publish.yml on forma-tex/python-sdk

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 Pingdom Monitoring Sentry Error logging StatusPage Status page