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.1

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.1
File Size Uploaded Provenance Actions
sayer-0.8.1.tar.gz 69.7 kB Without provenance Details for sayer-0.8.1.tar.gz

Built distribution (wheel)

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

Total release size: 155.0 kB

Release files / sayer-0.8.1.tar.gz

Download URL sayer-0.8.1.tar.gz
Size 69.7 kB
Tags Source
SHA-256 checksum
How to use checksums
77c6c822f5cf9559f6978c394eaf4bea42eebb20d44691412a5a264ce4e28813
BLAKE2b-256 checksum
How to use checksums
e3781e5ce98759948450bfb69e81c7abfc9a85e31879cc010d9aa3a189f021d6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.18.1 {"ci":true,"cpu":"x86_64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Ubuntu","version":"24.04"},"implementation":{"name":"CPython","version":"3.12.15"},"installer":{"name":"hatch","version":"1.18.1"},"openssl_version":"OpenSSL 3.0.13 30 Jan 2024","python":"3.12.15","system":{"name":"Linux","release":"7.0.0-1017-azure"}} HTTPX2/2.16.0

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

Download URL sayer-0.8.1-py3-none-any.whl
Size 85.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
06b661063e5a68b12c6e166d86f8fe75cfc1d512ca21bb7d84e3153ef195d960
BLAKE2b-256 checksum
How to use checksums
42f0b60fc261eb90b38480a2e9d915fe57c0c8067fde50bd41dfeb6d738dd6aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.18.1 {"ci":true,"cpu":"x86_64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Ubuntu","version":"24.04"},"implementation":{"name":"CPython","version":"3.12.15"},"installer":{"name":"hatch","version":"1.18.1"},"openssl_version":"OpenSSL 3.0.13 30 Jan 2024","python":"3.12.15","system":{"name":"Linux","release":"7.0.0-1017-azure"}} HTTPX2/2.16.0

Security for sayer 0.8.1

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.1 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