Command-line guide¶
Status: Phase 7. The command and its options are the promise; the Python modules behind them are internal and may move in any release. See the stability guide.
The xyberos command exists so that four things a developer does over and over are one documented
line each: inspecting a composition, starting a project, running a server, and applying migrations.
It is a front door over APIs the runtime already proves — it never becomes a second implementation
of the runtime, never starts an application implicitly, and never ships a server.
Install and invoke¶
The console script is installed with the package, and python -m xyberos runs the same command for
the case where the script directory is not on PATH — an unactivated virtual environment, for
example.
| Command | What it wraps | Needs |
|---|---|---|
xyberos check |
Settings.load, App.validate, App.diagnostics |
core |
xyberos new |
nothing at all; it writes files | core |
xyberos run |
an ASGI server's own run, handed an import string |
an ASGI server |
xyberos migrate |
run_migrations / apply_migrations |
the database extra |
xyberos check¶
Loads settings and inspects an application without starting it. Validation is the same call the application makes at startup, so a successful check is evidence about the deployment rather than a second opinion.
settings: myapp (development), schema_version 1, debug False
application: myapp.app:create_app
provider graph: valid
providers:
ItemService [app] from application
ItemRepository [request] from application
plugins:
(none)
routes: 6 (handler signatures valid)
--config PATHinspects a specificxyberos.tomlinstead of the discovered one.--app MODULE:ATTRIBUTEnames the application to inspect. A factory is expected, because anApponly exists once something constructs it; it is called, and nothing in it is started, so no service is constructed and no connection is opened.--app-dir DIRmakes asrclayout importable without installing it — the same escape hatch the ASGI server offers.- Route handlers are compiled through the adapter when the
httpextra is installed, which is what catches a bad handler signature offline. Without the extra, the count is reported as not compiled rather than as a failure, because an application with no routes is a legitimate application. - It is read-only: nothing is written, started, or imported beyond the target.
xyberos new¶
Writes a minimal project that already runs: a composition root, one service, two routes, a settings
file, a test, and a .gitignore.
xyberos new billing
cd billing
python -m pip install -e ".[http,dev]" uvicorn
pytest
xyberos check --app billing.app:create_app --app-dir src
- The name must be a valid lower-case Python identifier, because the distribution name and the import name are the same here.
- An existing non-empty directory is never overwritten.
--forcewrites into one, and is only for the case where you have already decided the contents do not matter. - The generated project is the same shape the getting started guide describes, so the code you read while scaffolding is the code you keep.
xyberos run¶
Hands an import string to an ASGI server and owns nothing else.
xyberos run --app billing.app:asgi_app --app-dir src --reload
xyberos run --app sqlite_crud.app:app_factory --factory --app-dir examples --port 9000
- The server is not a dependency. If none is installed, the command says so and names the install; it will not choose one for you.
- The target is passed to the server as an import string, so the server keeps ownership of
reloading, workers, and graceful shutdown.
--reloadtherefore works exactly as it does without this command, and--app-dirmeans the same thing it means there. --factoryis for a target that builds the application when called.- Nothing is imported on the application's behalf, which is precisely what keeps
--reloadcorrect.
xyberos migrate¶
Applies Alembic revisions from a directory to a database URL, at deploy time, explicitly.
- The URL is the synchronous one, because Alembic's engine is synchronous.
--asyncapplies inside an event loop, for a caller that is already there.- A password in the URL is never printed. The success line quotes a redacted form, and a failure is reported as this command's own message with the URL and every encoding of its password scrubbed out — because a traceback is the ordinary way a configured value ends up in a CI log. A URL containing a percent sign works rather than failing, which it did not always.
- Migrations are never applied at application startup, and this command does not change that: it is the explicit deploy step, not an implicit one.
Exit codes¶
| Code | Meaning |
|---|---|
0 |
the command did what it said |
1 |
the command failed — invalid configuration, a missing server, a failed migration |
2 |
what you asked for is wrong — an unimportable target, a missing attribute, a bad name |
The distinction is there so a script can tell a typo from a broken deployment without parsing the
message. Failures are printed to standard error as xyberos: error: ...; a command's report goes to
standard output.
What the CLI will not do¶
- It will not import your application to run it. Only
checkimports the target, and only to validate it; the server does its own importing so reloading works. - It will not start an application implicitly. There is no command that starts an
Appand serves it through a Xyberos-owned server, because a second serving path is a second set of bugs. - It will not manage your environment. No dependency resolution, no model downloads, no service installation.
- It is not the only way to do anything. Every command has a documented equivalent that does not
involve the CLI at all;
checkisApp.validate()plusApp.diagnostics(), andrunis whatever your ASGI server already does.