# `orchestrator.launch`
<!-- generated by `orchestrator understand`; the PKG is source of truth, edits here are advisory -->

[← Episteme](../README.md) · [Architecture](../architecture.md)

**Source:** [`src/orchestrator/launch.py`](../../src/orchestrator/launch.py)

2 types · 17 functions · python

## Changing this safely

**Tested by** (1): `tests.test_launch`

**Most depended-upon here** — a change to these reaches the most code (call graph, ≤4 hops):

- [`find_project_file`](../../src/orchestrator/launch.py#L119) — reaches **5** symbols
- [`LaunchError`](../../src/orchestrator/launch.py#L303) — reaches **4** symbols · **no test path visible**
- [`_run`](../../src/orchestrator/launch.py#L235) — reaches **4** symbols · **no test path visible**
- [`_resolve_compose_file`](../../src/orchestrator/launch.py#L246) — reaches **3** symbols
- [`alembic_command`](../../src/orchestrator/launch.py#L196) — reaches **3** symbols
- [`build_child_env`](../../src/orchestrator/launch.py#L150) — reaches **3** symbols
- [`resolve_compose_base`](../../src/orchestrator/launch.py#L129) — reaches **3** symbols
- [`_block_until_interrupted`](../../src/orchestrator/launch.py#L369) — reaches **2** symbols · **no test path visible**

_10 of the symbols other code depends on here have no test path the graph can see — worth a second look before changing them. Absence of a path is not proof of absence of a test: calls through an attribute chain (`obj.method()`) are skipped rather than guessed at, so indirect coverage is invisible._

## Types

### `LaunchConfig`

[`src/orchestrator/launch.py:86`](../../src/orchestrator/launch.py#L86)

- **Called by** (1 production · 8 test): [`up`](../../src/orchestrator/cli.py#L1969), [`test_api_command`](../../tests/test_launch.py#L78), [`test_app_url_keeps_real_host`](../../tests/test_launch.py#L26), [`test_app_url_shows_localhost_for_loopback`](../../tests/test_launch.py#L23), [`test_existing_values_win`](../../tests/test_launch.py#L64), [`test_explicit_file_wins`](../../tests/test_launch.py#L152), [`test_fills_defaults_when_unset`](../../tests/test_launch.py#L55), [`test_health_urls_bind_to_host`](../../tests/test_launch.py#L29), [`test_writes_embedded_when_none_found`](../../tests/test_launch.py#L158)
- **Fields**: `api_key`, `compose_file`, `env`, `host`, `port`, `postgres_port`, `session_secret`, `start_worker`, `temporal_port`, `use_docker`

### `LaunchError`

[`src/orchestrator/launch.py:303`](../../src/orchestrator/launch.py#L303)

- **Extends** (1): `RuntimeError`
- **Called by** (3): [`_bring_up_docker`](../../src/orchestrator/launch.py#L260), [`_run_migrations`](../../src/orchestrator/launch.py#L277), [`run_up`](../../src/orchestrator/launch.py#L307)

## Functions

### `_block_until_interrupted`

[`src/orchestrator/launch.py:369`](../../src/orchestrator/launch.py#L369)

- **Called by** (1): [`run_up`](../../src/orchestrator/launch.py#L307)
- **Calls** (1): `sleep`

### `_bring_up_docker`

[`src/orchestrator/launch.py:260`](../../src/orchestrator/launch.py#L260)

- **Called by** (1): [`run_up`](../../src/orchestrator/launch.py#L307)
- **Calls** (4): [`LaunchError`](../../src/orchestrator/launch.py#L303), [`_resolve_compose_file`](../../src/orchestrator/launch.py#L246), [`_run`](../../src/orchestrator/launch.py#L235), [`resolve_compose_base`](../../src/orchestrator/launch.py#L129)

### `_has_llm_key`

[`src/orchestrator/launch.py:299`](../../src/orchestrator/launch.py#L299)

- **Called by** (1): [`run_up`](../../src/orchestrator/launch.py#L307)

### `_print_ready_banner`

[`src/orchestrator/launch.py:358`](../../src/orchestrator/launch.py#L358)

- **Called by** (1): [`run_up`](../../src/orchestrator/launch.py#L307)

### `_resolve_compose_file`

[`src/orchestrator/launch.py:246`](../../src/orchestrator/launch.py#L246)

- **Called by** (1 production · 2 test): [`_bring_up_docker`](../../src/orchestrator/launch.py#L260), [`test_explicit_file_wins`](../../tests/test_launch.py#L152), [`test_writes_embedded_when_none_found`](../../tests/test_launch.py#L158)
- **Calls** (2): `cwd`, [`find_project_file`](../../src/orchestrator/launch.py#L119)

### `_run`

[`src/orchestrator/launch.py:235`](../../src/orchestrator/launch.py#L235)

- **Called by** (2): [`_bring_up_docker`](../../src/orchestrator/launch.py#L260), [`_run_migrations`](../../src/orchestrator/launch.py#L277)
- **Calls** (1): `run`

### `_run_migrations`

[`src/orchestrator/launch.py:277`](../../src/orchestrator/launch.py#L277)

- **Called by** (1): [`run_up`](../../src/orchestrator/launch.py#L307)
- **Calls** (6): [`LaunchError`](../../src/orchestrator/launch.py#L303), [`_run`](../../src/orchestrator/launch.py#L235), [`alembic_command`](../../src/orchestrator/launch.py#L196), [`build_child_env`](../../src/orchestrator/launch.py#L150), [`find_project_file`](../../src/orchestrator/launch.py#L119), `sleep`

### `_teardown`

[`src/orchestrator/launch.py:383`](../../src/orchestrator/launch.py#L383)

- **Called by** (1): [`run_up`](../../src/orchestrator/launch.py#L307)

### `alembic_command`

[`src/orchestrator/launch.py:196`](../../src/orchestrator/launch.py#L196)

- **Called by** (1 production · 1 test): [`_run_migrations`](../../src/orchestrator/launch.py#L277), [`test_alembic_command`](../../tests/test_launch.py#L91)
- **Calls** (1): `which`

### `api_command`

[`src/orchestrator/launch.py:170`](../../src/orchestrator/launch.py#L170)

- **Called by** (1 production · 1 test): [`run_up`](../../src/orchestrator/launch.py#L307), [`test_api_command`](../../tests/test_launch.py#L78)
- **Documented in**: `docs/specs/build-documents/SSPN-49-plan.md#3-pkg-understanding-and-where-it-misleads`

### `build_child_env`

[`src/orchestrator/launch.py:150`](../../src/orchestrator/launch.py#L150)

- **Called by** (2 production · 2 test): [`_run_migrations`](../../src/orchestrator/launch.py#L277), [`run_up`](../../src/orchestrator/launch.py#L307), [`test_existing_values_win`](../../tests/test_launch.py#L64), [`test_fills_defaults_when_unset`](../../tests/test_launch.py#L55)

### `find_project_file`

[`src/orchestrator/launch.py:119`](../../src/orchestrator/launch.py#L119)

- **Called by** (2 production · 2 test): [`_resolve_compose_file`](../../src/orchestrator/launch.py#L246), [`_run_migrations`](../../src/orchestrator/launch.py#L277), [`test_finds_marker_in_parent`](../../tests/test_launch.py#L39), [`test_returns_none_when_absent`](../../tests/test_launch.py#L47)
- **Calls** (1): `cwd`

### `resolve_compose_base`

[`src/orchestrator/launch.py:129`](../../src/orchestrator/launch.py#L129)

- **Called by** (1 production · 3 test): [`_bring_up_docker`](../../src/orchestrator/launch.py#L260), [`test_falls_back_to_legacy_binary`](../../tests/test_launch.py#L110), [`test_none_when_docker_absent`](../../tests/test_launch.py#L117), [`test_prefers_compose_v2`](../../tests/test_launch.py#L103)
- **Calls** (2): `run`, `which`

### `run_up`

[`src/orchestrator/launch.py:307`](../../src/orchestrator/launch.py#L307)

- **Called by** (1): [`up`](../../src/orchestrator/cli.py#L1969)
- **Calls** (13): [`LaunchError`](../../src/orchestrator/launch.py#L303), `Popen`, [`_block_until_interrupted`](../../src/orchestrator/launch.py#L369), [`_bring_up_docker`](../../src/orchestrator/launch.py#L260), [`_has_llm_key`](../../src/orchestrator/launch.py#L299), [`_print_ready_banner`](../../src/orchestrator/launch.py#L358), [`_run_migrations`](../../src/orchestrator/launch.py#L277), [`_teardown`](../../src/orchestrator/launch.py#L383), [`api_command`](../../src/orchestrator/launch.py#L170), [`build_child_env`](../../src/orchestrator/launch.py#L150), [`wait_for_http`](../../src/orchestrator/launch.py#L218), [`wait_for_tcp`](../../src/orchestrator/launch.py#L206), [`worker_command`](../../src/orchestrator/launch.py#L185)

### `wait_for_http`

[`src/orchestrator/launch.py:218`](../../src/orchestrator/launch.py#L218)

- **Called by** (1 production · 2 test): [`run_up`](../../src/orchestrator/launch.py#L307), [`test_returns_false_on_timeout`](../../tests/test_launch.py#L140), [`test_returns_true_on_2xx`](../../tests/test_launch.py#L136)
- **Calls** (2): `monotonic`, `sleep`

### `wait_for_tcp`

[`src/orchestrator/launch.py:206`](../../src/orchestrator/launch.py#L206)

- **Called by** (1): [`run_up`](../../src/orchestrator/launch.py#L307)
- **Calls** (3): `create_connection`, `monotonic`, `sleep`

### `worker_command`

[`src/orchestrator/launch.py:185`](../../src/orchestrator/launch.py#L185)

- **Called by** (1 production · 1 test): [`run_up`](../../src/orchestrator/launch.py#L307), [`test_worker_command_targets_sdlc_worker`](../../tests/test_launch.py#L86)

## Imports

`__future__.annotations`, `collections.abc.Callable`, `dataclasses.dataclass`, `dataclasses.field`, `os`, `pathlib.Path`, `shutil`, `socket`, `subprocess`, `sys`, `time`, `urllib.error`, `urllib.request`

## Imported by

[`orchestrator.cli`](orchestrator.cli.md), [`tests.test_launch`](../../tests/test_launch.py#L1)
