An example HTTP server demonstrating how to build image experiences on top of the
trueblocks-dalle
Go package.
It turns Ethereum addresses into consistently generated, stylistically filtered ("series") images. This repo shows a server approach; a companion desktop / direct usage example can build images without HTTP by calling the same library functions.
Developers often ask: "How do I actually use the trueblocks-dalle
module in a program?"
This code answers that by demonstrating:
- Discovering and validating a "series" (prompt filter set) at runtime
- Generating prompts (data / title / terse / full / enhanced) for an address
- Optionally enhancing prompts via OpenAI (LLM) with timeouts + fallbacks
- Generating and annotating DALL·E images (or skipping in offline mode)
- Caching + locking so concurrent requests don’t stampede
- Exposing a REST API and a gallery preview page
- Testing, linting, benchmarking and baseline capture
If you only need library usage, jump to Direct library usage.
git clone https://github.com/TrueBlocks/trueblocks-dalleserver.git # or: git clone [email protected]:TrueBlocks/trueblocks-dalleserver.git
cd trueblocks-dalleserver
cp .env.example .env # create and edit (.env is auto-loaded)
make run # builds then starts :8080
open http://localhost:8080/preview
List available series:
curl http://localhost:8080/series
Fetch (or trigger) an image:
open "http://localhost:8080/dalle/simple/0xf503017d7baf7fbc0fff7492b751025c6a78179b?generate=1"
Preview gallery:
http://localhost:8080/preview
Command | Purpose |
---|---|
make run |
Build + run server on :8080 |
make lint |
Install + run golangci-lint (pinned) |
make test |
Run tests (image generation skipped) |
make race |
Run race detector tests (skip image) |
make bench |
Run all benchmarks (skip image) |
make benchmark |
Focused benchmark target |
make bench-baseline |
Produce timestamped JSON benchmark artifacts (benchmarks/*.json) |
make clean-output |
Remove generated PNGs |
Variable | Description | Default |
---|---|---|
OPENAI_API_KEY |
Key for enhancement + DALL·E image calls (required unless skipping) | (none) |
DALLESERVER_SKIP_IMAGE |
1 to skip actual image generation (offline / fast tests) |
unset |
DALLESERVER_NO_ENHANCE |
1 to disable LLM enhancement (use raw prompt) |
unset |
DALLESERVER_ENHANCE_TIMEOUT |
Override enhance prompt timeout (e.g. 75s ) |
60s |
DALLESERVER_IMAGE_TIMEOUT |
Timeout for image request + download | 30s |
DALLE_QUALITY |
DALL·E quality parameter (standard , hd , etc.) |
standard |
Example (fish shell):
set -x OPENAI_API_KEY "sk-..."
make run
Or use a local .env
file (preferred for development):
cp .env.example .env
edit .env # populate OPENAI_API_KEY and options
make run
Offline/dev mode:
set -x DALLESERVER_SKIP_IMAGE 1; make run
Path | Description |
---|---|
/dalle/<series>/<address> |
Returns annotated image if complete; otherwise a JSON progress snapshot (add ?generate=1 to start/force generation). |
/series |
Lists available series names. |
/preview |
HTML gallery of annotated images (filterable). |
/files/... |
Static access to generated output tree. |
/healthz |
Basic health probe JSON. |
/metrics |
Placeholder metrics endpoint. |
While a generation is in progress the /dalle/...
response looks like (truncated):
{
"series": "simple",
"address": "0x...",
"currentPhase": "image_wait",
"percent": 42.7,
"etaSeconds": 11.3,
"done": false,
"cacheHit": false
}
Poll the same URL until "done": true
; then re-request (optionally without ?generate=1
) to fetch the final PNG.
All runtime artifacts live under a configurable base "data directory" resolved via:
--data-dir
flagDALLESERVER_DATA_DIR
env var- Default:
$HOME/.local/share/trueblocks/dalle
Derived sub-directories (created automatically):
<dataDir>/
output/
<series>/
data/ # Raw data prompt
title/ # Title prompt
terse/ # Short prompt
prompt/ # Full prompt
enhanced/ # Enhanced (LLM) prompt text
annotated/ # Final PNG images (watermarked)
series/ # JSON series definition files
logs/ # Rotating server logs (lumberjack)
The server fails fast on startup if the data directory cannot be created or written.
If you want to skip the server and just integrate image generation, import the package:
import (
dalle "github.com/TrueBlocks/trueblocks-dalle/v2"
"time"
)
func generateOne(series, addr string, dataDir string) error {
outputDir := filepath.Join(dataDir, "output")
_ = os.MkdirAll(outputDir, 0o755)
_, err := dalle.GenerateAnnotatedImage(series, addr, outputDir, false /* skipImage */, 30*time.Second)
return err
}
Or inside this server, prefer the helpers: app.OutputDir()
and app.SeriesDir()
.
Logging uses a single rotating file (default max 50MB, 5 backups, 30d retention) located at <dataDir>/logs/server.log
plus a mirror to stderr.
Override max size for testing via env: DALLESERVER_LOG_MAX_MB
.
Removed prior zap dependency for simpler deployment; JSON logging mode no longer supported.
Set skipImage
true (or DALLESERVER_SKIP_IMAGE=1
) for fast / offline usage.
See .env.example
included in the repo for a documented starter file.
Key server concerns illustrated here:
- Per-(series,address) locking + TTL to avoid duplicate work
- Simple context + prompt caching inside the
trueblocks-dalle
library - Timeouts on enhancement + image requests (configurable)
- Prompt + image phase logging (start/end + elapsed)
- Lint (golangci-lint) pinned version for reproducibility
- Benchmarks + baseline JSON artifacts for regression tracking
- Graceful shutdown and HTTP server timeouts (Slowloris protection)
make lint # runs golangci-lint
make test # skips network/image by setting DALLESERVER_SKIP_IMAGE=1 internally
Run a single benchmark:
go test -bench=BenchmarkGenerateAnnotatedImage -run=^$ ./...
Capture a baseline JSON (for dashboards / diffing):
make bench-baseline
Symptom | Likely Cause | Fix |
---|---|---|
Immediate exit: OPENAI_API_KEY not set |
Missing key & not in skip mode | Export key or set DALLESERVER_SKIP_IMAGE=1 |
Enhancement timeout | Model slow / low timeout | Increase DALLESERVER_ENHANCE_TIMEOUT |
Blank preview page | No images yet | Trigger generation (?generate=1 ) |
404 under /files/ |
File not generated yet | Wait for generation to complete |
GNU GPL v3 (or later). See LICENSE
.
PRs welcome. Please see the core project’s branching workflow for consistency.
- Fork & branch.
- Make changes + add tests when practical.
make lint test
must pass.- Open PR.
Questions / ideas / complaints: join our Discord (linked from https://trueblocks.io).
Thanks to: