CLI Guide¶
azure-functions-openapi ships with a CLI entry point for generating OpenAPI output from decorated handlers.
Install¶
Then verify:
Command overview¶
Current command set:
generate: build OpenAPI spec in JSON or YAML
generate command¶
Basic usage¶
By default this prints JSON to stdout using:
- title:
API - version:
1.0.0 - OpenAPI version:
3.1.0
Common examples¶
Generate JSON to stdout:
Generate YAML to stdout:
Write JSON to file:
Write YAML to file:
Generate OpenAPI 3.1 output:
Import your function app so routes are registered:
Pretty-print JSON output:
Endpoint-metadata discovery (module:variable)¶
@openapi-decorated routes register themselves the moment the module is
imported, so --app module is enough to see them. Producers that register
only through the shared endpoint-metadata namespace — @validate_http
(azure-functions-validation), azure-functions-langgraph, and other
third-party producers — are attached to the live FunctionApp object and are
discovered by scanning it.
To include those endpoints, pass an explicit module:variable so the CLI can
resolve the FunctionApp instance and run discovery on it:
# Imports function_app, resolves `app`, then discovers BOTH decorator-
# registered and endpoint-metadata routes into a single spec.
azure-functions-openapi generate --app function_app:app --output openapi.json
Discovery semantics:
--app function_app(module only): the module is imported so@openapidecorators fire, but endpoint-metadata discovery is not run — the CLI never guesses theFunctionAppvariable name. A note is printed reminding you to passmodule:variableto also discover endpoint-metadata routes.--app function_app:app(module + variable): the namedFunctionAppattribute is resolved and scanned, merging endpoint-metadata routes into the same registry as the decorator routes.- Discovery is one-shot per run and uses the idempotent
FunctionBuilder.build()path. The CLI never callsFunctionApp.get_functions(), which is non-idempotent on all supported SDK versions (1.21–1.25): it accumulates intofunctions_bindingsand raises on a second call. - Blueprints (raw or registered via
register_functions/register_blueprint) are enumerated through the same path — no special casing is required. - Re-running discovery on the same app is safe: the registry merges by function id, so no duplicate paths or operations are produced.
Options reference¶
| Option | Alias | Values | Default | Description |
|---|---|---|---|---|
--app |
- | module or module:var |
- | Import module so @openapi decorators register routes; with module:var, also resolve the FunctionApp and discover endpoint-metadata routes (see Endpoint-metadata discovery) |
--title |
- | any string | API |
OpenAPI info.title |
--version |
- | any string | 1.0.0 |
OpenAPI info.version |
--description |
- | any string | library default | OpenAPI info.description (Markdown / CommonMark supported) |
--output |
-o |
file path | stdout | Write generated content to file |
--format |
-f |
json, yaml |
json |
Output serialization format |
--openapi-version |
- | 3.0, 3.1 |
3.1 |
OpenAPI schema version |
--pretty |
-p |
flag | false |
Pretty-print JSON output (adds indentation); no effect on YAML |
--route-prefix |
- | any string (or "") |
/api |
HTTP route prefix from host.json extensions.http.routePrefix. See Route Prefix. |
--fail-on-empty-paths |
- | flag | false |
Exit with code 1 if the generated spec has no paths |
Exit codes¶
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Runtime or generation error |
2 |
Invalid CLI arguments (argparse parse error) |
Validate generated output¶
Use a validator in local checks and CI:
For YAML:
CI example¶
name: OpenAPI Validation
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install tools
run: pip install azure-functions-openapi openapi-spec-validator
- name: Generate spec
run: azure-functions-openapi generate --openapi-version 3.1 --output openapi.json
- name: Validate spec
run: openapi-spec-validator openapi.json
Troubleshooting¶
command not found¶
- Confirm package installed in active environment
- Use
python -m azure_functions_openapi.cli --helpas fallback
Empty paths in output¶
- Ensure app handlers are decorated with
@openapi - Pass
--app <module>so decorated routes are registered before generation:
- Use
module:variablesyntax when theFunctionAppinstance is not namedapp:
Unsupported version error¶
- Use only
--openapi-version 3.0or--openapi-version 3.1