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.3.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.3-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: formatex-1.0.3.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.3.tar.gz
Algorithm Hash digest
SHA256 0ff0de8322172f4cc68c63b98c880a44575fa7aa228a0b67b92a052954e4dc06
MD5 11f1fbfaf0cb7d56508202de57d3c646
BLAKE2b-256 225bdb51b157f42f1b74a23a6c2ac99f02b7102f058b750447449d678ec7ff6d

See more details on using hashes here.

Provenance

The following attestation bundles were made for formatex-1.0.3.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.3-py3-none-any.whl.

File metadata

  • Download URL: formatex-1.0.3-py3-none-any.whl
  • Upload date:
  • Size: 10.6 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 b03fe5d08429c805ba94bbf77a2687efaf3edd0f350aaa7200c34b54f84a84f0
MD5 22b5ec85bf32199dd707f89b327b046a
BLAKE2b-256 300210ac51b3797254e6ab013594f56e8d44f316eee66f476bf911a3ed75a730

See more details on using hashes here.

Provenance

The following attestation bundles were made for formatex-1.0.3-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