Turn an OpenAPI / Swagger spec into ready-to-run HTTPie commands — or a Postman collection you can import into HTTPie Desktop.
Point it at a spec, get back a runnable .sh file where every endpoint is a clean, copy-pasteable http command with real example data, correct auth, and environment-variable placeholders for your secrets.
$ openapi2httpie petstore.yaml#!/usr/bin/env bash
# Swagger Petstore 1.2.0
# Generated by openapi2httpie
#
# Edit the variables below (or export them beforehand), then run this file.
: "${BASE_URL:=https://api.example.com/v1}" # API base URL
: "${TOKEN:=REPLACE_ME}" # bearer token
: "${X_API_KEY:=REPLACE_ME}" # API key (X-API-Key in header)
# GET /users/{id}
# Fetch a user
http --ignore-stdin -A bearer -a "$TOKEN" GET "$BASE_URL/users/0" verbose==true
# POST /users
# Create a user
http --ignore-stdin POST "$BASE_URL/users" "X-API-Key:$X_API_KEY" 'name=Ada Lovelace' age:=0HTTPie is a joy to use by hand, but nobody wants to hand-write a request for every endpoint of a 200-operation API. Existing generators target the .http file format used by IDE REST clients — not HTTPie, and not the terminal. openapi2httpie fills that gap, and does the parts those tools skip:
- Real authentication. It reads your spec's
securitySchemes/securityDefinitionsand per-operationsecurity, and emits the correct HTTPie form —-A bearer -a "$TOKEN",-a "$USER:$PASS",X-API-Key:$KEY, query keys, or cookies. - Useful example bodies. It uses the spec's own
example/examples/default/enumvalues, falling back to type- and format-aware placeholders (user@example.com,2024-01-01T00:00:00Z, a real-looking UUID) — not hollow zeros. - Both spec dialects. Swagger 2.0 and OpenAPI 3.0 / 3.1, normalised into one model.
- Safe by construction. Every value from the spec is shell-quoted, so example data can never break out of its argument. Generated scripts pass
bash -n, even with multi-line bodies.
pip install openapi2httpie # or: pipx install openapi2httpieRequires Python 3.9+. The only runtime dependency is PyYAML. (HTTPie itself is only needed to run the generated commands.)
$ openapi2httpie SPEC [options]SPEC can be a file path, an http(s):// URL, or - for stdin. JSON or YAML.
| Option | Description |
|---|---|
-f, --format {httpie,postman} |
Output format (default httpie). |
-o, --output PATH |
Write to a file (default: stdout). With --split, a directory. |
--split |
HTTPie only: one script per operation, into the output directory. |
--base-url URL |
Override the base URL from the spec. |
--offline |
Emit http --offline commands (build & print the request, don't send). |
--command {http,https} |
HTTPie executable to emit (default http). |
--all-optional |
Include optional parameters and body properties in the examples. |
--no-auth |
Don't emit authentication. |
--no-multiline |
Keep each command on one line. |
--tag TAG |
Only include operations with this tag (repeatable). |
--operation ID |
Only include this operationId (repeatable). |
# Whole API to a runnable script
openapi2httpie api.yaml -o api.sh && bash api.sh
# Just the "Pets" tag, previewing requests without sending them
openapi2httpie api.yaml --tag Pets --offline
# One script per endpoint
openapi2httpie api.yaml --split -o ./requests/
# From a live URL, straight into HTTPie
openapi2httpie https://api.example.com/openapi.json | bashThe generated script declares its variables with shell defaults, so you can either edit the file or export them first:
export BASE_URL=https://api.example.com TOKEN=eyJhbGc...
bash api.sh--format postman emits a Postman Collection v2.1 with native auth objects, structured URLs (query params + path variables), tag folders, and JSON bodies:
openapi2httpie api.yaml -f postman -o api.postman.jsonHTTPie Desktop can import Postman collections (File → Import), so this is the path to get an OpenAPI spec into the Desktop app today. The collection is also a valid Postman/Insomnia import.
Note: HTTPie Desktop's importer is closed-source; this output is built to its published import-compatibility contract. It drops file-upload bodies, folder nesting (flattened to
Folder / Requestnames), scripts, and cookies on import — by design. Round-trip a sample through your Desktop version to confirm before relying on it.
from openapi2httpie import to_httpie, to_postman, build_model
script = to_httpie("api.yaml")
collection = to_postman("api.yaml", base_url="https://api.example.com")
model = build_model("api.yaml") # the normalised IR
for req in model.requests:
print(req.method, req.path, req.label)spec ──▶ loader ──▶ resolver ──▶ extractor ──▶ ApiModel (IR) ──┬──▶ HTTPie emitter
(json/yaml, ($ref, (normalises 2.0 & 3.x: │
dialect cycle-safe) params, bodies, auth, └──▶ Postman emitter
detect) servers, examples)
One intermediate model, two emitters. Swagger 2.0 and OpenAPI 3.x differences are absorbed in the extractor, so the emitters never branch on dialect.
- Array/scalar query params are emitted as a single example value; HTTPie has no native repeated-key syntax, so multi-value arrays are approximate.
- Remote
$refs ($refto another URL/file) are not resolved — only local#/...references. Bundle your spec first if it uses remote refs. - File uploads in
multipart/form-databecomefield@./path/to/fieldplaceholders — point them at a real file before running. - Example bodies are plausible, not validated — they satisfy shape and format, not business rules.
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
pytest # 83 tests incl. a real-HTTPie end-to-end suiteThe test suite includes an end-to-end test that generates a script and runs it with the real http binary against an in-process mock server, asserting the requests land with the right method, path, query, auth header, and JSON body.
MIT