Python API#
This page documents the programmatic surface of the mymodel package.
It covers the server entry points, the management HTTP API contract, the configuration knobs, and the error behavior.
The mymodel package contains no inference endpoints of its own.
Chat completions, embeddings, and streaming are served by the vLLM subprocesses that the launcher starts.
See Serving with vLLM for the operational guide and Model Catalogue for the catalogue class reference.
I Module Layout#
Module |
Public symbols |
Purpose |
|---|---|---|
|
|
Catalogue-driven launcher and management API |
|
|
JWT authentication and TLS configuration |
|
|
Shared constants resolved from the environment |
|
|
The model catalogue (Model Catalogue) |
mymodel/__init__.py is empty, so import symbols from their own modules, for example from mymodel.serve import Semioserve.
II Starting the Server#
From the command line#
The only entry point is the module runner.
mymodel/__main__.py delegates to mymodel.serve.main(), and pyproject.toml defines no console script.
uv run python -m mymodel <model> [<model> ...] [options]
Each model spec is a catalogue name, optionally prefixed with its verb as VERB:name.
Only the part after the first colon is used for the lookup, so CHAT:gemma_md and gemma_md resolve to the same card.
A name that is not in the catalogue raises a KeyError at startup, before any server listens.
Argument |
Default |
Description |
|---|---|---|
|
(required, one or more) |
Catalogue model names to serve, one vLLM server each |
|
|
Host for the management API and the vLLM servers |
|
|
Management API port |
|
|
Development mode (disables JWT auth) |
|
|
Local root directory |
|
|
Catalogue YAML file |
Each model gets its own port.
The first model listens on --port + 1, the second on --port + 2, and so on.
From Python#
The same launcher is a class, so embedding it in another program is direct:
import asyncio
from mymodel.serve import Semioserve
asyncio.run(Semioserve(models=['gemma_md']).run())
Semioserve is a singleton.
Its __new__ returns the existing instance on repeated construction, because the Quart routes read the instance as a singleton.
The constructor accepts the same knobs as the CLI: models, host, port, dev_mode, directory, and catalogue.
What happens at startup#
Validate the root directory layout. The directories
models,logs,metrics, anddatamust already exist under--directory, or startup raises anAssertionError.Load the catalogue YAML file into a
Registry.Resolve each requested model spec to a
ModelCard, raisingKeyErrorfor unknown names.Create one
VLLMServerper model, with ports assigned in request order.Configure TLS for the management API if a certificate pair exists under
<directory>/ssl.Launch each
vllm servesubprocess, then serve the management API until SIGTERM arrives. SIGTERM stops every vLLM subprocess before the process exits.
VLLMServer.start() does not block on readiness.
A large model can take tens of seconds to load.
GET /models reports the live health of each server in the meantime.
III The Management HTTP API#
The management API is a Quart application bound to --host:--port.
It exposes two GET endpoints.
Quart serializes the returned dicts as JSON.
Endpoint |
Method |
Description |
|---|---|---|
|
GET |
Liveness of the management API itself |
|
GET |
Active servers with live health, plus the catalogue |
GET /health#
Returns a static payload. It does not probe the vLLM servers.
{"status": "ok", "models": 1}
The models field counts the configured vLLM servers, healthy or not.
GET /models#
Polls each vLLM server’s /health endpoint and reports the result per model.
{
"active": {
"gemma_md": {
"verb": "chat",
"url": "http://localhost:5001/v1",
"healthy": true
}
},
"catalogue": ["gemma_md", "..."]
}
activemaps each served model name to its verb, its OpenAI-compatible base URL, and a live health boolean.cataloguelists every model name in the loaded catalogue, sorted, whether served or not.
A vLLM server that is still loading reports "healthy": false until its /health endpoint answers with status 200.
Error shapes#
The management API defines a small error surface:
401 Unauthorized. In production mode, a missing, malformed, expired, or mis-issued token gets a
401with atext/plainbody ofUnauthorized.Startup errors. An unknown model name raises
KeyErrorand a missing root directory raisesAssertionError. Both abort the process before the API listens, so they never surface as HTTP responses.vLLM failures. Errors from the model servers themselves appear in the subprocess logs, not in the management API. The only signal the API gives is
"healthy": falsefromGET /models.
Streaming#
The management API has no streaming endpoints.
Streaming inference, such as server-sent events from /v1/chat/completions with "stream": true, is served by the vLLM subprocesses directly.
IV Configuration#
Environment variables#
Variable |
Default |
Effect |
|---|---|---|
|
|
Selects the |
|
|
Default for |
|
|
Default for |
|
(required) |
Default for |
|
(empty) |
When set, passed to every vLLM server as |
|
(required in production) |
HMAC secret for JWT verification |
|
(required in production) |
Expected |
CLI arguments take precedence over the environment defaults they mirror.
Directory layout#
The root directory must contain models, logs, metrics, and data before startup.
Local model weights live under models.
A card whose weights exist on disk is served from that path, otherwise vLLM fetches the HuggingFace id.
TLS#
If both <directory>/ssl/server.crt and <directory>/ssl/server.key exist, the management API is served over TLS.
In development mode an optional <directory>/ssl/ca.crt is also loaded into the server configuration.
Without a certificate pair, the API falls back to plain HTTP.
See Auth & TLS for certificate setup.
V Authentication#
Authentication is posture-dependent, controlled by OpsStance:
Development (
--dev_mode, the default whileNUCLEUS_MODEstarts withdev). The management API serves without authentication.Production (
NUCLEUS_MODEset to anything else, without--dev_mode).AuthMiddlewarewraps the ASGI application and verifies a Keycloak-issued JWT on every connection.
Production clients pass the token as an Authorization: Bearer <token> header on HTTP requests, or as an ?auth=<token> query parameter on websocket connections.
Tokens are HMAC-signed with HS512 and verified against KEYCLOAK_SECRET.
The iss claim must equal KEYCLOAK_ISSUER, the aud claim must be nexus, and the token must be unexpired.
Failures return the 401 shape described above.
Full key issuance and hardening steps live in Auth & TLS.
VI Examples#
Query the management API with curl:
curl http://localhost:5000/health
curl http://localhost:5000/models
In production mode, add the token header:
curl -H "Authorization: Bearer $TOKEN" http://localhost:5000/models
Use the package’s existing aiohttp dependency to make the same calls from Python:
import asyncio
import aiohttp
async def main():
async with aiohttp.ClientSession() as session:
async with session.get('http://localhost:5000/models') as resp:
status = await resp.json()
for name, server in status['active'].items():
print(f"{name}: {server['url']} healthy={server['healthy']}")
asyncio.run(main())
VII See also#
Serving with vLLM: the operational guide for catalogue concepts, GPU sizing, and troubleshooting.
Model Catalogue: the
RegistryandModelCardAPI for listing, adding, and enriching models.The LiteLLM Gateway: the proxy that fronts the vLLM servers with one OpenAI-compatible endpoint.
Auth & TLS: JWT issuance, TLS setup, and production hardening.