Interfacy
Interfacy is a CLI framework that turns Python functions, classes, and class instances into command-line interfaces. It derives the CLI from signatures, type annotations, and docstrings instead of making you define it twice.
Features
- Generate CLIs from functions, classes, class methods, and class instances.
- Nested subcommands and manual command groups with aliases.
- Type-driven parsing from annotations, with support for custom parsers.
- Model expansion for dataclasses, Pydantic models, and plain classes.
--helptext generated from docstrings.- Highly customizable help output with multiple layouts, color themes, and configurable ordering.
- Stdin piping support with configurable routing to parameters.
- Optional tab completion via
argcomplete.
Installation
From PyPI
pip install interfacy
uv add interfacy
From source
pip install git+https://github.com/zigai/interfacy.git
uv add "git+https://github.com/zigai/interfacy.git"
Quick Start
from interfacy import Interfacy
def greet(name: str, times: int = 1) -> None:
"""Print a greeting."""
print(" ".join([f"Hello, {name}!" for _ in range(times)]))
if __name__ == "__main__":
Interfacy().run(greet)
$ python app.py Ada
Hello, Ada!
$ python app.py Ada --times 2
Hello, Ada! Hello, Ada!
Agent Skill
The official AI agent skill can be installed from this repo.
npx skills add https://github.com/zigai/interfacy/tree/master/interfacy/.agents/skills/interfacy
or
uvx library-skills
Class-Based Commands
Classes become command namespaces. __init__ parameters live at the command level and public methods become subcommands.
from interfacy import Interfacy
class Calculator:
def __init__(self, precision: int = 2) -> None:
self.precision = precision
def add(self, a: float, b: float) -> float:
return round(a + b, self.precision)
def mul(self, a: float, b: float) -> float:
return round(a * b, self.precision)
if __name__ == "__main__":
Interfacy(print_result=True).run(Calculator)
$ python app.py --precision 3 add 1.2345 2.3445
3.579
Structured Parameters
Dataclasses, Pydantic models, and plain classes with typed __init__ parameters can be expanded into nested flags and reconstructed before execution.
from dataclasses import dataclass
from interfacy import Interfacy
@dataclass
class Address:
city: str
postal_code: int
@dataclass
class User:
name: str
age: int
address: Address | None = None
def greet(user: User) -> str:
return f"Hello {user.name}, age {user.age}"
if __name__ == "__main__":
Interfacy(print_result=True).run(greet)
$ python app.py --user.name Ada --user.age 32
Hello Ada, age 32
Manual Groups
Use CommandGroup when your command tree is not naturally rooted in one callable:
from interfacy import CommandGroup, Interfacy
def clone(url: str) -> str:
return f"clone:{url}"
class Releases:
def cut(self, version: str) -> str:
return f"cut:{version}"
ops = CommandGroup("ops", description="Operational commands")
ops.add_command(clone)
ops.add_command(Releases)
if __name__ == "__main__":
Interfacy(print_result=True).run(ops)
Interfacy CLI Entrypoint
Interfacy also ships a CLI that can run an existing function, class, or class instance directly from a module or Python file:
$ interfacy app.py:greet Ada
$ interfacy app.py:greet --help
$ interfacy package.cli:Calculator add 1 2
The entrypoint supports configuration via TOML, loaded from ~/.config/interfacy/config.toml or INTERFACY_CONFIG.
usage: interfacy [--help] [--version] [--config-paths] [TARGET] ...
Interfacy is a framework for building CLIs from Python callables.
positional arguments:
[TARGET] Python file or module with a function/class/instance symbol
(e.g. main.py:main, pkg.cli:App, pkg.cli:service).
... Arguments passed through to the target command.
options:
--help Show this help message and exit
--version show version and exit.
--config-paths print config file search paths and exit.
Use 'interfacy TARGET --help' to display the help text for the target.
License
Release files for interfacy 0.8.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| interfacy-0.8.1.tar.gz | 140.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| interfacy-0.8.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 313.2 kB
Release files / interfacy-0.8.1.tar.gz
| Download URL | interfacy-0.8.1.tar.gz |
|---|---|
| Size | 140.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7fe638bc4ba3b0bbbb42586d41678fe85cd9fe414eee30d924dee478a69302d8
|
|
BLAKE2b-256 checksum How to use checksums |
046675064a489f75a1e29ba3cd436434aacbd758531094c3eaf0a88d2132b3e7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / interfacy-0.8.1-py3-none-any.whl
| Download URL | interfacy-0.8.1-py3-none-any.whl |
|---|---|
| Size | 172.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
99db255f42aff7143c3eedc6620c89cd4679d713b542bb9dfac06df058f63080
|
|
BLAKE2b-256 checksum How to use checksums |
56ae70f7c2dfaeec87e64341d37d33702e47ef1944b5f38e5ad52b53a9316593
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|