Add REST API for preset-based generation and fallback cover images
REST API (routes/api.py): Three endpoints behind API key auth for programmatic image generation via presets — list presets, queue generation with optional overrides, and poll job status. Shared generation logic extracted from routes/presets.py into services/generation.py so both web UI and API use the same code path. Fallback covers: library index pages now show a random generated image at reduced opacity when no cover is assigned, instead of "No Image". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
23
CLAUDE.md
23
CLAUDE.md
@@ -27,6 +27,7 @@ services/
|
||||
sync.py # All sync_*() functions + preset resolution helpers
|
||||
job_queue.py # Background job queue (_enqueue_job, _make_finalize, worker thread)
|
||||
file_io.py # LoRA/checkpoint scanning, file helpers
|
||||
generation.py # Shared generation logic (generate_from_preset)
|
||||
routes/
|
||||
__init__.py # register_routes(app) — imports and calls all route modules
|
||||
characters.py # Character CRUD + generation + outfit management
|
||||
@@ -44,6 +45,7 @@ routes/
|
||||
strengths.py # Strengths gallery system
|
||||
transfer.py # Resource transfer system
|
||||
queue_api.py # /api/queue/* endpoints
|
||||
api.py # REST API v1 (preset generation, auth)
|
||||
```
|
||||
|
||||
### Dependency Graph
|
||||
@@ -60,7 +62,8 @@ app.py
|
||||
│ ├── mcp.py ← (stdlib only: subprocess, os)
|
||||
│ ├── sync.py ← models, utils
|
||||
│ ├── job_queue.py ← comfyui, models
|
||||
│ └── file_io.py ← models, utils
|
||||
│ ├── file_io.py ← models, utils
|
||||
│ └── generation.py ← prompts, workflow, job_queue, sync, models
|
||||
└── routes/
|
||||
├── All route modules ← services/*, utils, models
|
||||
└── (routes never import from other routes)
|
||||
@@ -77,6 +80,8 @@ SQLite at `instance/database.db`, managed by Flask-SQLAlchemy. The DB is a cache
|
||||
|
||||
**Models**: `Character`, `Look`, `Outfit`, `Action`, `Style`, `Scene`, `Detailer`, `Checkpoint`, `Settings`
|
||||
|
||||
The `Settings` model stores LLM provider config, LoRA/checkpoint directory paths, default checkpoint, and `api_key` for REST API authentication.
|
||||
|
||||
All category models (except Settings and Checkpoint) share this pattern:
|
||||
- `{entity}_id` — canonical ID (from JSON, often matches filename without extension)
|
||||
- `slug` — URL-safe version of the ID (alphanumeric + underscores only, via `re.sub(r'[^a-zA-Z0-9_]', '', id)`)
|
||||
@@ -180,6 +185,10 @@ LoRA nodes chain: `4 → 16 → 17 → 18 → 19`. Unused LoRA nodes are bypasse
|
||||
- **`get_available_checkpoints()`** — Scans checkpoint directories.
|
||||
- **`_count_look_assignments()`** / **`_count_outfit_lora_assignments()`** — DB aggregate queries.
|
||||
|
||||
### `services/generation.py` — Shared Generation Logic
|
||||
|
||||
- **`generate_from_preset(preset, overrides=None)`** — Core preset generation function used by both the web route and the REST API. Resolves entities, builds prompts, wires the workflow, and enqueues the job. The `overrides` dict accepts: `action`, `checkpoint`, `extra_positive`, `extra_negative`, `seed`, `width`, `height`. Has no `request` or `session` dependencies.
|
||||
|
||||
### `services/mcp.py` — MCP/Docker Lifecycle
|
||||
|
||||
- **`ensure_mcp_server_running()`** — Ensures the danbooru-mcp Docker container is running.
|
||||
@@ -351,6 +360,15 @@ Each category follows the same URL pattern:
|
||||
- `POST /checkpoint/<slug>/save_json`
|
||||
- `POST /checkpoints/rescan`
|
||||
|
||||
### REST API (`/api/v1/`)
|
||||
Authenticated via `X-API-Key` header (or `api_key` query param). Key is stored in `Settings.api_key` and managed from the Settings page.
|
||||
- `GET /api/v1/presets` — list all presets (id, slug, name, has_cover)
|
||||
- `POST /api/v1/generate/<preset_slug>` — queue generation from a preset; accepts JSON body with optional `checkpoint`, `extra_positive`, `extra_negative`, `seed`, `width`, `height`, `count` (1–20); returns `{"jobs": [{"job_id": ..., "status": "queued"}]}`
|
||||
- `GET /api/v1/job/<job_id>` — poll job status; returns `{"id", "label", "status", "error", "result"}`
|
||||
- `POST /api/key/regenerate` — generate a new API key (Settings page)
|
||||
|
||||
See `API_GUIDE.md` for full usage examples.
|
||||
|
||||
### Job Queue API
|
||||
All generation routes use the background job queue. Frontend polls:
|
||||
- `GET /api/queue/<job_id>/status` — returns `{"status": "pending"|"running"|"done"|"failed", "result": {...}}`
|
||||
@@ -378,7 +396,7 @@ Image retrieval is handled server-side by the `_make_finalize()` callback; there
|
||||
- Global default checkpoint selector (saves to session via AJAX)
|
||||
- Resource delete modal (soft/hard) shared across gallery pages
|
||||
- `initJsonEditor(saveUrl)` — shared JSON editor modal (simple form + raw textarea tabs)
|
||||
- Context processors inject `all_checkpoints`, `default_checkpoint_path`, and `COMFYUI_WS_URL` into every template.
|
||||
- Context processors inject `all_checkpoints`, `default_checkpoint_path`, and `COMFYUI_WS_URL` into every template. The `random_gen_image(category, slug)` template global returns a random image path from `static/uploads/<category>/<slug>/` for use as a fallback cover when `image_path` is not set.
|
||||
- **No `{% block head %}` exists** in layout.html — do not try to use it.
|
||||
- Generation is async: JS submits the form via AJAX (`X-Requested-With: XMLHttpRequest`), receives a `{"job_id": ...}` response, then polls `/api/queue/<job_id>/status` every ~1.5 seconds until `status == "done"`. The server-side worker handles all ComfyUI polling and image saving via the `_make_finalize()` callback. There are no client-facing finalize HTTP routes.
|
||||
- **Batch generation** (library pages): Uses a two-phase pattern:
|
||||
@@ -386,6 +404,7 @@ Image retrieval is handled server-side by the `_make_finalize()` callback; there
|
||||
2. **Poll phase**: All jobs are polled concurrently via `Promise.all()`, updating UI as each completes
|
||||
3. **Progress tracking**: Displays currently processing items in real-time using a `Set` to track active jobs
|
||||
4. **Sorting**: All batch operations sort items by display `name` (not `filename`) for better UX
|
||||
- **Fallback covers** (library pages): When a resource has no assigned `image_path` but has generated images in its upload folder, a random image is shown at 50% opacity (CSS class `fallback-cover`). The image changes on each page load. Resources with no generations show "No Image".
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user