Generate typed Python CLIs from OpenAPI specs with Pydantic model flattening into CLI flags
Project description
openapi-cli-gen
Generate a typed Python CLI from any OpenAPI 3.x spec in seconds. Nested request bodies become flat --flags automatically.
# Instead of this:
curl -X POST /api/users -d '{"name": "John", "address": {"city": "NYC", "state": "NY"}}'
# You get this:
mycli users create --name John --address.city NYC --address.state NY
Install
# Recommended: pipx (installs in isolated environment)
pipx install openapi-cli-gen
# Or with uv
uv tool install openapi-cli-gen
# Or in a virtual environment
pip install openapi-cli-gen
Try It Now
Point at any public API — no setup, no files needed:
# Get a random cat fact
openapi-cli-gen run --spec https://catfact.ninja/docs --base-url https://catfact.ninja \
facts get-random
# Browse cat breeds as a table
openapi-cli-gen run --spec https://catfact.ninja/docs --base-url https://catfact.ninja \
breeds get --limit 5 --output-format table
┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ breed ┃ country ┃ origin ┃ coat ┃ pattern ┃
┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ Abyssinian │ Ethiopia │ Natural/Stand… │ Short │ Ticked │
│ Aegean │ Greece │ Natural/Stand… │ Semi-long │ Bi- or tri-… │
│ American Curl │ United States │ Mutation │ Short/Long │ All │
└────────────────┴───────────────┴────────────────┴────────────┴───────────────┘
# Inspect any spec to see what commands you'd get
openapi-cli-gen inspect --spec https://petstore3.swagger.io/api/v3/openapi.json
Generate Your Own CLI
openapi-cli-gen generate --spec https://api.example.com/openapi.json --name mycli
cd mycli && pip install -e .
mycli users list
mycli users create --name John --email john@example.com --address.city NYC
Ship it to your users: pip install mycli.
Nested Model Flattening
The core feature. Works at any depth:
--address.city NYC # depth 1
--ceo.name Bob --ceo.email bob@acme.com # depth 2
--retry.backoff.strategy exponential # depth 3
--tags admin --tags reviewer # arrays
--environment JAVA_HOME=/usr/lib/jvm # dicts
--role admin # enums (validated)
--address '{"street": "123 Main", "city": "NYC"}' # JSON fallback
As a Library
from openapi_cli_gen import build_cli
app = build_cli(spec="openapi.yaml", name="mycli")
app()
Or plug API commands into your existing CLI:
from openapi_cli_gen import build_command_group
registry = build_command_group(spec="openapi.yaml", name="mycli")
Auth
Auto-configures from your spec's securitySchemes:
export MYCLI_TOKEN=sk-xxx # env var
mycli users list --token sk-xxx # or flag (overrides env)
Pre-Built CLIs
Six ready-to-use CLI wrappers, each generated from its API's official OpenAPI spec. Install one and start using it instantly:
# OpenAI — every endpoint (chat, embeddings, images, audio, files,
# vector stores, batch, fine-tuning, ...) as a typed subcommand
pipx install openai-rest-cli
export OPENAI_REST_CLI_TOKEN=sk-...
openai-rest-cli chat create-completion --model gpt-4o-mini \
--messages '[{"role":"user","content":"Hi"}]'
# Qdrant — collections, points, search, snapshots, distributed
pipx install qdrant-rest-cli
qdrant-rest-cli collections get-collections
qdrant-rest-cli search points --collection-name pets \
--vector '[0.1,0.2,0.3,0.4]' --limit 5 --with-payload true
# Meilisearch — indexes, documents, search, settings, tasks
pipx install meilisearch-rest-cli
meilisearch-rest-cli indexes list
meilisearch-rest-cli documents replace --index-uid movies \
--root '[{"id":1,"title":"The Matrix"}]'
# Typesense — collections, documents, search (72 search flags typed)
pipx install typesense-rest-cli
export TYPESENSE_REST_CLI_API_KEY=xyz
typesense-rest-cli documents search-collection --collection-name books \
-q programmer --query-by title,author
# AdGuard Home — filtering, clients, DHCP, rewrite, TLS, stats
pipx install adguard-home-cli
export ADGUARD_HOME_CLI_USERNAME=admin
export ADGUARD_HOME_CLI_PASSWORD=xxx
adguard-home-cli filtering add-url --name "OISD" --url "https://big.oisd.nl/" --no-whitelist
# Immich — ~250 subcommands across 36 groups including multipart upload
pipx install immich-rest-cli
export IMMICH_REST_CLI_TOKEN=your-key
immich-rest-cli assets upload --asset-data photo.jpg \
--device-asset-id "id-1" --device-id "script" \
--file-created-at 2026-04-10T00:00:00.000Z \
--file-modified-at 2026-04-10T00:00:00.000Z --filename photo.jpg
Each wrapper's source README (install, auth, real verified commands) lives under wrappers/ in this monorepo.
| Wrapper | PyPI | Source |
|---|---|---|
| openai-rest-cli | pypi | wrappers/openai-rest-cli/ |
| qdrant-rest-cli | pypi | wrappers/qdrant-rest-cli/ |
| meilisearch-rest-cli | pypi | wrappers/meilisearch-rest-cli/ |
| typesense-rest-cli | pypi | wrappers/typesense-rest-cli/ |
| adguard-home-cli | pypi | wrappers/adguard-home-cli/ |
| immich-rest-cli | pypi | wrappers/immich-rest-cli/ |
Tested Against Real APIs
36/36 regression tests passing across 6 live APIs. Full CRUD validated — not just reads.
| API | Type | Tests | Notes |
|---|---|---|---|
| OpenAI | AI/LLM | 8/8 | Models, Chat Completions, Embeddings, Images (DALL-E), Moderations, Files, Vector Stores |
| Qdrant (collections) | Vector DB | 7/7 | Service root, healthz, collections CRUD, exists |
| Qdrant Points | Vector DB | 7/7 | Upsert, get, scroll, count, query-points, cleanup — vector search with real similarity scores |
| Meilisearch | Search | 7/7 | Health, version, indexes, stats, tasks |
| Typesense | Search | 1/1 | Health verified live; documents index --root + search-collection -q ... verified via wrapper |
| GitHub | Public | 6/6 | Meta, licenses, users, rate limit, zen, octocat |
Real commands that work today:
# OpenAI Chat — one command, real GPT-4o-mini response
openapi-cli-gen run --spec <openai-spec> chat create-completion \
--model gpt-4o-mini \
--messages '[{"role":"user","content":"Hello"}]'
# Qdrant vector search — create collection, insert vectors, semantic search
openapi-cli-gen run --spec <qdrant-spec> --base-url http://localhost:6333 \
collections create --collection-name pets \
--vectors '{"size": 4, "distance": "Cosine"}'
openapi-cli-gen run --spec <qdrant-spec> --base-url http://localhost:6333 \
search query-points --collection-name pets \
--query '[0.1, 0.2, 0.3, 0.4]' --limit 5
# Meilisearch — add documents and search, verified against live 1.41
openapi-cli-gen run --spec <meili-spec> --base-url http://localhost:7700 \
documents replace --index-uid movies \
--root '[{"id":1,"title":"The Matrix"}]'
# GitHub — public API, no auth needed
openapi-cli-gen run --spec <github-spec> --base-url https://api.github.com \
users users/get-by-username --username torvalds
See CHANGELOG.md for the full list of bug fixes and improvements.
Compared to Alternatives
| Feature | openapi-cli-gen | specli | restish | Stainless |
|---|---|---|---|---|
| Nested model flattening | All depths | Scalars only | No | 2 levels |
| Generates distributable code | Yes | No | No | Yes |
| Runtime mode (no codegen) | Yes | Yes | Yes | No |
| Pluggable into existing CLI | Yes | No | No | No |
| Open source | Yes | Yes | Yes | No |
Status
Early release. Core features work. Issues and feedback welcome.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openapi_cli_gen-0.0.19.tar.gz.
File metadata
- Download URL: openapi_cli_gen-0.0.19.tar.gz
- Upload date:
- Size: 113.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c457de06ca820c5f05e04b85df024706da9daa5adb020de06d47ef7ce1ffb9b4
|
|
| MD5 |
d1e71c1d44be527207a614f6a548d12d
|
|
| BLAKE2b-256 |
debbd9fce36767f50f9af831e04b0b2a4389524c4c029a7dee901696f10409c6
|
File details
Details for the file openapi_cli_gen-0.0.19-py3-none-any.whl.
File metadata
- Download URL: openapi_cli_gen-0.0.19-py3-none-any.whl
- Upload date:
- Size: 35.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
473b1f7dbb88a3138b3621d8e40fafda50b3b4e05a20a8fc24eda13573ecbd3c
|
|
| MD5 |
6cd11526f90d8ae494c245754c779d53
|
|
| BLAKE2b-256 |
502a3b0c1cc1510d37d438d51465e53133cddcd13b5b61a3f4f8a97ff79a2f2a
|