A Pacto plugin that auto-detects web frameworks and extracts OpenAPI 3.1 specs from source code.
make installOr download a pre-built binary from the latest release.
pacto generate openapi-infer <bundle-dir> [--option key=value ...]| Argument | Description |
|---|---|
<bundle-dir> |
Path to the Pacto bundle directory containing the service's source code and pacto.yaml. Use . for the current directory. |
# Auto-detect framework and extract (default output: interfaces/openapi.yaml)
pacto generate openapi-infer .
# Or specify an explicit path
pacto generate openapi-infer /path/to/my-service
# Custom output path (format inferred from extension)
pacto generate openapi-infer . --option output=interfaces/openapi.json
# Override framework detection
pacto generate openapi-infer . --option framework=fastapiThis generates an OpenAPI spec file. Reference it in your Pacto contract:
interfaces:
- name: rest-api
type: http
port: 8080
visibility: public
contract: interfaces/openapi.yamlpacto-plugin-openapi-infer --versionOptions are passed via --option key=value flags when invoking with Pacto.
Output file path for the generated OpenAPI spec.
- Default:
interfaces/openapi.yaml - Format detection: the file extension determines the output format:
.json-- outputs indented JSON.yamlor.yml-- outputs YAML (default)
# YAML output (default)
pacto generate openapi-infer .
# JSON output
pacto generate openapi-infer . --option output=interfaces/openapi.json
# Custom path with YAML
pacto generate openapi-infer . --option output=api/spec.yamlPath to the directory containing the source code to scan. This is useful when
the source code lives outside the bundle directory (e.g., the Go source is at
the repository root while the bundle is in pactos/my-service/).
- Default: the bundle directory itself
- Relative paths are resolved relative to the bundle directory
- Absolute paths are used as-is
# Source code is two levels up from the bundle directory
pacto generate openapi-infer pactos/my-service --option source=../..
# Absolute path
pacto generate openapi-infer pactos/my-service --option source=/path/to/repoOverride automatic framework detection. Useful when the project has dependencies for multiple frameworks, or when the detection heuristic doesn't match your setup.
- Default: auto-detected from dependency files
- Possible values:
fastapi-- force FastAPI runtime extraction. Requires the project's Python environment to be set up with FastAPI and all dependencies installed. Detects by checkingrequirements.txt,pyproject.toml,Pipfile,setup.py, orsetup.cfgfor the stringfastapi.huma-- force Huma static extraction via Go AST analysis. No runtime or build required. Detects by checkinggo.modfordanielgtaylor/huma.
# Skip detection, force FastAPI extraction
pacto generate openapi-infer . --option framework=fastapi
# Skip detection, force Huma extraction
pacto generate openapi-infer . --option framework=humaIf framework is not specified and no supported framework is detected, the plugin exits with an error listing the supported frameworks.
| Framework | Language | Detection | Extraction |
|---|---|---|---|
| FastAPI | Python | fastapi in dependency files |
Runtime -- runs app.openapi() |
| Huma | Go | danielgtaylor/huma in go.mod |
Static -- Go AST analysis |
Extracts the exact OpenAPI spec by running the FastAPI app using the project's Python environment. The plugin auto-discovers:
- Python interpreter: walks up from the project directory looking for
.venv/bin/python,venv/bin/python, or usesuv runif apyproject.tomlis present, falling back to systempython3/python - FastAPI app: scans
*.pyfiles forFastAPI()instances and imports the app object to callapp.openapi()
Requirements: the project's Python environment must be set up with all dependencies installed.
The /health endpoint is automatically excluded from the generated spec.
Extracts routes and schemas using Go's built-in go/ast parser. Supports:
huma.Get,huma.Post,huma.Put,huma.Delete,huma.Patchshorthand callshuma.Registerwithhuma.Operationstruct (extracts method, path, summary)huma.DefaultConfigfor API title and version- Exported Go structs with JSON tags as schema definitions
- Path parameters extracted from route patterns (e.g.,
/pets/{id})
No build, runtime, or external dependencies required.
- The plugin receives the project's
bundleDirpath - It detects the web framework by checking dependency files
- It extracts the OpenAPI spec using the framework-specific strategy
- The spec is formatted as YAML or JSON based on the output file extension
- The result is returned as a Pacto
GenerateResponse
Given a Huma project with:
func main() {
cfg := huma.DefaultConfig("Pet Store", "1.0.0")
// ...
huma.Get(api, "/pets", listPets)
huma.Get(api, "/pets/{petId}", getPet)
huma.Post(api, "/pets", createPet)
}Running:
pacto generate openapi-infer .Generates interfaces/openapi.yaml:
openapi: 3.1.0
info:
title: Pet Store
version: 1.0.0
paths:
/pets:
get:
responses:
"200":
description: Successful response
post:
responses:
"200":
description: Successful response
/pets/{petId}:
get:
parameters:
- in: path
name: petId
required: true
schema:
type: string
responses:
"200":
description: Successful responsemake build # Build the binary to dist/
make test # Run unit tests
make e2e # Run e2e tests
make coverage # Run tests with coverage report
make lint # Check formatting and run go vet
make ci # Run full CI pipeline
make install # Install to $GOPATH/bin