\section{Pourquoi serverless + LaTeX}
Génération de PDF sans infrastructure
TeX Live pèse plus de 4 Go. L'embarquer dans une couche Lambda est lent, coûteux et fragile. L'API FormaTeX prend entièrement en charge la compilation, vos fonctions restent donc petites et rapides.
Pas de couche TeX Live
Gardez votre package de déploiement Lambda sous 10 Mo. FormaTeX gère l'environnement TeX Live complet sur une infrastructure managée.
Paiement à la compilation
Lambda facture à l'invocation ; FormaTeX facture à la compilation. Réduisez à zéro quand rien ne tourne et montez à des milliers de PDF en cas de charge.
Exécution isolée
Chaque compilation s'exécute dans un conteneur isolé sur les serveurs FormaTeX. Votre fonction Lambda n'exécute jamais de LaTeX arbitraire en local.
\section{Gestionnaire Python}
Gestionnaire Lambda Python
N'utilise que la bibliothèque standard de Python et boto3 (préinstallé sur tous les environnements d'exécution Lambda). Le PDF compilé est stocké dans S3 et la clé de l'objet est renvoyée.
- Environnement d'exécution : Python 3.12 ou ultérieur
- Dépendances : boto3 uniquement (inclus dans l'environnement d'exécution Lambda)
- Délai d'expiration : définissez au moins 30 secondes pour les documents complexes
import json
import os
import urllib.request
import boto3
def lambda_handler(event, context):
"""Compile LaTeX to PDF via FormaTeX API and store the result in S3."""
source = event.get("source", "")
engine = event.get("engine", "pdflatex")
if not source:
return {
"statusCode": 400,
"body": json.dumps({"error": "source is required"}),
}
# API key stored as a Lambda environment variable (or fetched from
# Secrets Manager at cold-start — see the IAM section below).
api_key = os.environ["FORMATEX_API_KEY"]
payload = json.dumps({"latex": source, "engine": engine}).encode()
req = urllib.request.Request(
"https://api.formatex.io/api/v1/compile",
data=payload,
headers={
"X-API-Key": api_key,
"Content-Type": "application/json",
},
method="POST",
)
with urllib.request.urlopen(req, timeout=25) as resp:
pdf_bytes = resp.read()
s3 = boto3.client("s3")
bucket = os.environ["OUTPUT_BUCKET"]
key = f"pdfs/{context.aws_request_id}.pdf"
s3.put_object(Bucket=bucket, Key=key, Body=pdf_bytes, ContentType="application/pdf")
return {
"statusCode": 200,
"body": json.dumps({"bucket": bucket, "key": key}),
}\section{Gestionnaire Node.js}
Gestionnaire Lambda Node.js
Gestionnaire orienté TypeScript, n'utilisant que les modules natifs de Node.js et le client S3 du SDK AWS v3. La clé API est mise en cache dans la portée du module afin que les invocations à chaud évitent la lecture de la variable d'environnement.
- Environnement d'exécution : Node.js 20.x ou ultérieur (ESM)
- Dépendances : @aws-sdk/client-s3 (inclus dans l'environnement d'exécution Lambda)
- Délai d'expiration : définissez au moins 30 secondes
import https from "node:https"
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"
const s3 = new S3Client({})
// Cache the API key across warm invocations
let cachedApiKey: string | undefined
export const handler = async (event: {
source: string
engine?: string
requestId?: string
}) => {
const { source, engine = "pdflatex" } = event
if (!source) {
return { statusCode: 400, body: JSON.stringify({ error: "source is required" }) }
}
if (!cachedApiKey) {
cachedApiKey = process.env.FORMATEX_API_KEY
}
if (!cachedApiKey) throw new Error("FORMATEX_API_KEY is not set")
const pdfBuffer = await compilePdf(cachedApiKey, source, engine)
const bucket = process.env.OUTPUT_BUCKET!
const key = `pdfs/${event.requestId ?? Date.now()}.pdf`
await s3.send(
new PutObjectCommand({
Bucket: bucket,
Key: key,
Body: pdfBuffer,
ContentType: "application/pdf",
}),
)
return { statusCode: 200, body: JSON.stringify({ bucket, key }) }
}
function compilePdf(apiKey: string, source: string, engine: string): Promise<Buffer> {
return new Promise((resolve, reject) => {
const body = JSON.stringify({ latex: source, engine })
const options = {
hostname: "api.formatex.io",
path: "/api/v1/compile",
method: "POST",
headers: {
"X-API-Key": apiKey,
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(body),
},
}
const req = https.request(options, (res) => {
const chunks: Buffer[] = []
res.on("data", (c: Buffer) => chunks.push(c))
res.on("end", () => {
if (res.statusCode !== 200) {
reject(new Error(`FormaTeX error: HTTP ${res.statusCode}`))
} else {
resolve(Buffer.concat(chunks))
}
})
})
req.on("error", reject)
req.write(body)
req.end()
})
}\section{Autorisations IAM}
Stocker la clé API dans Secrets Manager
Pour les charges de travail en production, stockez votre clé API FormaTeX dans AWS Secrets Manager plutôt que dans une simple variable d'environnement. Attachez la politique ci-dessous au rôle d'exécution de votre Lambda et récupérez le secret au démarrage à froid.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadFormaTeXApiKey",
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:formatex/api-key-*"
},
{
"Sid": "WriteOutputBucket",
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": "arn:aws:s3:::your-output-bucket/pdfs/*"
}
]
}
# Store the secret in Secrets Manager (one-time setup):
aws secretsmanager create-secret \
--name formatex/api-key \
--secret-string '{"FORMATEX_API_KEY":"your-key-here"}'
# Then fetch it at cold-start in Python:
# import boto3, json
# secret = boto3.client("secretsmanager").get_secret_value(SecretId="formatex/api-key")
# api_key = json.loads(secret["SecretString"])["FORMATEX_API_KEY"]\section{Démarrages à froid}
Réduire la latence des démarrages à froid
Mettre les secrets en cache dans la portée du module
Récupérez votre clé API depuis Secrets Manager une seule fois, en dehors de la fonction du gestionnaire. La valeur est réutilisée pour toutes les invocations à chaud sans appel réseau supplémentaire.
Utiliser la concurrence provisionnée pour les chemins sensibles à la latence
Activez la concurrence provisionnée sur la version Lambda pour éliminer complètement les démarrages à froid sur les points de terminaison de génération de PDF exposés aux utilisateurs. Utilisez la concurrence à la demande pour les tâches par lots en arrière-plan.
Définir un délai d'expiration réaliste
Les documents LaTeX complexes avec TikZ, bibliographie ou plusieurs passes de compilation peuvent prendre 10 à 20 secondes. Définissez le délai d'expiration de la Lambda à au moins 30 secondes et configurez celui de votre intégration API Gateway ou ALB en conséquence.
\section{Guides associés}
Autres guides SDK et langages
L'API FormaTeX est un simple point de terminaison HTTP. Utilisez-la depuis n'importe quel langage ou environnement d'exécution.

