Small HTTP server that converts a hand-drawn diagram image into standalone LaTeX/TikZ using an LLM, then compiles it with pdflatex and renders a PNG preview via ImageMagick.
https://lab.phc.dm.unipi.it/diagram-to-tikz/
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
5 months ago | |
|---|---|---|
| examples | 5 months ago | |
| public | 5 months ago | |
| templates | 5 months ago | |
| .gitignore | 5 months ago | |
| .python-version | 5 months ago | |
| Dockerfile | 5 months ago | |
| README.md | 5 months ago | |
| docker-compose.yaml | 5 months ago | |
| main.py | 5 months ago | |
| pyproject.toml | 5 months ago | |
| uv.lock | 5 months ago | |
README.md
diagram-to-tikz
Small HTTP server that converts a hand-drawn diagram image into standalone LaTeX/TikZ using an LLM, then compiles it with pdflatex and renders a PNG preview via ImageMagick (magick).
Prerequisites
-
System tools:
-
pdflatex(TeX Live) -
magick(ImageMagick) -
pdf2svg
-
Install (uv)
From this folder:
uv sync
Configure LLM
This project uses LiteLLM with Google Gemini models.
Set credentials (common case):
export GOOGLE_API_KEY="..."
Defaults (comma-separated fallback order):
LLM_MODELS=gemini/gemini-3-pro-preview,gemini/gemini-3-flash-preview,gemini/gemini-flash-latestEDIT_MODELS=gemini/gemini-3-flash-preview,gemini/gemini-flash-latest
Override if you want:
export LLM_MODELS="gemini/gemini-3-flash-preview"
export EDIT_MODELS="gemini/gemini-3-flash-preview"
Run
Option A: run via Python entrypoint
uv run python main.py
Option B: run via uvicorn (recommended for dev)
uv run uvicorn main:app --reload
Open:
Docker
Single-stage python:3.12-slim + uv with cached dependency layer. BuildKit is required for cache mounts.
Build locally:
docker build -t diagram-to-tikz .
Run with Docker
docker run -it --rm -p 8000:8000 \
-e GOOGLE_API_KEY="your-google-api-key" \
-e LLM_MODELS="gemini/gemini-3-pro-preview,gemini/gemini-3-flash-preview,gemini/gemini-flash-latest" \
-e EDIT_MODELS="gemini/gemini-3-flash-preview,gemini/gemini-flash-latest" \
-e BASE_PATH="/" \
-v $(pwd)/runs:/app/runs \
diagram-to-tikz \
uv run uvicorn main:app --host 0.0.0.0 --port 8000
Run with Docker Compose
Run with Compose (persists runs/ to the host):
services:
app:
build: .
ports:
- "8000:8000"
environment:
GOOGLE_API_KEY: "your-google-api-key"
LLM_MODELS: "gemini/gemini-3-pro-preview,gemini/gemini-3-flash-preview,gemini/gemini-flash-latest"
EDIT_MODELS: "gemini/gemini-3-flash-preview,gemini/gemini-flash-latest"
BASE_PATH: "/"
LOG_LEVEL: "INFO"
CONVERT_DAILY_LIMIT: "5"
EDIT_DAILY_LIMIT: "10"
PDFLATEX_TIMEOUT_SECONDS: "10"
HOST: "0.0.0.0"
PORT: "8000"
RELOAD: "0"
volumes:
- ./runs:/app/runs
command: uv run uvicorn main:app --host 0.0.0.0 --port 8000
Then start it:
docker compose up --build
Outputs
Each request creates a folder under runs/<run_id>/ containing:
original.*(your upload)diagram.texdiagram.pdf(if LaTeX compilation succeeded)diagram.png(if ImageMagick rendering succeeded)run.log.txt(all logs: LLM + pdflatex + magick)