A fast way to turn your python function into a script
npx @tessl/cli install tessl/pypi-fastscript@0.1.0A fast way to turn your python function into a script. fastscript provides a lightweight Python library that simplifies the creation of command-line interfaces from Python functions, acting as a streamlined wrapper around argparse with minimal boilerplate code.
pip install fastscriptfrom fastscript import Param, call_parse, anno_parser, str2boolCommon wildcard import pattern:
from fastscript import *from fastscript import *
@call_parse
def main(
msg: Param("The message", str),
upper: Param("Convert to uppercase?", str2bool) = False
):
"""A simple CLI script that prints a message."""
print(msg.upper() if upper else msg)When you run this script:
$ python script.py "Hello World"
Hello World
$ python script.py "Hello World" --upper true
HELLO WORLD
$ python script.py --help
usage: script.py [-h] [--upper UPPER] msg
A simple CLI script that prints a message.
positional arguments:
msg The message
optional arguments:
-h, --help show this help message and exit
--upper UPPER Convert to uppercase?fastscript uses function annotations and decorators to automatically generate CLI interfaces:
The library automatically determines argument types based on function defaults:
Creates a command-line interface from a Python function using function annotations.
def call_parse(func):
"""
Decorator to create a simple CLI from func using anno_parser.
Parameters:
- func: Function to convert to CLI script
Returns:
Decorated function that can be called programmatically or from CLI
Behavior:
- Automatically calls the function with parsed CLI arguments when script is run as __main__
- Function remains callable programmatically with direct arguments
- Uses function docstring as program description
- Determines argument types from Param annotations and defaults
"""Usage example:
@call_parse
def process_file(
filename: Param("Input file to process", str),
verbose: Param("Enable verbose output", str2bool) = False,
output: Param("Output file", str) = "result.txt"
):
"""Process a file with optional verbose output."""
# Function implementation
passDefines the behavior and help text for function parameters in CLI scripts.
class Param:
"""
A parameter in a function used in anno_parser or call_parse.
Parameters:
- help: str, optional - Help text for the parameter
- type: type, optional - Parameter type conversion function
- opt: bool, optional - Whether parameter is optional (default: True)
- action: str, optional - argparse action type
- nargs: str/int, optional - Number of arguments ('*', '+', '?', or int)
- const: any, optional - Constant value for store_const action
- choices: list, optional - List of valid choices for the parameter
- required: bool, optional - Whether parameter is required (overrides opt)
Properties:
- pre: Returns '--' if optional parameter, '' if positional
- kwargs: Returns dict of non-None attributes excluding 'opt'
"""Usage example:
def process_data(
input_file: Param("Input data file", str),
format: Param("Output format", str, choices=["json", "csv", "xml"]) = "json",
count: Param("Number of items to process", int, nargs='?') = 10,
verbose: Param("Enable verbose mode", action="store_true") = False
):
passCreates an ArgumentParser from function annotations for advanced CLI customization.
def anno_parser(func):
"""
Look at params (annotated with Param) in func and return an ArgumentParser.
Parameters:
- func: Function with Param annotations to analyze
Returns:
argparse.ArgumentParser configured from function signature
Behavior:
- Examines function signature and Param annotations
- Creates ArgumentParser with function docstring as description
- Automatically determines positional vs optional arguments from defaults
- Configures argument types, help text, and validation from Param objects
"""Usage example:
def my_function(
name: Param("Your name", str),
age: Param("Your age", int) = 25
):
"""A sample function."""
pass
# Get the parser for manual use
parser = anno_parser(my_function)
args = parser.parse_args(['John', '--age', '30'])
my_function(**args.__dict__)Utility function for converting string values to boolean, commonly used with CLI arguments.
def str2bool(v):
"""
Convert string values to boolean for CLI argument parsing.
Parameters:
- v: bool or str - Value to convert
Returns:
bool - Converted boolean value
Behavior:
- Returns input unchanged if already boolean
- Converts 'yes', 'true', 't', 'y', '1' (case-insensitive) to True
- Converts 'no', 'false', 'f', 'n', '0' (case-insensitive) to False
- Raises argparse.ArgumentTypeError for invalid string values
"""Usage example:
@call_parse
def toggle_feature(
enable: Param("Enable the feature", str2bool) = False
):
"""Toggle a feature on or off."""
if enable:
print("Feature enabled")
else:
print("Feature disabled")
# Command line usage:
# python script.py --enable yes
# python script.py --enable true
# python script.py --enable 1fastscript supports setuptools console_scripts for system-wide command installation:
In setup.py or setup.cfg:
entry_points = {
'console_scripts': [
'my-script=mypackage.module:main',
],
}Or in settings.ini (fastscript style):
console_scripts = my-script=mypackage.module:main# mypackage/cli.py
from fastscript import *
@call_parse
def main(
input_file: Param("Input file to process", str),
output: Param("Output directory", str) = "./output",
verbose: Param("Enable verbose logging", str2bool) = False
):
"""Process input files and generate output."""
# Implementation
pass
# Entry point for console script
if __name__ == "__main__":
main()After installation with pip install -e ., the script becomes available system-wide:
$ my-script input.txt --output /tmp/results --verbose truefastscript includes a built-in console script for testing:
# Available after installing fastscript
$ test_fastscript "Hello World" --upper true
HELLO WORLDThis script is defined as test_fastscript=fastscript.test_cli:main and provides a working example of console script integration.
@call_parse
def advanced_script(
files: Param("Input files", str, nargs='+'),
mode: Param("Processing mode", str, choices=['fast', 'thorough', 'debug']) = 'fast',
workers: Param("Number of worker threads", int) = 4,
config: Param("Configuration file", str, required=False) = None,
dry_run: Param("Perform dry run without changes", action='store_true') = False
):
"""Advanced script with multiple parameter types."""
print(f"Processing {len(files)} files in {mode} mode")
print(f"Using {workers} workers")
if config:
print(f"Config file: {config}")
if dry_run:
print("DRY RUN MODE - no changes will be made")def my_function(name: Param("Name", str), count: Param("Count", int) = 1):
"""Example function."""
for i in range(count):
print(f"Hello, {name}!")
# Create parser manually for custom argument handling
parser = anno_parser(my_function)
parser.add_argument('--version', action='version', version='1.0.0')
# Parse arguments manually
args = parser.parse_args()
my_function(**args.__dict__)