Skip to main content

Sayer

Sayer logo

Fast. Scalable. Elegant. Command the CLI like a boss. 🧙‍♂️

Test Suite Package version Supported Python versions


Documentation: https://sayer.dymmond.com 📚

Source Code: 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:

pip install sayer

Or with uv (blazing fast):

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 Ty + Ruff compliant
Fun to Use? 🕺 Extremely Let the code dance with you

🚀 Getting Started

Create your first CLI app:

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:

$ python app.py hello --name Ada
Hello, Ada!

🧪 Testing

hatch run test:test

Or with pytest:

pytest -v

📚 Documentation

Full docs available at: https://sayer.dymmond.com

You'll find:

  • Full API reference
  • Command examples
  • Parameter deep dives
  • Middleware patterns
  • Configuration strategies
  • ... and some fun easter eggs 🐣

Metadata

Release files for sayer 0.8.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sayer 0.8.2
File Size Uploaded Provenance Actions
sayer-0.8.2.tar.gz 70.0 kB Without provenance Details for sayer-0.8.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for sayer 0.8.2
File Interpreter ABI Platform Actions
sayer-0.8.2-py3-none-any.whl Python 3 none any Details for sayer-0.8.2-py3-none-any.whl

Total release size: 155.5 kB

Release files / sayer-0.8.2.tar.gz

Download URL sayer-0.8.2.tar.gz
Size 70.0 kB
Tags Source
SHA-256 checksum
How to use checksums
d7fd24327a3e4d56827a41cf235cd4ab273e39acfb0c470b81fa2bece98488dd
BLAKE2b-256 checksum
How to use checksums
13de8153970f8e2fdb903138b75366a86dcdb1d9887fbfef44ed13ec74124b96
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.18.2 {"ci":true,"cpu":"x86_64","distro":{"id":"resolute","libc":{"lib":"glibc","version":"2.43"},"name":"Ubuntu","version":"26.04"},"implementation":{"name":"CPython","version":"3.12.16"},"installer":{"name":"hatch","version":"1.18.2"},"openssl_version":"OpenSSL 3.5.5 27 Jan 2026","python":"3.12.16","system":{"name":"Linux","release":"7.0.0-1019-azure"}} HTTPX2/2.16.0

Release files / sayer-0.8.2-py3-none-any.whl

Download URL sayer-0.8.2-py3-none-any.whl
Size 85.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0a765282c7477dd519ed97c059cc197d30536bde992c2242bec4333d15d75944
BLAKE2b-256 checksum
How to use checksums
5f9cf008b65ba36568e6a1ebb9440afec4ea5d0156bde3d07f44dfaf24109980
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.18.2 {"ci":true,"cpu":"x86_64","distro":{"id":"resolute","libc":{"lib":"glibc","version":"2.43"},"name":"Ubuntu","version":"26.04"},"implementation":{"name":"CPython","version":"3.12.16"},"installer":{"name":"hatch","version":"1.18.2"},"openssl_version":"OpenSSL 3.5.5 27 Jan 2026","python":"3.12.16","system":{"name":"Linux","release":"7.0.0-1019-azure"}} HTTPX2/2.16.0

Security for sayer 0.8.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.8.2 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page