https://github.com/dymmond/sayer
The Modern Python CLI Framework
https://github.com/dymmond/sayer
attrs click command-line dataclass msgspec pydantic rich rich-text-editor sayer serialization
Last synced: 7 months ago
JSON representation
The Modern Python CLI Framework
- Host: GitHub
- URL: https://github.com/dymmond/sayer
- Owner: dymmond
- License: mit
- Created: 2025-05-15T10:15:36.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-07-21T19:27:24.000Z (8 months ago)
- Last Synced: 2025-08-18T02:55:35.491Z (7 months ago)
- Topics: attrs, click, command-line, dataclass, msgspec, pydantic, rich, rich-text-editor, sayer, serialization
- Language: Python
- Homepage: https://sayer.dymmond.com
- Size: 370 KB
- Stars: 3
- Watchers: 4
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: docs/contributing.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# Sayer
Fast. Scalable. Elegant. Command the CLI like a boss. ๐งโโ๏ธ
---
**Documentation**: [https://sayer.dymmond.com](https://sayer.dymmond.com) ๐
**Source Code**: [https://github.com/dymmond/sayer](https://github.com/dymmond/sayer)
**The official supported version is always the latest released**.
---
## ๐ค What is Sayer?
Sayer is a modern, async-native Python CLI framework built for developers who want more:
- More structure.
- More power.
- More expressiveness.
Less boilerplate. Less headache. Less "why doesn't this just work?".
Designed to scale from weekend scripts to enterprise-grade CLI suites โ with a touch of magic.
---
## ๐ฆ Installation
**Using [pip](https://pip.pypa.io/):**
```bash
pip install sayer
```
**Or with [uv](https://github.com/astral-sh/uv) (blazing fast):**
```bash
uv pip install sayer
```
---
## ๐งฉ Features
* โ
Fully async support out-of-the-box
* โ
Param metadata via `Option(...)`, `Argument(...)`, `Env(...)` โ inspired by the best
* โ
Declarative CLI building with decorators
* โ
Built-in middleware system (yes, for CLI!)
* โ
Shared app state and lifecycle management
* โ
Terminal-rich output via `rich`
* โ
Easy testing with `SayerTestClient`
* โ
Flexible help and docs rendering
* โ
Clean project scaffolding, sensible defaults
* โ
100% type annotated.
---
## ๐ฅ Why Sayer?
| Feature | Sayer | Notes |
| --------------------- | ------------ | --------------------------------- |
| Async Support | โ
Yes | Truly async from top to bottom |
| Param Metadata | โ
Yes | With rich options, env vars, etc. |
| Middleware Support | โ
Yes | Per-command, app-wide, scoped |
| Lifecycle Hooks | โ
Yes | `on_startup`, `on_shutdown` |
| State Management | โ
Yes | Like a Flask `g` but better |
| Testability | โ
Yes | CLI client for unit tests |
| Output Styling | โ
Yes | Built-in `rich` integration |
| Based on Modern Tools | โ
Hatch + UV | Modern dev setup from day 1 |
| Full Typing | โ
Yes | Mypy + Ruff compliant |
| Fun to Use? | ๐บ Extremely | Let the code dance with you |
---
## ๐ Getting Started
Create your first CLI app:
```python
from sayer import Sayer, Option
app = Sayer()
@app.command()
def hello(name: str = Option(..., help="Your name")):
"""Say hello to someone"""
print(f"Hello, {name}!")
if __name__ == "__main__":
app()
```
Run it:
```bash
$ python app.py hello --name Ada
Hello, Ada!
```
---
## ๐งช Testing
```bash
hatch run test:test
```
Or with pytest:
```bash
pytest -v
```
---
## ๐ Documentation
Full docs available at: [https://sayer.dymmond.com](https://sayer.dymmond.com)
Youโll find:
* Full API reference
* Command examples
* Parameter deep dives
* Middleware patterns
* Configuration strategies
* ... and some fun easter eggs ๐ฃ