Development
Everything except the image builds runs inside a dev container, so the host needs only Docker and Make. make help lists every target.
Layout
| Path | What it holds |
|---|---|
| src/flickies/server.py | The FastAPI app, every route, the input/output contract, async job scheduling, error handlers. |
src/flickies/mcp_server.py | The FastMCP server mounted at /v1/mcp. |
src/flickies/engines/ | base.py (the engine lifecycle), _registry.py (hot-swap and idle unload), _license_gate.py, and one module per executor: wav2lip.py, latentsync.py, gfpgan.py. |
src/flickies/ffmpeg.py | Every ffmpeg and ffprobe call. |
src/flickies/files.py, fetch.py | Staging-area paths and uploads; URL downloads, presigned PUTs and the private address guard. |
src/flickies/jobs.py, webhooks.py | In-memory async jobs; signed webhook delivery with retries. |
src/flickies/auth.py, middleware.py | Bearer auth; request ids, rate limit, idempotency. |
src/flickies/config.py, logging_config.py, prefetch.py | Startup settings, JSON logging, the boot weight download. |
src/flickies/schema/ | Pydantic models generated from openapi.yaml. The routes do not use them; request bodies are plain dicts. |
src/flickies/_vendor/ | Vendored LatentSync 1.5 and Wav2Lip source. See THIRD_PARTY.md. |
| openapi.yaml | The REST contract. |
engines.json | The engine registry baked into the images. |
pkg/clients/go/, pkg/clients/python/ | Generated clients (Generated clients). |
Dockerfile, Dockerfile.cuda, Dockerfile.dev, entrypoint.sh | CPU image, CUDA image, dev image, container startup. |
scripts/ | Dependency compilation, the exclude-newer bump and model generation. |
tests/ | Unit tests. |
docs/ | This site. |
.agents/ | The agent skill, the OpenClaw plugin and the Claude Code and Codex plugin manifests. |
Make targets
| Target | What it does |
|---|---|
make dev-image | Builds psyb0t/flickies-dev:latest from Dockerfile.dev: Python 3.12, uv, ruff, pyright, pytest, the generators and Go. Every dev target depends on it. |
make shell | Interactive shell in the dev container. |
make lint | ruff check src tests, ruff format --check src tests, pyright src. |
make format | ruff format then ruff check --fix. |
make test, make test-unit | pytest tests/ with coverage. |
make test-unit-cov-gate | Fails below 80% line coverage on the config, engine base, license gate and registry modules. |
make check | lint then test. |
make build, make build-cuda, make build-all | Builds the CPU and CUDA images, tagged v<version> and latest (with -cuda). |
make run, make run-cuda | Builds and runs an image on PORT (default 8000) with ~/.flickies-data as /data. |
make docs | Builds this site with GitHub’s Pages image into .testing/docs-site. |
make version | Prints v and the version in pyproject.toml. |
make clean | Removes the local images and Python caches. |
Tests
Unit tests run offline in the dev image, which has no ML stack. They exercise routing, the error envelope, auth, file staging, jobs, the middleware and the license gate, and run real ffmpeg for info and trim (skipped if ffmpeg is missing). Engine inference is not covered.
make test-integration runs pytest on tests/integration/ on the host. That directory holds only an empty package today, so there is no integration suite.
Code generation
openapi.yaml is the source for the server models and both clients, and the generated files are committed:
make generate # all three
make generate-models # src/flickies/schema/_generated.py
make generate-client-go # pkg/clients/go/client.gen.go
make generate-client-python # pkg/clients/python/flickies-client/
make generate-check # fails if the generated files differ from git
Never edit generated files. Change openapi.yaml, run make generate, and commit the spec and the output together.
Dependencies
Light runtime dependencies are in pyproject.toml and uv.lock. Change them only through make pkg-add PKG=..., pkg-remove, pkg-update or pkg-upgrade, which first move the exclude-newer date in pyproject.toml to seven days ago so the resolver never sees a release younger than a week.
The ML stack (torch, OpenCV, librosa, GFPGAN and, for CUDA, the LatentSync libraries) lives in scripts/heavy-deps-cpu.in and scripts/heavy-deps-cuda.in. make pkg-compile-heavy compiles them into requirements-heavy-cpu.txt and requirements-heavy-cuda.txt, which the Dockerfiles install.
CI and releases
.github/workflows/pipeline.yml runs on every push:
- every branch:
make lintandmake test; - the default branch, after those pass: build, scan and push both images as
latestandsha-<commit>(each with-cudafor the CUDA image), and refresh the README badges; - a
v*tag: wait for that commit’s default-branch run to succeed, re-tag the same images asvX.Y.ZandvX.Y.Z-cudawithout rebuilding, create the GitHub release, publish the skill and plugin to ClawHub, and publishserver.jsonto the MCP Registry.
A tag therefore only releases a commit that is already on the default branch with a green pipeline. Other workflows close outside pull requests (collaborators-only.yml), mirror and archive the repository (mirror-and-archive.yml), and copy issues back from the mirrors (issue-pull.yml).
Changes are listed in CHANGELOG.md.