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.
2.4 KiB
2.4 KiB
latex-diagram-to-tikz
Small HTTP server that converts a hand-drawn diagram image into standalone LaTeX/TikZ using an LLM (via LiteLLM), then compiles it with pdflatex and renders a PNG preview via ImageMagick (magick).
Prerequisites
- System tools:
pdflatex(TeX Live)magick(ImageMagick)
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:
LLM_MODEL=gemini/gemini-3-flash-preview(image → TikZ)EDIT_MODEL=gemini/gemini-3-flash-preview(text edits on LaTeX)
Override if you want:
export LLM_MODEL="gemini/gemini-3-flash-preview"
export EDIT_MODEL="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 latex-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-flash-preview" \
-e EDIT_MODELS="gemini/gemini-3-flash-preview" \
-e BASE_PATH="/" \
-v $(pwd)/runs:/app/runs \
latex-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-flash-preview"
EDIT_MODELS: "gemini/gemini-3-flash-preview"
BASE_PATH: "/"
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)preview.png(if ImageMagick rendering succeeded)run.log.txt(all logs: LLM + pdflatex + magick)