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.1.tar.gz (16.1 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.1-py3-none-any.whl (3.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: formatex-1.0.1.tar.gz
  • Upload date:
  • Size: 16.1 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.1.tar.gz
Algorithm Hash digest
SHA256 6741854c026b27993bc1f2dda7d4eb8687f8bc6b28b51d6eeefa8e6c25a6e437
MD5 aae618fa2e8f48f267f7beb74cf85738
BLAKE2b-256 fa6cac2f0c0958a34db4bc52e4bc80498b7517077a606be1f1950cfa0ca06470

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: formatex-1.0.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 753d06449d0a215fd8d06abb5216600e769982f8b0247f80ec31d6132ee89e30
MD5 b7e28d7453bbe31e52ad17dbe0abfde3
BLAKE2b-256 6e8bd481422d683ee667c5864b31589aee34cbaae43525753b44ed2b997de058

See more details on using hashes here.

Provenance

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