Skip to content
Guide

CLI and Migrations

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

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.

Terminal window
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:

Terminal window
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.

Terminal window
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.

Print a specification:

Terminal window
uv run flasgo openapi app.py

Write it atomically for CI or deployment:

Terminal window
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.

Terminal window
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. The check catches configuration errors without serving traffic; it does not replace application tests.

Terminal window
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 for snapshot contents, public=True, and the limits of metadata inspection.

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:

Terminal window
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:

Terminal window
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.

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

Terminal window
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.