tempestweb.cli¶
The implementation behind the tempestweb command — new, build, dev, deploy, gen, sync. Documented for calling a command from Python or extending the CLI; to use it in a terminal, the usage page is the right place.
Guide with examples: Using the CLI.
tempestweb.cli ¶
tempestweb.cli — the tempestweb command-line tool.
The CLI drives the whole developer loop in typed Python: new scaffolds a
runnable project, dev watches and triggers reloads, build emits a
mode-specific artifact, and run builds then serves. See docs/plan.md §5.
Public symbols (the parser, every command entrypoint, the config/loader/scaffold helpers) are re-exported here so callers import at the package level rather than reaching into submodules.
BuildError ¶
BuildResult
dataclass
¶
The outcome of a build.
Attributes:
| Name | Type | Description |
|---|---|---|
mode |
str
|
The execution mode that was built ( |
out_dir |
Path
|
The artifact root directory. |
files |
tuple[str, ...]
|
Artifact-relative paths that were written, in a stable order. |
Source code in tempestweb/cli/commands/build.py
DeployError ¶
DeployResult
dataclass
¶
The outcome of scaffolding deploy files.
Attributes:
| Name | Type | Description |
|---|---|---|
out_dir |
Path
|
The directory the files were written to. |
files |
tuple[str, ...]
|
The relative file names written. |
Source code in tempestweb/cli/commands/deploy.py
DevError ¶
DevSession
dataclass
¶
A ready-to-run dev session: watcher + signal + transport, all wired.
Attributes:
| Name | Type | Description |
|---|---|---|
config |
ProjectConfig
|
The resolved project config. |
mode |
str
|
The execution mode for this session. |
signal |
ReloadSignal
|
The reload hub the watcher triggers. |
watcher |
FileWatcher
|
The file watcher observing the project root. |
transport |
StubTransport
|
The reload sink (a :class: |
Source code in tempestweb/cli/commands/dev.py
NewError ¶
RunError ¶
RunPlan
dataclass
¶
A built artifact plus the bind plan for serving it.
Attributes:
| Name | Type | Description |
|---|---|---|
build |
BuildResult
|
The artifact produced for this run. |
host |
str
|
The bind address ( |
port |
int
|
The bind port. |
Source code in tempestweb/cli/commands/run.py
url
property
¶
Return the local URL the served app will be reachable at.
Returns:
| Type | Description |
|---|---|
str
|
An |
StubTransport
dataclass
¶
A transport-agnostic reload sink used until a real transport plugs in.
Records every reload it receives. A real transport (browser reload for Mode
A, session restart for Mode B) replaces this by subscribing to the same
:class:ReloadSignal.
Attributes:
| Name | Type | Description |
|---|---|---|
mode |
str
|
The execution mode this transport stands in for. |
reloads |
list[ReloadEvent]
|
Every reload event received, in order. |
Source code in tempestweb/cli/commands/dev.py
on_reload ¶
Handle a reload event by recording it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
ReloadEvent
|
The reload event emitted by the signal. |
required |
SyncError ¶
SyncResult
dataclass
¶
Outcome of a tempestweb sync run.
Attributes:
| Name | Type | Description |
|---|---|---|
config_path |
Path
|
The |
modules |
list[str]
|
The full |
added |
list[str]
|
The module names newly discovered and added this run. |
changed |
bool
|
Whether the config would change ( |
written |
bool
|
Whether the config file was actually written ( |
Source code in tempestweb/cli/commands/sync.py
ConfigError ¶
ProjectConfig
dataclass
¶
Resolved configuration for a tempestweb project.
Attributes:
| Name | Type | Description |
|---|---|---|
root |
Path
|
The project directory the config was read from. |
name |
str
|
The project name. |
entrypoint |
str
|
The project-relative path to the app module. |
mode |
str
|
The default execution mode ( |
host |
str
|
The default dev/run bind address. |
port |
int
|
The default dev/run port. |
wasm |
WasmConfig
|
Mode A build extras (extra packages, bundled modules, static assets, injected scripts). Empty by default. |
pwa |
PwaConfig
|
Web-App-Manifest overrides. Installable-shaped defaults otherwise. |
typing_strictness |
Strictness
|
How strictly the quality commands ( |
Source code in tempestweb/cli/config.py
entrypoint_path
property
¶
Return the absolute path to the entrypoint module.
Returns:
| Type | Description |
|---|---|
Path
|
|
LoadedApp
dataclass
¶
A successfully loaded project module and its contract callables.
Attributes:
| Name | Type | Description |
|---|---|---|
path |
Path
|
The resolved path of the loaded entrypoint module. |
module |
Any
|
The imported module object. |
make_state |
Callable[[], Any]
|
The project's |
view |
Callable[[App[Any]], Widget]
|
The project's |
Source code in tempestweb/cli/loader.py
ProjectLoadError ¶
Bases: RuntimeError
Raised when a project module cannot be loaded or is missing its contract.
This covers a missing entrypoint file, an import error inside the module, or
the absence of the required make_state / view callables.
Source code in tempestweb/cli/loader.py
ProjectExistsError ¶
ScaffoldResult
dataclass
¶
The outcome of scaffolding a project.
Attributes:
| Name | Type | Description |
|---|---|---|
root |
Path
|
The created project directory. |
files |
tuple[str, ...]
|
Project-relative paths that were written, in write order. |
Source code in tempestweb/cli/scaffold.py
build_artifact ¶
build_artifact(project_root: str | Path, *, mode: str | None = None, out_dir: str | Path | None = None, clean: bool = True, offline: bool = False, dev: bool = False) -> BuildResult
Build a deployable artifact for mode from a project.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_root
|
str | Path
|
The project directory (must contain the entrypoint). |
required |
mode
|
str | None
|
|
None
|
out_dir
|
str | Path | None
|
Where to write the artifact. Defaults to
|
None
|
clean
|
bool
|
When |
True
|
offline
|
bool
|
When |
False
|
dev
|
bool
|
When |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
BuildResult
|
class: |
Raises:
| Type | Description |
|---|---|
BuildError
|
If the mode is invalid or the project's view fails to render. |
Source code in tempestweb/cli/commands/build.py
1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 | |
create_dev_session ¶
create_dev_session(project_root: str | Path, *, mode: str | None = None, verify: bool = True) -> DevSession
Build a wired dev session for a project without starting the watch loop.
The session is fully connected — triggering the signal (or feeding the
watcher a change batch) reaches the transport — but the blocking file-watch
loop is started separately via await session.watcher.run(). Splitting
construction from the loop keeps the session unit-testable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_root
|
str | Path
|
The project directory. |
required |
mode
|
str | None
|
|
None
|
verify
|
bool
|
When |
True
|
Returns:
| Type | Description |
|---|---|
DevSession
|
A wired :class: |
Raises:
| Type | Description |
|---|---|
DevError
|
If the mode is invalid or (when verifying) the project fails to load. |
Source code in tempestweb/cli/commands/dev.py
create_project ¶
create_project(name: str, *, parent: str | Path = '.', force: bool = False, verify: bool = True, template: str = 'default') -> ScaffoldResult
Scaffold a new project and optionally verify it renders.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The project name / directory. |
required |
parent
|
str | Path
|
The directory to create the project inside. Defaults to the cwd. |
'.'
|
force
|
bool
|
Overwrite a non-empty target directory when |
False
|
verify
|
bool
|
When |
True
|
template
|
str
|
The scaffold template — |
'default'
|
Returns:
| Name | Type | Description |
|---|---|---|
The |
ScaffoldResult
|
class: |
Raises:
| Type | Description |
|---|---|
NewError
|
If the name is empty or the scaffold fails verification. |
Source code in tempestweb/cli/commands/new.py
prepare_run ¶
prepare_run(project_root: str | Path, *, mode: str | None = None, host: str | None = None, port: int | None = None, offline: bool = False) -> RunPlan
Build the artifact and compute the bind plan for serving it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_root
|
str | Path
|
The project directory. |
required |
mode
|
str | None
|
|
None
|
host
|
str | None
|
Override the bind address. Defaults to the project config's host. |
None
|
port
|
int | None
|
Override the bind port. Defaults to the project config's port. |
None
|
offline
|
bool
|
When |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
RunPlan
|
class: |
Raises:
| Type | Description |
|---|---|
RunError
|
If the build fails. |
Source code in tempestweb/cli/commands/run.py
render_deploy_files ¶
render_deploy_files(root: str | Path, *, server_name: str = '_', tls: bool = False, replicas: int = 1, sticky: bool = True, port: int | None = None) -> dict[str, str]
Render every deploy file's contents without touching disk.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
str | Path
|
The project directory (read for the |
required |
server_name
|
str
|
The nginx |
'_'
|
tls
|
bool
|
When |
False
|
replicas
|
int
|
Number of |
1
|
sticky
|
bool
|
Emit |
True
|
port
|
int | None
|
Override the app port (defaults to the config's port). |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
A mapping of file name to contents covering :data: |
Raises:
| Type | Description |
|---|---|
DeployError
|
If |
Source code in tempestweb/cli/commands/deploy.py
scaffold_deploy ¶
scaffold_deploy(root: str | Path, *, out: str | Path | None = None, server_name: str = '_', tls: bool = False, replicas: int = 1, sticky: bool = True, force: bool = False) -> DeployResult
Write the deploy files into out (default <root>/deploy).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
str | Path
|
The project directory. |
required |
out
|
str | Path | None
|
The output directory (default |
None
|
server_name
|
str
|
The nginx |
'_'
|
tls
|
bool
|
Emit a TLS (443) server block. |
False
|
replicas
|
int
|
Upstream |
1
|
sticky
|
bool
|
Emit |
True
|
force
|
bool
|
Overwrite existing files instead of refusing. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
DeployResult
|
class: |
Raises:
| Type | Description |
|---|---|
DeployError
|
If a target file exists and |
Source code in tempestweb/cli/commands/deploy.py
serve_run ¶
Serve a built artifact according to its bind plan (blocking).
For server mode this imports the artifact's server.py — the real
FastAPI WS/SSE host — and runs it under uvicorn. For wasm mode it serves
the static bundle over the dev HTTP app. Either way the call binds
plan.host:plan.port and blocks until stopped (Ctrl-C).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plan
|
RunPlan
|
The run plan produced by :func: |
required |
Raises:
| Type | Description |
|---|---|
RunError
|
If the built server (server mode) cannot be imported. |
Source code in tempestweb/cli/commands/run.py
sync_modules ¶
Fill [wasm].modules from the project's installed pure-Python deps.
Reads [project.dependencies] from the project's pyproject.toml, keeps
the dependencies that are installed and pure-Python (excluding the framework
and anything already under [wasm].packages), and adds their import names
to [wasm].modules — preserving any existing entries. Idempotent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
The project directory (the one holding |
required |
dry_run
|
bool
|
When |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
SyncResult
|
class: |
Raises:
| Type | Description |
|---|---|
SyncError
|
If there is no |
Source code in tempestweb/cli/commands/sync.py
load_config ¶
Load tempestweb.toml from a project root, falling back to defaults.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
str | Path
|
The project directory. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ProjectConfig
|
class: |
ProjectConfig
|
takes its default and |
Raises:
| Type | Description |
|---|---|
ConfigError
|
If a |
Source code in tempestweb/cli/config.py
load_app ¶
Import a project entrypoint and validate its public contract.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entrypoint
|
str | Path
|
Path to the project's |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
LoadedApp
|
class: |
Raises:
| Type | Description |
|---|---|
ProjectLoadError
|
If the file does not exist, fails to import, or does
not expose callable |
Source code in tempestweb/cli/loader.py
render_initial_tree ¶
Build the project's initial widget tree into a core IR node.
This is the cheapest possible proof that a project is runnable: it builds the
initial state, calls view with a minimal :class:~tempest_core.App
handle, and reconciles the result into a :class:~tempest_core.Node. No
transport, browser or server is involved.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loaded
|
LoadedApp
|
A project loaded via :func: |
required |
Returns:
| Type | Description |
|---|---|
Node
|
The reconciled root :class: |
Raises:
| Type | Description |
|---|---|
ProjectLoadError
|
If |
Source code in tempestweb/cli/loader.py
build_parser ¶
Build the top-level argument parser.
Returns:
| Type | Description |
|---|---|
ArgumentParser
|
The configured parser with the |
Source code in tempestweb/cli/main.py
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | |
render_files ¶
Render every scaffolded file's contents without touching disk.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The project name (used in config and README). |
required |
template
|
str
|
The scaffold template — |
'default'
|
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
A mapping of project-relative path to file contents, covering exactly |
dict[str, str]
|
data: |
Raises:
| Type | Description |
|---|---|
UnknownTemplateError
|
If |
Source code in tempestweb/cli/scaffold.py
scaffold_project ¶
scaffold_project(name: str, *, parent: str | Path = '.', force: bool = False, template: str = 'default') -> ScaffoldResult
Create a new runnable project tree under parent/name.
Passing name="." scaffolds in place into parent (the current
directory) instead of creating a subdirectory, and derives the project name
from that directory's basename. In-place scaffolding refuses to clobber an
existing scaffold file (app.py / tempestweb.toml / …) unless force
is set, but tolerates other pre-existing files in the directory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The project name / directory. |
required |
parent
|
str | Path
|
The directory to create the project inside. Defaults to the cwd. |
'.'
|
force
|
bool
|
When |
False
|
template
|
str
|
The scaffold template ( |
'default'
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
ScaffoldResult
|
class: |
Raises:
| Type | Description |
|---|---|
ProjectExistsError
|
If the target directory exists and is non-empty and
|
UnknownTemplateError
|
If |