avalon-cli
The command-line companion for the Avalon real-time web framework.
avalon-cli gets you from zero to a running, auto-reloading app in two commands:
avalon new scaffolds a project and avalon dev runs it, restarting the server
every time you save a file. It uses only the Python standard library and does not
import avalon itself, so it installs in seconds and works with any Avalon version
(or with no framework at all, via the static template).
Features
- Project scaffolding:
avalon newgenerates a ready-to-run project from a built-in template. - Auto-reloading dev server:
avalon devruns your dev command, watches files by polling (no native dependencies), and restarts the process on change. If the process crashes it waits for your fix and starts again on the next save, so you never have to restartavalon dev. - One config file:
avalon.tomlholds the dev command, host, port and watch rules, found by walking upward from the current directory. - Clean shutdown: Ctrl-C or SIGTERM always terminates the child process; nothing is orphaned.
- Zero dependencies: standard library only, Python 3.11+.
Install
pip install avalon-cli
This installs the avalon command. python -m avalon_cli works too.
Quickstart
avalon new chat-demo # Avalon app (default "minimal" template)
cd chat-demo
pip install avalon # the framework the generated app.py uses
avalon dev # http://127.0.0.1:8000/, reloads on save
No framework yet? The static template needs nothing but Python:
avalon new mysite --template static
avalon dev -C mysite --port 9000
Commands
All commands print errors as error: <message> on stderr and exit with status 1;
usage errors exit with status 2.
avalon new NAME [-t TEMPLATE] [-d DIRECTORY] [--force]
Create the directory DIRECTORY/NAME and fill it from a template.
| Option | Default | Meaning |
|---|---|---|
NAME |
(required) | Project name and directory name. Must start with a letter and contain only letters, digits, - and _. |
-t, --template |
minimal |
One of the templates listed by avalon templates. |
-d, --directory |
. |
Parent directory to create the project in. |
--force |
off | Write into an existing non-empty directory, overwriting files the template provides (other files are left alone). |
An existing empty directory is always accepted.
avalon templates
List the built-in templates:
| Template | Files | Notes |
|---|---|---|
minimal (default) |
avalon.toml, app.py, templates/index.html, README.md, .gitignore |
An Avalon app with one page and a WebSocket echo endpoint. Requires avalon. |
static |
avalon.toml, public/index.html, public/style.css, public/app.js, README.md, .gitignore |
Served by python -m http.server; no dependencies. |
avalon dev [-C PROJECT] [--host HOST] [-p PORT] [--interval SECONDS] [--no-reload]
Find avalon.toml (in PROJECT or any parent directory), start the configured dev
command from the project root, and restart it whenever a watched file is added,
modified or removed.
| Option | Default | Meaning |
|---|---|---|
-C, --project |
. |
Directory to start looking for avalon.toml. |
--host |
[dev].host |
Overrides the host. |
-p, --port |
[dev].port |
Overrides the port (1-65535). |
--interval |
[dev].interval |
Seconds between file-change polls. |
--no-reload |
off | Run the command once, without watching; avalon dev exits with the command's exit code. |
The child process receives AVALON_HOST, AVALON_PORT and AVALON_ENV=development
in its environment. With reloading on, avalon dev exits with status 0 on SIGTERM
and 130 on Ctrl-C.
avalon info [-C PROJECT]
Print the avalon-cli and Python versions and, if a project is found, its name,
root, fully-resolved dev command, address, watch paths and extensions.
avalon --version
Print avalon 0.2.0.
Configuration: avalon.toml
[project]
name = "chat-demo" # default: the directory name
[dev]
command = "{python} app.py" # placeholders: {host}, {port}, {python}
host = "127.0.0.1"
port = 8000
watch = ["."] # files or directories, relative to the project root
extensions = [".py", ".html", ".css", ".js", ".toml"] # [] watches every file
ignore = [".venv", ".git", "__pycache__", "node_modules"] # glob patterns matched against names
interval = 0.5 # seconds between polls
Every key is optional; the values above are the defaults. Extensions without a
leading dot get one ("py" becomes ".py"). Unknown keys in [dev] are rejected
so typos are caught early. The command is split shell-style before placeholders
are substituted, so a {python} path containing spaces stays a single argument.
{python} is the interpreter running avalon-cli.
Python API
Everything the CLI does is available from avalon_cli:
from avalon_cli import DevServer, build_command, create_project, load_config
result = create_project("chat-demo", template="minimal", parent=".", force=False)
print(result.root, result.template, result.files) # ScaffoldResult
config = load_config(result.root) # ProjectConfig(root, name, dev=DevConfig(...))
argv = build_command(config.dev.command, host=config.dev.host, port=config.dev.port)
server = DevServer(
argv,
cwd=config.root,
watch=config.dev.watch,
extensions=config.dev.extensions,
ignore=config.dev.ignore,
interval=config.dev.interval,
)
server.run() # blocks; pass a threading.Event to stop it from another thread
| Name | Description |
|---|---|
create_project(name, template="minimal", parent=".", *, force=False) -> ScaffoldResult |
Scaffold a project; raises ScaffoldError. |
load_config(start=".") -> ProjectConfig |
Locate and validate avalon.toml; raises ConfigError. |
find_project_root(start=".") -> Path |
Directory containing the nearest avalon.toml; raises ConfigError. |
build_command(template, *, host, port, python=None) -> list[str] |
Turn a dev command template into argv; raises ValueError. |
DevServer(argv, *, cwd=".", env=None, watch=(".",), extensions=(), ignore=(), interval=0.5, reload=True, log=...) |
Reloading process runner with start(), stop(timeout=5.0), restart(), poll_changes(), run(stop_event=None) -> int, and a restarts counter. |
take_snapshot(roots, extensions=(), ignore=()) -> dict[Path, int] |
File-to-mtime map of watched files. |
diff_snapshots(old, new) -> set[Path] |
Paths added, removed or modified between two snapshots. |
TEMPLATES, get_template(name), ProjectTemplate |
The built-in template registry. |
Development
python3 -m venv .venv && . .venv/bin/activate
pip install -e .
python -m unittest discover -s tests -t .
License
MIT
Metadata
Release files for avalon-cli 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| avalon_cli-0.2.0.tar.gz | 22.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| avalon_cli-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.1 kB
Release files / avalon_cli-0.2.0.tar.gz
| Download URL | avalon_cli-0.2.0.tar.gz |
|---|---|
| Size | 22.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8b73c635c4c59a0029185e815b7b8e78f0188fb4d83a3d8bb0665687f860e6e6
|
|
BLAKE2b-256 checksum How to use checksums |
f223283603ed1055c89b64ef91b03516433d9e3efb7a7ea006346ae40f954f98
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / avalon_cli-0.2.0-py3-none-any.whl
| Download URL | avalon_cli-0.2.0-py3-none-any.whl |
|---|---|
| Size | 17.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
65082b5be884184f5a28eca853d60833ec6b9afb54c6219491d2ab87d52ee9b4
|
|
BLAKE2b-256 checksum How to use checksums |
19df4916e53beb5ec2e185d8e110265fb06ccfebaf3e4f0dcc9d7209826cccab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|