# CLI and Migrations

Run, inspect, validate, document, and migrate a Flasgo application.

Source: https://flasgo.dev/guides/cli-and-migrations/

CLI commands accept Python files, extensionless local file names, package directories, and import strings. A target can include a `:attribute`, including a nested attribute such as `package.module:namespace.app`; that explicit attribute takes precedence over `--app`. With the default name, Flasgo checks `app` and then `application`. A mistyped command name, such as `flasgo rotues`, suggests the closest valid command.

## Run

```bash
uv run flasgo run app.py --reload
uv run flasgo run app
uv run flasgo run src/package/app.py:application
uv run flasgo run src/package
uv run flasgo run package.module:app \
  --host 127.0.0.1 \
  --port 8000 \
  --reload \
  --reload-dir src
```

File and package targets establish their project import root before loading, so sibling, absolute package, and package-relative imports work from the installed console script. Each `--reload-dir` adds a watched directory without replacing the target's default watch directory. Without `--reload` or `--no-reload`, reloading follows the app's `DEBUG` setting.

The reloader runs the server as a child process and restarts it when watched files change. Stopping the reloader with Ctrl+C or `SIGTERM` also stops the child, sending it `SIGINT` and killing it if it has not exited after five seconds, so it does not keep holding the port. In 0.10.0, `flasgo run --reload` and `app.run()` with `DEBUG=True` no longer fail with `signal only works in main thread`.

The built-in command is a development server. It runs Uvicorn with the `h11` HTTP implementation and the `websockets-sansio` WebSocket implementation, and it does not send a `server` header. For production, configure Uvicorn explicitly:

```bash
uv run uvicorn app:app \
  --host 0.0.0.0 \
  --port 8000 \
  --workers 4 \
  --no-proxy-headers
```

Only enable proxy-header trust when a known proxy overwrites the forwarded headers and the server is unreachable directly.

## Inspect routes

```bash
uv run flasgo routes app.py
uv run flasgo routes package.module:application
uv run flasgo routes app.py --app application
```

The output includes HTTP methods and WebSocket routes without starting a server. Import errors raised by application code retain their traceback, while malformed or missing targets receive concise target-resolution guidance.

## Generate OpenAPI

Print a specification:

```bash
uv run flasgo openapi app.py
```

Write it atomically for CI or deployment:

```bash
uv run flasgo openapi app.py --output openapi.json
```

`--output` (or `-o`) writes a temporary sibling file and then replaces the destination, so a failed write leaves neither a partial document nor a hidden temporary file. Replacing an existing file keeps its permissions; a new file, or one replacing a symlink, uses the process umask. `routes --json --output` writes policy snapshots the same way. JSON output rejects NaN and Infinity values instead of emitting invalid JSON.

## Check before deployment

```bash
uv run flasgo check app.py
```

The check detects duplicate route names, missing route or docs auth backends, and conflicts with enabled docs, OpenAPI, or metrics paths. Ambiguous HTTP and WebSocket patterns now fail during registration, so a check can report an application load failure before it inspects the completed app. Registration also rejects invalid method tokens and conflicting request-binding plans. See [Route Precedence and Conflicts](/guides/http-apps/#route-precedence-and-conflicts). The check catches configuration errors without serving traffic; it does not replace application tests.

## Policy checks and baselines

```bash
uv run flasgo routes app.py --policy
uv run flasgo routes app.py --json --output policy.json
uv run flasgo check app.py --deploy --json
uv run flasgo check app.py --against policy.json --json
```

`--deploy` adds security configuration and undeclared-access warnings; any warning returns nonzero. `--against` compares declared application controls, internal endpoints, and routes with a reviewed snapshot, returning nonzero for any change. Review deliberate changes before replacing the baseline. Plain `flasgo check` keeps its registration checks.

In 0.9.1, `flasgo check --json` keeps stdout parseable when application loading fails, including registration errors. It redirects application import output to stderr, exits with status `1`, and emits `passed: false`, a `registration` issue with severity `error`, and an empty `changes` list. Successful loads use the same top-level `passed`, `issues`, and `changes` fields. This stdout guarantee applies to `check --json`; use `routes --json --output` for a policy file separated from import output.

See [Policy and Deployment Checks](/guides/policy-and-deployment-checks/) for snapshot contents, `public=True`, and the limits of metadata inspection.

## Database migrations

Flasgo does not impose an ORM. The optional database extra delegates migrations to Alembic. In 0.11.0 it pins Alembic 1.20, which requires SQLAlchemy 2.0 or newer, so upgrade projects still on SQLAlchemy 1.4 before using `flasgo db`:

```bash
uv add flasgo --extra db
uv run flasgo db init
uv run flasgo db migrate -m "create users"
uv run flasgo db upgrade
uv run flasgo db downgrade
```

Useful variants:

```bash
uv run flasgo db \
  --config config/alembic.ini \
  init --directory migrations

uv run flasgo db upgrade head --sql
uv run flasgo db downgrade -1 --sql
```

Review generated migrations before applying them. Back up production data, use least-privilege database credentials, and coordinate schema changes across running application versions.

## CI baseline

For a Flasgo application, a compact verification job can run:

```bash
uv run ruff check .
uv run ty check
uv run pytest
uv run flasgo check app.py
uv run flasgo openapi app.py --output openapi.json
```

The generated artifact is OpenAPI 3.2 with JSON Schema 2020-12. Validate and diff it in CI when clients depend on the contract.

Pin dependencies with a committed `uv.lock`, audit them in CI, and build deployments from the verified lockfile.
