https://github.com/phalt/clientele
A different way to build Python API Clients
https://github.com/phalt/clientele
api api-rest asyncio django-ninja django-rest-framework fastapi httpx openapi pydantic python
Last synced: 4 days ago
JSON representation
A different way to build Python API Clients
- Host: GitHub
- URL: https://github.com/phalt/clientele
- Owner: phalt
- License: mit
- Created: 2023-07-21T07:13:34.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2026-01-11T13:09:42.000Z (16 days ago)
- Last Synced: 2026-01-11T16:03:25.981Z (16 days ago)
- Topics: api, api-rest, asyncio, django-ninja, django-rest-framework, fastapi, httpx, openapi, pydantic, python
- Language: Python
- Homepage: http://docs.clientele.dev/
- Size: 17 MB
- Stars: 121
- Watchers: 2
- Forks: 8
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
Awesome Lists containing this project
README
# ⚜️ Clientele

[](https://pypi.org/project/clientele)


[](https://codecov.io/github/phalt/clientele)
[](https://pepy.tech/projects/clientele)


## Example code
```python
from clientele import api
from pydantic import BaseModel
client = api.APIClient(base_url="https://pokeapi.co/api/v2/")
class Pokemon(BaseModel):
name: str
@client.get("/pokemon/{id}")
def get_pokemon_name(id: int, result: Pokemon) -> str:
return result.name
```
[See more examples](https://docs.clientele.dev/api-examples/)
## Why use Clientele?
- **A comfortable abstraction** - Encourages consistency and focus on the functionality.
- **Easy to learn** - Clientele is visually similar to popular python API server frameworks.
- **Easy to test** - Comes with built-in testing tools.
- **Easy to configure** - Sensible HTTP defaults and plenty of hooks for customisation.
- **Easy data validation** - Built in data validation using [Pydantic](https://docs.pydantic.dev/latest/).
- **Core built-ins** - Caching, Network, and Retry handling built specifically for HTTP.
- **Use your own HTTP** - Clientele can support any Python HTTP library.
- **OpenAPI support** - Build your own client, or scaffold one from an OpenAPI schema.
## Async support
```python
@client.get("/pokemon/{id}")
async def get_pokemon_name(id: int, result: Pokemon) -> str:
return result.name
```
## Automatic data validation
```python
from clientele import api as clientele_api
from .my_pydantic_models import CreateBookRequest, CreateBookResponse
client = clientele_api.APIClient(base_url="http://localhost:8000")
@client.post("/books")
def create_book(data: CreateBookRequest, result: CreateBookResponse) -> CreateBookResponse:
return result
```
## Streaming responses
```python
from typing import AsyncIterator
from clientele import api
from pydantic import BaseModel
client = api.APIClient(base_url="https://httpbin.org")
class Event(BaseModel):
id: int
url: str
@client.get("/stream/{n}", streaming_response=True)
async def stream_events(n: int, result: AsyncIterator[Event]) -> AsyncIterator[Event]:
return result
```
## Works with Python API frameworks
Building an API service in Python? Clientele can build you a client library in seconds.
Clientele is built and tested to be 100% compatible with the OpenAPI schemas generated from:
- **FastAPI**
- **Django REST Framework** via **drf-spectacular**
- **Django Ninja**
See the working demos in our [`server_examples/`](https://github.com/phalt/clientele/tree/main/server_examples) directory.
## OpenAPI support
Clientele can create scaffolding for an API client from an OpenAPI schema with:
- **Pydantic models** generated from the schema objects.
- **Decorated function signatures** generated from schema operations.
- **Async support** if you want a client with concurrency.
- **A tiny output** that is only 3 files big.
- **Regeneration-friendly** - update your API, regenerate, review the git diff, then ship it!
- **Formatted code** thanks to [Ruff](https://docs.astral.sh/ruff/).

## Getting Started
👉 Read the [full documentation](https://docs.clientele.dev/) for all documentation.