diff --git a/docs/Flash_Apps_and_Environments.md b/docs/Flash_Apps_and_Environments.md index 69fb06f..1035936 100644 --- a/docs/Flash_Apps_and_Environments.md +++ b/docs/Flash_Apps_and_Environments.md @@ -13,15 +13,14 @@ Flash apps are the top-level packaging unit for Flash projects. Each app tracks - `FlashApp` instances call `_hydrate()` to fetch or create the remote app ID before doing any work. - CLI helpers (`flash app ...`, `flash deploy ...`) call `discover_flash_project()` when `--app-name` is omitted, then hydrate via `FlashApp.from_name` or eager constructors. 2. **Environment Creation** - - `flash deploy new ` calls `FlashApp.create_environment_and_app` to ensure the parent app exists and to create the environment in a single async transaction. + - `flash env create ` calls `FlashApp.create_environment_and_app` to ensure the parent app exists and to create the environment in a single async transaction. - Once created, the CLI prints both a confirmation panel and a table summarizing the environment metadata so operators can confirm IDs/states. 3. **Build Upload & Resource Provisioning** - `flash build` generates `.flash/artifact.tar.gz` artifacts containing source code and flash_manifest.json. `flash deploy send ` uploads the archive and provisions all resources upfront before environment activation, extracting the manifest on each resource during boot. 4. **Inspection & Operations** - `flash app list/get` surface app-level metadata: environment counts, build history, IDs. - - `flash deploy list/info` zoom into environment state, showing associated endpoints and volumes, while `flash deploy delete` undeploys associated resources before deleting the environment (aborting on failures) with confirmation prompts. + - `flash env list/get` zoom into environment state, showing associated endpoints and volumes, while `flash env delete` undeploys associated resources before deleting the environment (aborting on failures) with confirmation prompts. ## Operational Notes - Flash app CLI entrypoint wraps async helpers with `asyncio.run`, so tests patch that boundary and the shared Rich `console` to keep assertions deterministic. - Environment deletion requires confirmation because the API call is irreversible. The CLI renders a warning `Panel` with the app/env IDs before prompting. - diff --git a/docs/Flash_Deploy_Guide.md b/docs/Flash_Deploy_Guide.md index 6a98656..eb7e62a 100644 --- a/docs/Flash_Deploy_Guide.md +++ b/docs/Flash_Deploy_Guide.md @@ -55,7 +55,7 @@ graph TB ### Key Concepts -**Mothership**: The orchestration endpoint responsible for deployment, resource provisioning, and manifest distribution. Created via `flash deploy new `. +**Mothership**: The orchestration endpoint responsible for deployment, resource provisioning, and manifest distribution. Created via `flash env create `. **Child Endpoints**: Worker endpoints that execute `@remote` functions. One per resource config (e.g., `gpu_config`, `cpu_config`). @@ -69,19 +69,19 @@ graph TB ## CLI Commands Reference -### flash deploy new +### flash env create Create a new deployment environment (mothership). ```bash -flash deploy new [--app-name ] +flash env create [--app ] ``` **Arguments:** - `env_name`: Name for the deployment environment **Options:** -- `--app-name `: Flash app name (auto-detected if not provided) +- `--app `: Flash app name (auto-detected if not provided) **What it does:** 1. Creates a FlashApp in RunPod (if first environment for the app) @@ -90,7 +90,7 @@ flash deploy new [--app-name ] **Example:** ```bash -flash deploy new production +flash env create production # Output: Environment 'production' created successfully # Environment ID: flash-prod-abc123 # Next: flash deploy send production @@ -133,16 +133,16 @@ flash deploy send production --- -### flash deploy list +### flash env list List all deployment environments for an app. ```bash -flash deploy list [--app-name ] +flash env list [--app ] ``` **Options:** -- `--app-name `: Flash app name (auto-detected if not provided) +- `--app `: Flash app name (auto-detected if not provided) **Output:** Table showing: - Environment name @@ -154,19 +154,19 @@ flash deploy list [--app-name ] --- -### flash deploy info +### flash env get Show detailed information about a deployment environment. ```bash -flash deploy info [--app-name ] +flash env get [--app ] ``` **Arguments:** - `env_name`: Name of the deployment environment **Options:** -- `--app-name `: Flash app name (auto-detected if not provided) +- `--app `: Flash app name (auto-detected if not provided) **Output:** Displays: - Environment status and ID @@ -178,19 +178,19 @@ flash deploy info [--app-name ] --- -### flash deploy delete +### flash env delete Delete a deployment environment. ```bash -flash deploy delete [--app-name ] +flash env delete [--app ] ``` **Arguments:** - `env_name`: Name of the deployment environment **Options:** -- `--app-name `: Flash app name (auto-detected if not provided) +- `--app `: Flash app name (auto-detected if not provided) **Safety:** - Requires confirmation (twice for safety) diff --git a/src/runpod_flash/cli/commands/env.py b/src/runpod_flash/cli/commands/env.py index d7677e3..5e115c6 100644 --- a/src/runpod_flash/cli/commands/env.py +++ b/src/runpod_flash/cli/commands/env.py @@ -157,17 +157,17 @@ async def _create_environment(app_name: str, env_name: str): console.print(table) -def info_command( +def get_command( env_name: str = typer.Argument(..., help="Name of the deployment environment"), app_name: str = typer.Option(None, "--app", "-a", help="Flash app name"), ): """Show detailed information about a deployment environment.""" if not app_name: _, app_name = discover_flash_project() - asyncio.run(_info_environment(app_name, env_name)) + asyncio.run(_get_environment(app_name, env_name)) -async def _info_environment(app_name: str, env_name: str): +async def _get_environment(app_name: str, env_name: str): app = await FlashApp.from_name(app_name) env = await app.get_environment_by_name(env_name) diff --git a/src/runpod_flash/cli/main.py b/src/runpod_flash/cli/main.py index 39337ce..405a8f6 100644 --- a/src/runpod_flash/cli/main.py +++ b/src/runpod_flash/cli/main.py @@ -51,7 +51,7 @@ def get_version() -> str: env_app.command("list")(env.list_command) env_app.command("create")(env.create_command) -env_app.command("info")(env.info_command) +env_app.command("get")(env.get_command) env_app.command("delete")(env.delete_command) app.add_typer(env_app, name="env") diff --git a/tests/unit/cli/test_env.py b/tests/unit/cli/test_env.py index 9d07ede..a5d1639 100644 --- a/tests/unit/cli/test_env.py +++ b/tests/unit/cli/test_env.py @@ -132,9 +132,9 @@ def test_create_environment_success( assert isinstance(table, Table) -class TestEnvInfo: +class TestEnvGet: @patch("runpod_flash.cli.commands.env.FlashApp.from_name", new_callable=AsyncMock) - def test_info_includes_children( + def test_get_includes_children( self, mock_from_name, runner, mock_asyncio_run_coro, patched_console ): flash_app = MagicMock() @@ -155,7 +155,7 @@ def test_info_includes_children( "runpod_flash.cli.commands.env.asyncio.run", side_effect=mock_asyncio_run_coro, ): - result = runner.invoke(app, ["env", "info", "dev", "--app", "demo"]) + result = runner.invoke(app, ["env", "get", "dev", "--app", "demo"]) assert result.exit_code == 0 panel = patched_console.print.call_args_list[0].args[0] @@ -166,7 +166,7 @@ def test_info_includes_children( assert isinstance(network_table, Table) @patch("runpod_flash.cli.commands.env.FlashApp.from_name", new_callable=AsyncMock) - def test_info_without_children( + def test_get_without_children( self, mock_from_name, runner, mock_asyncio_run_coro, patched_console ): flash_app = MagicMock() @@ -187,7 +187,7 @@ def test_info_without_children( "runpod_flash.cli.commands.env.asyncio.run", side_effect=mock_asyncio_run_coro, ): - result = runner.invoke(app, ["env", "info", "dev", "--app", "demo"]) + result = runner.invoke(app, ["env", "get", "dev", "--app", "demo"]) assert result.exit_code == 0 # Only the panel should be printed when there are no child resources