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.
128 lines
2.8 KiB
Markdown
128 lines
2.8 KiB
Markdown
# 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:
|
|
|
|
```bash
|
|
uv sync
|
|
```
|
|
|
|
## Configure LLM
|
|
|
|
This project uses LiteLLM with Google Gemini models.
|
|
|
|
Set credentials (common case):
|
|
|
|
```bash
|
|
export GOOGLE_API_KEY="..."
|
|
```
|
|
|
|
Defaults (comma-separated fallback order):
|
|
|
|
- `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`
|
|
|
|
Override if you want:
|
|
|
|
```bash
|
|
export LLM_MODELS="gemini/gemini-3-flash-preview"
|
|
export EDIT_MODELS="gemini/gemini-3-flash-preview"
|
|
```
|
|
|
|
## Run
|
|
|
|
### Option A: run via Python entrypoint
|
|
|
|
```bash
|
|
uv run python main.py
|
|
```
|
|
|
|
### Option B: run via uvicorn (recommended for dev)
|
|
|
|
```bash
|
|
uv run uvicorn main:app --reload
|
|
```
|
|
|
|
Open:
|
|
|
|
- http://127.0.0.1:8000
|
|
|
|
## Docker
|
|
|
|
Single-stage `python:3.12-slim` + `uv` with cached dependency layer. BuildKit is required for cache mounts.
|
|
|
|
Build locally:
|
|
|
|
```bash
|
|
docker build -t diagram-to-tikz .
|
|
```
|
|
|
|
### Run with Docker
|
|
|
|
```bash
|
|
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):
|
|
|
|
```yaml
|
|
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:
|
|
|
|
```bash
|
|
docker compose up --build
|
|
```
|
|
|
|
## Outputs
|
|
|
|
Each request creates a folder under `runs/<run_id>/` containing:
|
|
|
|
- `original.*` (your upload)
|
|
- `diagram.tex`
|
|
- `diagram.pdf` (if LaTeX compilation succeeded)
|
|
- `diagram.png` (if ImageMagick rendering succeeded)
|
|
- `run.log.txt` (all logs: LLM + pdflatex + magick)
|