synth-containers
The task contract for Synth optimizers and evals — wrap any task as a small HTTP service that optimizers can target without touching your code.
PyPI · Optimizers · Cookbooks
A Synth container is a small HTTP service around a task. It owns the dataset, the
scoring/verifier logic, the mutable prompt or policy fields, and the policy-model
credential boundary. An optimizer like
synth-optimizers GEPA sees one URL
and a typed rollout contract — it never imports your task package or reads private
evaluator state. The same contract works whether the task is a classifier, a coding
agent, or a live game environment, and in Python, Rust, or TypeScript.
Install
pip install synth-containers
# or
uv add synth-containers
Tested pair: synth-optimizers==0.2.22 pins and is tested against
synth-containers==0.4.3; both are published on PyPI.
Development
git clone https://github.com/synth-laboratories/containers.git
cd containers
uv sync --group dev
uv run --group dev pytest tests
The contract
| Route | Method | Purpose |
|---|---|---|
/metadata |
GET | contract version + capabilities |
/program |
GET | mutable prompt fields + seed candidate |
/dataset |
GET | split names + row counts |
/dataset/rows |
POST | rows for a requested seed list |
/rollout |
POST | run a candidate on a row → reward + usage |
/health |
GET | liveness |
The Python SDK also provides Container, Container.serve(),
ContainerHandle, ContainerConnection, and ContainerRunner (url, command,
in-process app, or local image_id). CLI: synth-containers serve and
synth-containers up.
Runnable local example (no provider credentials)
After pip install synth-containers, save this as smoke.py and run
python smoke.py. It starts a loopback-only server, scores a deterministic
exact-match task, prints reward: 1.0, and shuts the server down. This is an
SDK/HTTP smoke test, not a model-quality evaluation.
from datetime import datetime, timezone
import httpx
from synth_containers import Container
container = Container("local-exact-match", default_submission_mode="sync")
@container.rollout
def rollout(payload):
now = datetime.now(timezone.utc).isoformat()
reward = float(payload["answer"] == payload["expected"])
return {
"rollout_id": payload["rollout_id"],
"status": "completed", "success_status": "success",
"created_at": now, "updated_at": now,
"summary": {"reward": reward},
}
with container.serve() as running:
with httpx.Client(timeout=10, trust_env=False) as client:
response = client.post(running.url + "/rollouts", json={
"rollout_id": "smoke-1", "answer": "hello", "expected": "hello",
})
response.raise_for_status()
result = response.json()
assert result["status"] == "completed"
assert result["summary"]["reward"] == 1.0
print("reward:", result["summary"]["reward"])
See the cookbooks for complete containers: Banking77, HotpotQA, MiniGrid, TBLite, and Crafter.
Links
- Optimizers — GEPA on this contract
- Cookbooks — runnable containers
- Agent skill — drop into a coding agent to build and debug containers
- Contract OpenAPI
- Immutable live policy revisions — install multiple harness variants and pin each rollout explicitly
License
MIT
Metadata
Release files for synth-containers 0.4.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| synth_containers-0.4.6.tar.gz | 1.1 MB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| synth_containers-0.4.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.1 MB
Release files / synth_containers-0.4.6.tar.gz
| Download URL | synth_containers-0.4.6.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fb850662fd53c713c2ed97bc0838c4d9acbcb45df4f4502c4601489112784152
|
|
BLAKE2b-256 checksum How to use checksums |
c0d6bab6cbcba183e62cdc417c1e2e26cc92ccc5702bc0b19d7f9dfd3506b3c1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.33 {"installer":{"name":"uv","version":"0.11.33","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / synth_containers-0.4.6-py3-none-any.whl
| Download URL | synth_containers-0.4.6-py3-none-any.whl |
|---|---|
| Size | 967.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5c55a8908d34b513b4b59a14dbe2e5417000bf9ab96772fb8edbaad6f002c8b9
|
|
BLAKE2b-256 checksum How to use checksums |
21a718f3d9bbb854396197431fe4c3f8201e17e08ad66bbded1b9e7be1a30276
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.33 {"installer":{"name":"uv","version":"0.11.33","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for synth-containers 0.4.6
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.