|
| 1 | +> [!WARNING] |
| 2 | +> **Early Development**: This project is under active development. APIs may |
| 3 | +> change. |
| 4 | +
|
| 5 | +--- |
| 6 | + |
| 7 | +<div align="center"> |
| 8 | + |
| 9 | +<img src="docs/static/logo.png" alt="openapi-burrito logo" width="128" /> |
| 10 | + |
| 11 | +# openapi-burrito |
| 12 | + |
| 13 | +**Wrap your OpenAPI specs in type-safe Python clients** |
| 14 | + |
| 15 | +[](https://pypi.org/project/openapi-burrito/) |
| 16 | +[](https://pypi.org/project/openapi-burrito/) |
| 17 | +[](LICENSE) |
| 18 | +[](https://www.openapis.org/) |
| 19 | + |
| 20 | +</div> |
| 21 | + |
| 22 | +## Table of Contents |
| 23 | + |
| 24 | +- [Quick Start](#quick-start) |
| 25 | +- [Features](#features) |
| 26 | +- [Installation](#installation) |
| 27 | +- [Documentation](#documentation) |
| 28 | +- [Examples](#examples) |
| 29 | +- [Star History](#star-history) |
| 30 | + |
| 31 | +## Quick Start |
| 32 | + |
| 33 | +```bash |
| 34 | +# Install |
| 35 | +uv tool install openapi-burrito |
| 36 | + |
| 37 | +# Generate |
| 38 | +openapi-burrito generate openapi.json -o ./my_client |
| 39 | +``` |
| 40 | + |
| 41 | +```python |
| 42 | +from my_client import Client |
| 43 | + |
| 44 | +api = Client(base_url="https://api.example.com") |
| 45 | + |
| 46 | +# Path-first API: type-checked paths and snake_case parameters |
| 47 | +res = api.GET("/users/{user_id}", user_id=123) |
| 48 | + |
| 49 | +if res.is_success: |
| 50 | + print(res.data) |
| 51 | +else: |
| 52 | + print(f"Error {res.status_code}: {res.error}") |
| 53 | +``` |
| 54 | + |
| 55 | +## Features |
| 56 | + |
| 57 | +- **Path-First API** - Call endpoints by path literal |
| 58 | + (`api.GET("/users/{user_id}")`), with full IDE autocomplete for paths and |
| 59 | + parameters |
| 60 | +- **Type-Safe** - `TypedDict` models and `@overload` signatures |
| 61 | +- **Zero Runtime** - Generated code is yours, no runtime dependency on this tool |
| 62 | +- **httpx-Based** - Async support, connection pooling, all httpx features |
| 63 | +- **Middleware System** - Logging, retry, auth via composable middleware |
| 64 | +- **Snake Case Params** - Path parameters auto-converted to Python style |
| 65 | + (`{userId}` → `{user_id}`) |
| 66 | + |
| 67 | +## Installation |
| 68 | + |
| 69 | +### For Users |
| 70 | + |
| 71 | +```bash |
| 72 | +# As a CLI tool (recommended) |
| 73 | +uv tool install openapi-burrito |
| 74 | + |
| 75 | +# With preview server support (Swagger UI, Redoc) |
| 76 | +uv tool install openapi-burrito[preview] |
| 77 | +``` |
| 78 | + |
| 79 | +### For Developers |
| 80 | + |
| 81 | +```bash |
| 82 | +# Clone and install all dev dependencies |
| 83 | +git clone https://github.com/simon-lund/openapi-burrito.git |
| 84 | +cd openapi-burrito |
| 85 | +make install |
| 86 | + |
| 87 | +# Run linting and type checks |
| 88 | +make lint |
| 89 | + |
| 90 | +# Run tests |
| 91 | +make test |
| 92 | +``` |
| 93 | + |
| 94 | +## Security |
| 95 | + |
| 96 | +This generator sanitizes identifiers and string literals to prevent code |
| 97 | +injection from malformed OpenAPI specs. However, **always review untrusted specs |
| 98 | +before generating**. |
| 99 | + |
| 100 | +### Parser Safety Audit |
| 101 | + |
| 102 | +All fields output by the parser are validated/sanitized: |
| 103 | + |
| 104 | +| Field | Validation | Notes | |
| 105 | +| ------------------------------------- | ---------------------- | ------------------------------------- | |
| 106 | +| Model/param names | `sanitize(mode="id")` | Converted to valid Python identifiers | |
| 107 | +| Paths | `sanitize(mode="str")` | String-escaped for literals | |
| 108 | +| Descriptions/docs | `sanitize(mode="doc")` | Docstring-escaped | |
| 109 | +| `type` strings | Type translator | Built from validated schema types | |
| 110 | +| `method` | `HTTPMethod` enum | Only known HTTP methods allowed | |
| 111 | +| `in` (param location) | Enum check | Only `path\|query\|header\|cookie` | |
| 112 | +| `required`, `read_only`, `write_only` | `bool()` cast | Forced to boolean | |
| 113 | +| `default` | `repr()` | Python string representation | |
| 114 | + |
| 115 | +A malicious spec could attempt injection like: |
| 116 | + |
| 117 | +```yaml |
| 118 | +components: |
| 119 | + schemas: |
| 120 | + "User:\n pass\nimport os; os.system('rm -rf /') # ": |
| 121 | + type: object |
| 122 | +``` |
| 123 | +
|
| 124 | +While this generator escapes such payloads, the safest approach is to only |
| 125 | +generate clients from trusted sources. |
| 126 | +
|
| 127 | +See |
| 128 | +[CVE-2020-15142](https://github.com/openapi-generators/openapi-python-client/security/advisories/GHSA-9x4c-63pf-525f) |
| 129 | +for an example of this vulnerability class in other generators. |
| 130 | +
|
| 131 | +## Documentation |
| 132 | +
|
| 133 | +| Guide | Description | |
| 134 | +| ------------------------------------------- | ---------------------------------------------- | |
| 135 | +| [Introduction](docs/01-introduction.md) | Installation and basic usage | |
| 136 | +| [Authentication](docs/02-authentication.md) | API keys, tokens, OAuth patterns | |
| 137 | +| [Middleware](docs/03-middleware.md) | Logging, retry, custom handling | |
| 138 | +| [Type System](docs/04-type-system.md) | `UNSET`, `Unknown`, `NotRequired`, limitations | |
| 139 | +| [CLI Reference](docs/05-cli-reference.md) | `generate` and `preview` commands | |
| 140 | +| [Contributing](docs/06-contributing.md) | Development setup and guidelines | |
| 141 | + |
| 142 | +## Examples |
| 143 | + |
| 144 | +See the [`examples/`](examples/) directory: |
| 145 | + |
| 146 | +- **[Petstore](examples/petstore/)** - Classic Swagger Petstore API |
| 147 | +- **[Artifacts MMO](examples/artifactsmmo/)** - Game API with complex schemas |
| 148 | + |
| 149 | +## Star History |
| 150 | + |
| 151 | +[](https://www.star-history.com/#klementine/openapi-burrito&type=date&legend=top-left) |
0 commit comments