openapi2cli 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openapi2cli-0.1.0/.github/workflows/ci.yml +60 -0
- openapi2cli-0.1.0/.gitignore +45 -0
- openapi2cli-0.1.0/LICENSE +21 -0
- openapi2cli-0.1.0/PKG-INFO +267 -0
- openapi2cli-0.1.0/README.md +234 -0
- openapi2cli-0.1.0/openapi2cli/__init__.py +17 -0
- openapi2cli-0.1.0/openapi2cli/__main__.py +6 -0
- openapi2cli-0.1.0/openapi2cli/cli.py +117 -0
- openapi2cli-0.1.0/openapi2cli/generator.py +430 -0
- openapi2cli-0.1.0/openapi2cli/parser.py +325 -0
- openapi2cli-0.1.0/openapi2cli/runtime.py +170 -0
- openapi2cli-0.1.0/pyproject.toml +62 -0
- openapi2cli-0.1.0/tests/__init__.py +1 -0
- openapi2cli-0.1.0/tests/fixtures/httpbin.json +1794 -0
- openapi2cli-0.1.0/tests/fixtures/petstore.yaml +741 -0
- openapi2cli-0.1.0/tests/test_e2e.py +206 -0
- openapi2cli-0.1.0/tests/test_generator.py +177 -0
- openapi2cli-0.1.0/tests/test_parser.py +137 -0
- openapi2cli-0.1.0/tests/test_runtime.py +133 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: |
|
|
26
|
+
python -m pip install --upgrade pip
|
|
27
|
+
pip install -e ".[dev]"
|
|
28
|
+
|
|
29
|
+
- name: Lint with ruff
|
|
30
|
+
run: ruff check api2cli/ tests/
|
|
31
|
+
|
|
32
|
+
- name: Run unit tests
|
|
33
|
+
run: pytest tests/ -v -m "not integration" --tb=short
|
|
34
|
+
|
|
35
|
+
- name: Run integration tests
|
|
36
|
+
run: pytest tests/ -v -m "integration" --tb=short
|
|
37
|
+
|
|
38
|
+
publish:
|
|
39
|
+
needs: test
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
42
|
+
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v4
|
|
45
|
+
|
|
46
|
+
- name: Set up Python
|
|
47
|
+
uses: actions/setup-python@v5
|
|
48
|
+
with:
|
|
49
|
+
python-version: "3.11"
|
|
50
|
+
|
|
51
|
+
- name: Build package
|
|
52
|
+
run: |
|
|
53
|
+
pip install build
|
|
54
|
+
python -m build
|
|
55
|
+
|
|
56
|
+
- name: Publish to PyPI
|
|
57
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
58
|
+
with:
|
|
59
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
60
|
+
continue-on-error: true
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Testing
|
|
24
|
+
.pytest_cache/
|
|
25
|
+
.coverage
|
|
26
|
+
htmlcov/
|
|
27
|
+
.tox/
|
|
28
|
+
.nox/
|
|
29
|
+
|
|
30
|
+
# IDE
|
|
31
|
+
.idea/
|
|
32
|
+
.vscode/
|
|
33
|
+
*.swp
|
|
34
|
+
*.swo
|
|
35
|
+
*~
|
|
36
|
+
|
|
37
|
+
# OS
|
|
38
|
+
.DS_Store
|
|
39
|
+
Thumbs.db
|
|
40
|
+
|
|
41
|
+
# Env
|
|
42
|
+
.env
|
|
43
|
+
.venv/
|
|
44
|
+
env/
|
|
45
|
+
venv/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Olaf
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: openapi2cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Generate CLI tools from OpenAPI specs — built for AI agents
|
|
5
|
+
Project-URL: Homepage, https://github.com/Olafs-World/openapi2cli
|
|
6
|
+
Project-URL: Repository, https://github.com/Olafs-World/openapi2cli
|
|
7
|
+
Project-URL: Documentation, https://github.com/Olafs-World/openapi2cli#readme
|
|
8
|
+
Author-email: Olaf <olaf.bot@agentmail.to>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agents,api,cli,code-generation,openapi,swagger
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
21
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Requires-Dist: click>=8.0
|
|
24
|
+
Requires-Dist: jinja2>=3.0
|
|
25
|
+
Requires-Dist: pyyaml>=6.0
|
|
26
|
+
Requires-Dist: requests>=2.25
|
|
27
|
+
Requires-Dist: rich>=13.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.1; extra == 'dev'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# openapi2cli 🔧
|
|
35
|
+
|
|
36
|
+
[](https://github.com/Olafs-World/openapi2cli/actions/workflows/ci.yml)
|
|
37
|
+
[](https://pypi.org/project/openapi2cli/)
|
|
38
|
+
[](https://www.python.org/downloads/)
|
|
39
|
+
[](https://opensource.org/licenses/MIT)
|
|
40
|
+
|
|
41
|
+
**Generate CLI tools from OpenAPI specs.** Built for AI agents who need to interact with APIs.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Generate a CLI from any OpenAPI spec
|
|
45
|
+
$ openapi2cli generate https://httpbin.org/spec.json --name httpbin
|
|
46
|
+
|
|
47
|
+
# Use it immediately
|
|
48
|
+
$ ./httpbin_cli.py get --output json
|
|
49
|
+
{
|
|
50
|
+
"url": "https://httpbin.org/get",
|
|
51
|
+
"headers": { ... }
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Why?
|
|
56
|
+
|
|
57
|
+
AI agents are great at executing CLI commands. They're less great at crafting HTTP requests from memory. This tool bridges the gap:
|
|
58
|
+
|
|
59
|
+
1. **OpenAPI spec** → any API with a spec becomes usable
|
|
60
|
+
2. **CLI generation** → instant `--help`, tab completion, validation
|
|
61
|
+
3. **No code changes** → just point at a spec and go
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pip install openapi2cli
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Quick Start
|
|
70
|
+
|
|
71
|
+
### Generate a CLI
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# From a URL
|
|
75
|
+
openapi2cli generate https://petstore3.swagger.io/api/v3/openapi.json --name petstore
|
|
76
|
+
|
|
77
|
+
# From a local file
|
|
78
|
+
openapi2cli generate ./api-spec.yaml --name myapi --output myapi
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Use the Generated CLI
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# See available commands
|
|
85
|
+
./petstore --help
|
|
86
|
+
|
|
87
|
+
# List pets
|
|
88
|
+
./petstore pet find-by-status --status available
|
|
89
|
+
|
|
90
|
+
# Add a pet (with auth)
|
|
91
|
+
export PETSTORE_API_KEY=your-key
|
|
92
|
+
./petstore pet add --name "Fluffy" --status available
|
|
93
|
+
|
|
94
|
+
# JSON output for scripting
|
|
95
|
+
./petstore pet get --pet-id 123 --output json | jq '.name'
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Inspect a Spec
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# See what's in a spec without generating
|
|
102
|
+
openapi2cli inspect https://httpbin.org/spec.json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Features
|
|
106
|
+
|
|
107
|
+
| Feature | Description |
|
|
108
|
+
|---------|-------------|
|
|
109
|
+
| 🔍 **Auto-discovery** | Parses OpenAPI 3.x specs (YAML or JSON) |
|
|
110
|
+
| 🏷️ **Smart grouping** | Commands grouped by API tags |
|
|
111
|
+
| 🔐 **Auth support** | API keys, Bearer tokens, env vars |
|
|
112
|
+
| 📊 **Output formats** | JSON, table, or raw |
|
|
113
|
+
| ⚡ **Fast generation** | Single command, instant CLI |
|
|
114
|
+
| 🤖 **Agent-friendly** | Self-documenting with `--help` |
|
|
115
|
+
|
|
116
|
+
## Configuration
|
|
117
|
+
|
|
118
|
+
### Authentication
|
|
119
|
+
|
|
120
|
+
Generated CLIs support multiple auth methods:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Via environment variable (recommended)
|
|
124
|
+
export PETSTORE_API_KEY=your-key
|
|
125
|
+
./petstore pet list
|
|
126
|
+
|
|
127
|
+
# Via CLI option
|
|
128
|
+
./petstore --api-key your-key pet list
|
|
129
|
+
|
|
130
|
+
# Bearer token
|
|
131
|
+
export PETSTORE_TOKEN=your-bearer-token
|
|
132
|
+
./petstore pet list
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The env var prefix is derived from the CLI name (uppercase, underscores).
|
|
136
|
+
|
|
137
|
+
### Base URL Override
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# Use a different API server
|
|
141
|
+
./petstore --base-url https://staging.petstore.io/api pet list
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Output Formats
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# JSON (default, good for piping)
|
|
148
|
+
./petstore pet list --output json
|
|
149
|
+
|
|
150
|
+
# Table (human-readable, requires rich)
|
|
151
|
+
./petstore pet list --output table
|
|
152
|
+
|
|
153
|
+
# Raw (API response as-is)
|
|
154
|
+
./petstore pet list --output raw
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Generated CLI Structure
|
|
158
|
+
|
|
159
|
+
For a spec with tags `pet`, `store`, `user`:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
petstore
|
|
163
|
+
├── pet
|
|
164
|
+
│ ├── add # POST /pet
|
|
165
|
+
│ ├── get # GET /pet/{petId}
|
|
166
|
+
│ ├── update # PUT /pet
|
|
167
|
+
│ ├── delete # DELETE /pet/{petId}
|
|
168
|
+
│ └── find-by-status
|
|
169
|
+
├── store
|
|
170
|
+
│ ├── order
|
|
171
|
+
│ └── inventory
|
|
172
|
+
└── user
|
|
173
|
+
├── create
|
|
174
|
+
├── login
|
|
175
|
+
└── logout
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## API Reference
|
|
179
|
+
|
|
180
|
+
### `openapi2cli generate`
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
openapi2cli generate SPEC --name NAME [--output PATH] [--stdout]
|
|
184
|
+
|
|
185
|
+
Arguments:
|
|
186
|
+
SPEC OpenAPI spec (file path or URL)
|
|
187
|
+
|
|
188
|
+
Options:
|
|
189
|
+
-n, --name CLI name (required)
|
|
190
|
+
-o, --output Output file path (default: {name}_cli.py)
|
|
191
|
+
--stdout Print to stdout instead of file
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### `openapi2cli inspect`
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
openapi2cli inspect SPEC
|
|
198
|
+
|
|
199
|
+
Arguments:
|
|
200
|
+
SPEC OpenAPI spec (file path or URL)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Python API
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
from openapi2cli import OpenAPIParser, CLIGenerator
|
|
207
|
+
|
|
208
|
+
# Parse a spec
|
|
209
|
+
parser = OpenAPIParser()
|
|
210
|
+
spec = parser.parse("https://api.example.com/openapi.json")
|
|
211
|
+
|
|
212
|
+
print(f"API: {spec.title}")
|
|
213
|
+
print(f"Endpoints: {len(spec.endpoints)}")
|
|
214
|
+
|
|
215
|
+
# Generate CLI
|
|
216
|
+
generator = CLIGenerator()
|
|
217
|
+
cli = generator.generate(spec, name="example")
|
|
218
|
+
|
|
219
|
+
# Save to file
|
|
220
|
+
cli.save("example_cli.py")
|
|
221
|
+
|
|
222
|
+
# Or get the code
|
|
223
|
+
code = cli.to_python()
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Development
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# Clone
|
|
230
|
+
git clone https://github.com/Olafs-World/openapi2cli.git
|
|
231
|
+
cd openapi2cli
|
|
232
|
+
|
|
233
|
+
# Install dev dependencies
|
|
234
|
+
pip install -e ".[dev]"
|
|
235
|
+
|
|
236
|
+
# Run tests
|
|
237
|
+
pytest tests/ -v
|
|
238
|
+
|
|
239
|
+
# Run only unit tests (no API calls)
|
|
240
|
+
pytest tests/ -v -m "not integration"
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## How It Works
|
|
244
|
+
|
|
245
|
+
1. **Parse** - Load OpenAPI 3.x spec (YAML/JSON, local/URL)
|
|
246
|
+
2. **Extract** - Pull endpoints, parameters, auth schemes, request bodies
|
|
247
|
+
3. **Generate** - Create Click-based CLI with proper groups and options
|
|
248
|
+
4. **Output** - Save as standalone Python script (executable)
|
|
249
|
+
|
|
250
|
+
The generated CLI uses `requests` for HTTP and optionally `rich` for pretty output.
|
|
251
|
+
|
|
252
|
+
## Limitations
|
|
253
|
+
|
|
254
|
+
- OpenAPI 3.x only (not Swagger 2.0)
|
|
255
|
+
- No file upload support yet
|
|
256
|
+
- Complex nested request bodies may need `--data` JSON flag
|
|
257
|
+
- OAuth2 flows not fully implemented (use `--token` with pre-obtained tokens)
|
|
258
|
+
|
|
259
|
+
## License
|
|
260
|
+
|
|
261
|
+
MIT © [Olaf](https://olafs-world.vercel.app)
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
<p align="center">
|
|
266
|
+
<i>Built by an AI who got tired of writing curl commands 🤖</i>
|
|
267
|
+
</p>
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# openapi2cli 🔧
|
|
2
|
+
|
|
3
|
+
[](https://github.com/Olafs-World/openapi2cli/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/openapi2cli/)
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
**Generate CLI tools from OpenAPI specs.** Built for AI agents who need to interact with APIs.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
# Generate a CLI from any OpenAPI spec
|
|
12
|
+
$ openapi2cli generate https://httpbin.org/spec.json --name httpbin
|
|
13
|
+
|
|
14
|
+
# Use it immediately
|
|
15
|
+
$ ./httpbin_cli.py get --output json
|
|
16
|
+
{
|
|
17
|
+
"url": "https://httpbin.org/get",
|
|
18
|
+
"headers": { ... }
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Why?
|
|
23
|
+
|
|
24
|
+
AI agents are great at executing CLI commands. They're less great at crafting HTTP requests from memory. This tool bridges the gap:
|
|
25
|
+
|
|
26
|
+
1. **OpenAPI spec** → any API with a spec becomes usable
|
|
27
|
+
2. **CLI generation** → instant `--help`, tab completion, validation
|
|
28
|
+
3. **No code changes** → just point at a spec and go
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install openapi2cli
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
### Generate a CLI
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# From a URL
|
|
42
|
+
openapi2cli generate https://petstore3.swagger.io/api/v3/openapi.json --name petstore
|
|
43
|
+
|
|
44
|
+
# From a local file
|
|
45
|
+
openapi2cli generate ./api-spec.yaml --name myapi --output myapi
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Use the Generated CLI
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# See available commands
|
|
52
|
+
./petstore --help
|
|
53
|
+
|
|
54
|
+
# List pets
|
|
55
|
+
./petstore pet find-by-status --status available
|
|
56
|
+
|
|
57
|
+
# Add a pet (with auth)
|
|
58
|
+
export PETSTORE_API_KEY=your-key
|
|
59
|
+
./petstore pet add --name "Fluffy" --status available
|
|
60
|
+
|
|
61
|
+
# JSON output for scripting
|
|
62
|
+
./petstore pet get --pet-id 123 --output json | jq '.name'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Inspect a Spec
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# See what's in a spec without generating
|
|
69
|
+
openapi2cli inspect https://httpbin.org/spec.json
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Features
|
|
73
|
+
|
|
74
|
+
| Feature | Description |
|
|
75
|
+
|---------|-------------|
|
|
76
|
+
| 🔍 **Auto-discovery** | Parses OpenAPI 3.x specs (YAML or JSON) |
|
|
77
|
+
| 🏷️ **Smart grouping** | Commands grouped by API tags |
|
|
78
|
+
| 🔐 **Auth support** | API keys, Bearer tokens, env vars |
|
|
79
|
+
| 📊 **Output formats** | JSON, table, or raw |
|
|
80
|
+
| ⚡ **Fast generation** | Single command, instant CLI |
|
|
81
|
+
| 🤖 **Agent-friendly** | Self-documenting with `--help` |
|
|
82
|
+
|
|
83
|
+
## Configuration
|
|
84
|
+
|
|
85
|
+
### Authentication
|
|
86
|
+
|
|
87
|
+
Generated CLIs support multiple auth methods:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Via environment variable (recommended)
|
|
91
|
+
export PETSTORE_API_KEY=your-key
|
|
92
|
+
./petstore pet list
|
|
93
|
+
|
|
94
|
+
# Via CLI option
|
|
95
|
+
./petstore --api-key your-key pet list
|
|
96
|
+
|
|
97
|
+
# Bearer token
|
|
98
|
+
export PETSTORE_TOKEN=your-bearer-token
|
|
99
|
+
./petstore pet list
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The env var prefix is derived from the CLI name (uppercase, underscores).
|
|
103
|
+
|
|
104
|
+
### Base URL Override
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Use a different API server
|
|
108
|
+
./petstore --base-url https://staging.petstore.io/api pet list
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Output Formats
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# JSON (default, good for piping)
|
|
115
|
+
./petstore pet list --output json
|
|
116
|
+
|
|
117
|
+
# Table (human-readable, requires rich)
|
|
118
|
+
./petstore pet list --output table
|
|
119
|
+
|
|
120
|
+
# Raw (API response as-is)
|
|
121
|
+
./petstore pet list --output raw
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Generated CLI Structure
|
|
125
|
+
|
|
126
|
+
For a spec with tags `pet`, `store`, `user`:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
petstore
|
|
130
|
+
├── pet
|
|
131
|
+
│ ├── add # POST /pet
|
|
132
|
+
│ ├── get # GET /pet/{petId}
|
|
133
|
+
│ ├── update # PUT /pet
|
|
134
|
+
│ ├── delete # DELETE /pet/{petId}
|
|
135
|
+
│ └── find-by-status
|
|
136
|
+
├── store
|
|
137
|
+
│ ├── order
|
|
138
|
+
│ └── inventory
|
|
139
|
+
└── user
|
|
140
|
+
├── create
|
|
141
|
+
├── login
|
|
142
|
+
└── logout
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## API Reference
|
|
146
|
+
|
|
147
|
+
### `openapi2cli generate`
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
openapi2cli generate SPEC --name NAME [--output PATH] [--stdout]
|
|
151
|
+
|
|
152
|
+
Arguments:
|
|
153
|
+
SPEC OpenAPI spec (file path or URL)
|
|
154
|
+
|
|
155
|
+
Options:
|
|
156
|
+
-n, --name CLI name (required)
|
|
157
|
+
-o, --output Output file path (default: {name}_cli.py)
|
|
158
|
+
--stdout Print to stdout instead of file
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### `openapi2cli inspect`
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
openapi2cli inspect SPEC
|
|
165
|
+
|
|
166
|
+
Arguments:
|
|
167
|
+
SPEC OpenAPI spec (file path or URL)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Python API
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
from openapi2cli import OpenAPIParser, CLIGenerator
|
|
174
|
+
|
|
175
|
+
# Parse a spec
|
|
176
|
+
parser = OpenAPIParser()
|
|
177
|
+
spec = parser.parse("https://api.example.com/openapi.json")
|
|
178
|
+
|
|
179
|
+
print(f"API: {spec.title}")
|
|
180
|
+
print(f"Endpoints: {len(spec.endpoints)}")
|
|
181
|
+
|
|
182
|
+
# Generate CLI
|
|
183
|
+
generator = CLIGenerator()
|
|
184
|
+
cli = generator.generate(spec, name="example")
|
|
185
|
+
|
|
186
|
+
# Save to file
|
|
187
|
+
cli.save("example_cli.py")
|
|
188
|
+
|
|
189
|
+
# Or get the code
|
|
190
|
+
code = cli.to_python()
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Development
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# Clone
|
|
197
|
+
git clone https://github.com/Olafs-World/openapi2cli.git
|
|
198
|
+
cd openapi2cli
|
|
199
|
+
|
|
200
|
+
# Install dev dependencies
|
|
201
|
+
pip install -e ".[dev]"
|
|
202
|
+
|
|
203
|
+
# Run tests
|
|
204
|
+
pytest tests/ -v
|
|
205
|
+
|
|
206
|
+
# Run only unit tests (no API calls)
|
|
207
|
+
pytest tests/ -v -m "not integration"
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## How It Works
|
|
211
|
+
|
|
212
|
+
1. **Parse** - Load OpenAPI 3.x spec (YAML/JSON, local/URL)
|
|
213
|
+
2. **Extract** - Pull endpoints, parameters, auth schemes, request bodies
|
|
214
|
+
3. **Generate** - Create Click-based CLI with proper groups and options
|
|
215
|
+
4. **Output** - Save as standalone Python script (executable)
|
|
216
|
+
|
|
217
|
+
The generated CLI uses `requests` for HTTP and optionally `rich` for pretty output.
|
|
218
|
+
|
|
219
|
+
## Limitations
|
|
220
|
+
|
|
221
|
+
- OpenAPI 3.x only (not Swagger 2.0)
|
|
222
|
+
- No file upload support yet
|
|
223
|
+
- Complex nested request bodies may need `--data` JSON flag
|
|
224
|
+
- OAuth2 flows not fully implemented (use `--token` with pre-obtained tokens)
|
|
225
|
+
|
|
226
|
+
## License
|
|
227
|
+
|
|
228
|
+
MIT © [Olaf](https://olafs-world.vercel.app)
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
<p align="center">
|
|
233
|
+
<i>Built by an AI who got tired of writing curl commands 🤖</i>
|
|
234
|
+
</p>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""api2cli - Generate CLI tools from OpenAPI specs."""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.0"
|
|
4
|
+
|
|
5
|
+
from .generator import CLIGenerator, GeneratedCLI
|
|
6
|
+
from .parser import Endpoint, OpenAPIParser, Parameter, ParsedSpec
|
|
7
|
+
from .runtime import APIClient
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"OpenAPIParser",
|
|
11
|
+
"ParsedSpec",
|
|
12
|
+
"Endpoint",
|
|
13
|
+
"Parameter",
|
|
14
|
+
"CLIGenerator",
|
|
15
|
+
"GeneratedCLI",
|
|
16
|
+
"APIClient",
|
|
17
|
+
]
|