Chilo is a lightweight, form-meets-function, opinionated (yet highly configurable) api framework.
Project description
🐍 Chilo
Chilo is a lightweight, form-meets-function, opinionated (yet highly configurable) API framework.
Chilo (short for chilorhinophis, the two-headed snake) auto-routes requests straight from your directory tree, applies OpenAPI or custom validation before your handlers run, and keeps REST + gRPC services declarative and composable.
📖 Documentation & Examples
Full Documentation · Examples · Community Discussions
🎯 Why Chilo?
- 🚀 Zero Route Boilerplate – File paths become URLs; dynamic segments are inferred from file names.
- ✅ Built-in Validation – Apply OpenAPI schemas (request + response) or lightweight requirement decorators.
- 🧱 Middlewares Everywhere –
before,after,when_auth_required, and global hooks keep cross-cutting logic centralized. - 🔔 Lifecycle Hooks –
on_startup/on_shutdownlet you register callables that fire once when the router boots and when it stops. - 🔁 REST + gRPC – Switch between HTTP and gRPC by flipping
api_typeand pointing at protobufs. - 📜 Spec Generation – Inspect handlers + requirements to emit
openapi.yml/openapi.jsonwith a single CLI command. - ⚙️ Deploy-Friendly – Works with gunicorn or the built-in CLI; supports TLS, CORS, hot reload, and custom executors.
Happy Path Programming
Validate the world up front, then write business logic as if everything is already correct.
# ❌ Without Chilo
def handler(environ, start_response):
body = json.loads(environ.get('body') or '{}')
if 'email' not in body:
return error(400, 'email required')
if '@' not in body['email']:
return error(400, 'invalid email')
# more guards ...
return ok({'user': create(body)})
# ✅ With Chilo
from chilo_api import requirements, Request, Response
@requirements(required_body='v1-create-user')
def post(request: Request, response: Response) -> Response:
response.body = {'user': create(request.body)} # already validated
return response
📦 Installation
pip install chilo_api
# pipenv install chilo_api
# poetry add chilo_api
Supports Python 3.8
🚀 Quick Start · REST
1. Configure the API (e.g., api/main.py)
from chilo_api import Chilo
from chilo_api import logger
def cleanup_connections():
# close DB pools, flush caches, etc.
pass
api = Chilo(
base_path='/',
handlers='api/handlers',
cors=True,
on_startup=[lambda: logger.log(level='INFO', log='API booted')],
on_shutdown=[cleanup_connections],
openapi='api/openapi.yml', # optional
openapi_validate_request=False, # flip on when ready
openapi_validate_response=False
)
2. Create a Handler (api/handlers/__init__.py)
from chilo_api import Request, Response, requirements
@requirements(required_query=['greeting'])
def get(request: Request, response: Response) -> Response:
response.body = {'hello': request.query_params['greeting']}
return response
3. Run It
python -m chilo_api serve --api=api.main --reload=true
Visit http://127.0.0.1:3000/?greeting=developer
Directory → Route Mapping
api/handlers
├── __init__.py → /
├── user/__init__.py → /user
├── user/_user_id.py → /user/{user_id}
└── reports/daily.py → /reports/daily
Dynamic segments are prefixed with _ in file names (or directories) and become {param} tokens at runtime.
📡 Quick Start · gRPC
1. Define the API (api/main_grpc.py)
from chilo_api import Chilo
api = Chilo(
api_type='grpc',
handlers='api/handlers',
protobufs='api/protobufs',
reflection=True,
port=50051
)
2. Author Your Proto (api/protobufs/calculator.proto)
syntax = "proto3";
package calculator;
service Calculator {
rpc Add(CalcRequest) returns (CalcResponse);
}
message CalcRequest { double num1 = 1; double num2 = 2; }
message CalcResponse { double result = 1; }
3. Implement the Handler (api/handlers/__init__.py)
from chilo_api import requirements, Request, Response
@requirements(protobuf='calculator.proto', service='Calculator', rpc='Add')
def add(request: Request, response: Response) -> Response:
response.body = {'result': request.body.get('num1', 0) + request.body.get('num2', 0)}
return response
4. Serve It
python -m chilo_api serve --api=api.main_grpc
🧰 CLI Highlights
| Command | Description |
|---|---|
python -m chilo_api serve --api=api.main |
Run REST or gRPC servers with hot reload, TLS, verbose logging, etc. |
python -m chilo_api generate-openapi --api=api.main --output=docs --format=yml,json |
Inspect handlers + requirements to (re)build OpenAPI docs. |
Both commands accept switches for host, port, reload, private key/cert, worker count, and validation flags.
🤝 Contributing
Issues and PRs are welcome! Check SECURITY.md before reporting vulnerabilities and open a discussion if you want to propose larger features. For docs fixes, see chilo-docs.
📜 License
Chilo is released under the MIT License.
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 chilo_api-2.0.2.tar.gz.
File metadata
- Download URL: chilo_api-2.0.2.tar.gz
- Upload date:
- Size: 84.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.17
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eaf097ffd5a35ce3e026fa7280a77c45a1a6eed6718aaee21c3a8cfc201f2ee9
|
|
| MD5 |
2bea296e2e69a3ec1be6c28e752cd59c
|
|
| BLAKE2b-256 |
aa0309c8a223ad8753a1ea5f05bfa9be8733f08cbe4c04d3979697fb25f550a7
|
File details
Details for the file chilo_api-2.0.2-py3-none-any.whl.
File metadata
- Download URL: chilo_api-2.0.2-py3-none-any.whl
- Upload date:
- Size: 114.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.17
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc7dec4de04a86d1cc9edc3fcb33b7e98c221ded905b26d5c8b4284f4675dc86
|
|
| MD5 |
2b4b4686092a3319e39c61b457350fbb
|
|
| BLAKE2b-256 |
f3c064ea78938feecd1e95bc703d4b397ed6d4a75ee426f5766e951c7ba7793c
|