Easily turn functions into command line utilities
Project description
pysimplecli
Want to turn your script into a command line utility, but don't want the overhead of argparse?
You've come to the right place!
Simply import and wrap whatever function you'd like to expose. That's it!
Function variables are turned into CLI parameters, complete with input validation and help text generated from inline comments.
Install from PyPI
pip install pysimplecli
Quick Start
To convert a Python function into a CLI command, simply use the wrap
decorator from the simplecli
module. Here is a simple example:
import simplecli
@simplecli.wrap
def main(
name: str, # Person to greet
) -> None:
print(f"Hello, {name}!")
$ python3 myprogram.py --name="Dade Murphy"
Hello, Dade Murphy!
That's it!
Features
No configuration to worry about
Everything Just Works™ out of the box.
Autogenerated help
Parameters show up automatically and comments make them more friendly.
$ python3 hello.py --help
Usage:
hello.py [name]
Options:
--name Person to greet
--help Display hello.py version
Unicode support
$ python3 hello.py --name="Donatello 🐢"
Hello, Donatello 🐢!
Cross-platform
Tested on Windows/Linux/Mac with Python >= 3.9.
Required parameters are also positional
Want to pass positional instead of named parameters? All required parameters are available in top-down order.
$ python3 hello.py "El Duderino"
Hello, El Duderino!
Autogenerated version parameter
If you have the dunder variable __version__
set, you get a --version
parameter.
import simplecli
___version___ = "1.2.3"
@simplecli.wrap
def main(
name: str, # Person to greet
) -> None:
print(f"Hello, {name}!")
$ python3 hello.py --version
hello.py version 1.2.3
Automatic docstring to help description
Want to add some detail to your help output? Just make a docstring in the function that's being wrapped.
import simplecli
__version__ = "1.2.3"
@simplecli.wrap
def main(
name: str, # Person to greet
) -> None:
"""
This is a utility that greets whoever engages it. It's a simple example
of how to use the `simplecli` utility module. Give it a try!
"""
print(f"Hello, {name}!")
$ python3 hello.py --help
Usage:
hello.py [name]
Description:
This is a utility that greets whoever engages it. It's a simple example
of how to use the `simplecli` utility module. Give it a try!
Options:
--name Person to greet
--help Show this message
--version Display hello.py version
Gotchas
"Required" may be a bit confusing
A parameter becomes "required" if it is an int
, float
or str
and does not have a default.
bool
arguments cannot be required as there are only two possible states. Instead, they are False
by default and become True
when passed as a flag.
Complex variables are not supported
Only simple variable types (bool
, float
, int
, str
) are currently supported as well as list
and set
of those types. Mapping types are beyond the scope of this utility.
Only one @wrap
allowed per file
With more than one decorator, it's impossible to tell which function you'd like to wrap. Because of this, we enforce a single @wrap
per file. Importing modules using pysimplecli
is supported, as is calling said wrapped functions.
Truth table for boolean parameters
Parameter Default | Without Argument | With Argument |
---|---|---|
True |
True |
False |
False |
False |
True |
no default | False |
True |
How It Works
The wrap
decorator takes the annotated parameters of a given function and maps them to corresponding command-line arguments. It relies heavily on Python's inspect
and tokenize
modules to gather parameters, parse comments for parameter descriptions, determine default functionality, etc... In fact, a core part of this module is a are heavily extended inspect.Parameter
objects.
Why not just use argparse
?
argparse
is great for advanced input control. Unfortunately, that level of control means considerably more overhead for simple utilities. To be clear, this is not intended to replace argparse
. simplecli
is meant to easily expose a python function as a script.
(I've also felt conflicted about dunder names being used openly in if __name__ == "__main__":
)
Here's an example of an argparse
solution
import argparse
import sys
__version__ = "1.2.3"
def add(a: int = 5, b: int = 10) -> None:
print(a + b)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--a", default=5, required=True, type=int,
help="First integer to add")
parser.add_argument("--b", default=10, required=True, type=int,
help="Second integer to add")
parser.add_argument("--version", action="version",
version=f"{sys.argv[0]} version {__version__}")
args = parser.parse_args()
add(args.a, args.b)
Here's the same example, but with simplecli
from simplecli import wrap
__version__ = "1.2.3"
@wrap
def add(
a: int = 5, # First integer to add
b: int = 10, # Second integer to add
) -> None:
print(a + b)
Contributing
Feel free to open an issue and create a pull request!
License
pysimplecli © 2024 by Clif Bratcher is licensed under CC BY 4.0
Project details
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
File details
Details for the file pysimplecli-1.0.6.tar.gz
.
File metadata
- Download URL: pysimplecli-1.0.6.tar.gz
- Upload date:
- Size: 8.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.3 Darwin/23.4.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1661df8d4cc9893a7ddb3cc40a756d40b81744e3c74cad7ef0bbd5a4663de4d2 |
|
MD5 | 9ca99798bae00828145501b91e525a50 |
|
BLAKE2b-256 | 11536bdb6a0621e0102c2066da1b7d0cb2658e614235803d5eec5ca52325795d |
File details
Details for the file pysimplecli-1.0.6-py3-none-any.whl
.
File metadata
- Download URL: pysimplecli-1.0.6-py3-none-any.whl
- Upload date:
- Size: 8.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.3 Darwin/23.4.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | b8c70c6438601a04ae63728bd8fa8cd4ac9cd796982931844ac5b46014ea5363 |
|
MD5 | 92823412d426830504bdaccb3640b849 |
|
BLAKE2b-256 | a1739eb5121cb17e3b6cd3db2c484b01b3d0f74cc1ebd076bd28c07393590c86 |