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 automaticallybytes— raw binary data, base64-encoded for youstr— 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06cb9642ab2719b655821facdccdb8dd097cfe01bd69a1c67e28343ded11b893
|
|
| MD5 |
559dd2cf6bca8425cca9cfd7087fbcee
|
|
| BLAKE2b-256 |
dd589680a43413c792e2a1655ab9ffde9091d05ffdf6010593c8e0b769d2931e
|
Provenance
The following attestation bundles were made for formatex-1.0.2.tar.gz:
Publisher:
publish.yml on forma-tex/python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
formatex-1.0.2.tar.gz -
Subject digest:
06cb9642ab2719b655821facdccdb8dd097cfe01bd69a1c67e28343ded11b893 - Sigstore transparency entry: 1004884779
- Sigstore integration time:
-
Permalink:
forma-tex/python-sdk@c6ab90bcb58a1dd613343f801e9c3651faa6e71b -
Branch / Tag:
refs/tags/v1.0.2 - Owner: https://github.com/forma-tex
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c6ab90bcb58a1dd613343f801e9c3651faa6e71b -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5869dc52551186e6e4d905590aa82d69bb039dce4d57ae0acbd9cc307756c562
|
|
| MD5 |
036ad8ce782d8fb2d573654499ea2143
|
|
| BLAKE2b-256 |
ca8e484bb89a3ed653f384ede340733e7f5838bf6815c58931a2016bacd3c2ae
|
Provenance
The following attestation bundles were made for formatex-1.0.2-py3-none-any.whl:
Publisher:
publish.yml on forma-tex/python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
formatex-1.0.2-py3-none-any.whl -
Subject digest:
5869dc52551186e6e4d905590aa82d69bb039dce4d57ae0acbd9cc307756c562 - Sigstore transparency entry: 1004884782
- Sigstore integration time:
-
Permalink:
forma-tex/python-sdk@c6ab90bcb58a1dd613343f801e9c3651faa6e71b -
Branch / Tag:
refs/tags/v1.0.2 - Owner: https://github.com/forma-tex
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c6ab90bcb58a1dd613343f801e9c3651faa6e71b -
Trigger Event:
push
-
Statement type: