Generates typed Python CLIs from OpenAPI 3.x specs. Nested request bodies become flat --flags.
.venv/bin/python -m pytest tests/ -q # run tests (50, ~1s)
uv pip install -e . --python .venv/bin/python # dev install
.venv/bin/python scripts/regenerate.py # regenerate all wrapper CLIs
.venv/bin/python scripts/regenerate.py --publish --push # + PyPI + GitHub
.venv/bin/python scripts/regenerate.py --only qdrant-rest-cli # single wrapperspec/loader.py → load spec (file/URL), resolve $refs
spec/parser.py → extract endpoints from spec
engine/models.py → Pydantic models via datamodel-code-generator (disk cached in ~/.cache/openapi-cli-gen/)
engine/builder.py → build_cli() / build_command_group() public API
engine/dispatch.py → CLI dispatch (group → command → HTTP call)
engine/auth.py → bearer, api-key, basic auth
codegen/generator.py → generate installable package (Jinja2 templates)
cli.py → typer CLI: generate, run, inspect
Six CLIs, each in its own repo/PyPI package. Config in wrappers/manifest.yaml.
| Name | Repo |
|---|---|
| openai-rest-cli | shivaam/openai-rest-cli |
| meilisearch-rest-cli | shivaam/meilisearch-rest-cli |
| adguard-home-cli | shivaam/adguard-home-cli |
| immich-rest-cli | shivaam/immich-rest-cli |
| qdrant-rest-cli | shivaam/qdrant-rest-cli |
| typesense-rest-cli | shivaam/typesense-rest-cli |
Hand-written READMEs in wrappers/<name>/README.md are copied into generated packages.
- Bump version in both
pyproject.tomlandsrc/openapi_cli_gen/__init__.py python -m build && python -m twine upload dist/*- Bump
versioninwrappers/manifest.yaml(PyPI rejects duplicate versions) python scripts/regenerate.py --publish --push
- Dashes for CLI/PyPI names, underscores for Python packages
- Auth env vars:
{PREFIX}_TOKEN,{PREFIX}_API_KEY,{PREFIX}_USERNAME/{PREFIX}_PASSWORD - SSL env vars:
{PREFIX}_VERIFY_SSL,{PREFIX}_CA_CERT,{PREFIX}_CLIENT_CERT,{PREFIX}_CLIENT_KEY --rootflag on POST/PUT/PATCH accepts raw JSON, bypassing typed flags