Skip to main content

Documentation Status codecov PyPI version DeepSource

Description

su (Super User) tools

Per module utilities, designed to be lightweight, easy to configure, and reduce boilerplate code.

info

This package is intended to create an lower barrier for entry for logging and module level cli with sensible defaults; sutools is not intended to replace click, argparse, logging or other utility libraries. If your project requires a more flexible configuration please use the appropriate tooling.


Quick Start:

Register Functions with sutools


Using the register decorator @su.register on your functions will register it with sutools meta_handler. Stored functions are available across tools. This registry is intended to be used by logger and cli utilities.

import sutools as su

@su.register
def add(x : int, y : int):
    '''add two integers'''
    return x + y

You can also register async functions, these will be executed using asyncio.run() given a valid coroutine function

import sutools as su
import asyncio

@su.register
async def delay_add(x : int, y : int):
    '''add two integers after 1 sec'''
    await asyncio.sleep(1)
    return x + y
    

NOTE: Adding type hinting to your functions enforces types in the cli and adds positional arg class identifiers in the help docs for the command.



CLI Usage Example


"""This module does random stuff."""
import sutools as su

@su.register
def meet(name : str, greeting : str = 'hello', farewell : str = 'goodbye') -> str:
        '''meet a person'''
        output = f'\n{greeting} {name}\n{farewell} {name}'
        su.log().meeting.info(output)
        return output

su.logger() # optional

# module level function calls...

if __name__ == '__main__':
    # main code (will run even when using cli commands)...
    su.cli(desc = __doc__)
    # main code (will NOT run when using cli commands)...

NOTE: Adding type hinting to your functions enforces types in the cli and adds positional arg class identifiers in the help docs for the command.

command usage:

python module.py meet foo

output

hello foo
goodbye foo

module help output:

    usage: module [-h] {meet} ...

    This module does random stuff.

    options:
    -h, --help  show this help message and exit

    commands:
    {meet}
        meet      meet a person

command help output:

    usage: dev meet [-gr <class 'str'>] [-fa <class 'str'>] [-h] name

    meet(name: str, greeting: str = 'hello', farewell: str = 'goodbye') -> str

    positional arguments:
    name                  <class 'str'>

    options:
    -gr <class 'str'>, --greeting <class 'str'>
                            default: hello
    -fa <class 'str'>, --farewell <class 'str'>
                            default: goodbye
    -h, --help            Show this help message and exit.

CLI Using Variadic Functions

Variadic functions are compatible with sutools cli utility. When calling kwargs from the cli; key=value should be used instead of -- and -, these are reserved for default arguments.

NOTE: since input is from stdin it will always be of type <string>, sutools will not infer the data type you must infer your needed type within the function.

"""This module does random stuff."""
import sutools as su

@su.register
def variadic(*args, **kwargs):
    
    print("Positional arguments:")
    for arg in args:
        print(arg)

    print("Keyword arguments:")
    for key, value in kwargs.items():
        print(f"{key} = {value}")

    su.logger() # optional

# module level function calls...

if __name__ == '__main__':
    # main code (will run even when using cli commands)...
    su.cli(desc = __doc__)
    # main code (will NOT run when using cli commands)...

command usage:

python module.py variadic 1 2 3 foo=1 bar=2

output:

Positional arguments:
1
2
3
Keyword arguments:
foo = 1
bar = 2

Logger Usage Examples


accessing defined loggers is done with a log() helper function. Note the use of su.log() in the below functions to access a specified logger before defining the log level and message.


using registered function names

import sutools as su

@su.register
def add(x : int, y : int):
    '''add two integers'''
    su.log().add.info(f'{x} + {y} = {x+y}')
    return x + y

@su.register
def minus(x : int, y : int):
    '''subtract two integers'''
    su.log().minus.info(f'{x} - {y} = {x-y}')
    return x - y

su.logger()

# module level function calls
add(1,2)
minus(1,2)

if __name__ == '__main__':
    # main code (will run even when using cli commands)...
    su.cli() # optional
    # main code (will NOT run when using cli commands)...

log output

16:16:34, 961 add INFO 1 + 2 = 3
16:16:34, 961 minus INFO 1 - 2 = -1

using custom logger names

import sutools as su

@su.register
def add(x : int, y : int):
    '''add two integers'''
    su.log().logger1.info(f'{x} + {y} = {x+y}')
    return x + y

@su.register
def minus(x : int, y : int):
    '''subtract two integers'''
    su.log().logger2.info(f'{x} - {y} = {x-y}')
    return x - y

su.logger(loggers=['logger1','logger2'])

# module level function calls
add(1,2)
minus(1,2)

if __name__ == '__main__':
    # main code (will run even when using cli commands)...
    su.cli() # optional
    # main code (will NOT run when using cli commands)...

log output

16:16:34, 961 logger1 INFO 1 + 2 = 3
16:16:34, 961 logger2 INFO 1 - 2 = -1


Benchy Usage Example


The benchy decorator is designed to collect performance timing and call info for selected functions. This can be used in combination with @su.register, the decorators are order independent.

import sutools as su

@su.benchy
@su.register
def add(x : int, y : int):
    '''add two integers'''
    return x + y

@su.register
@su.benchy
def subtract(x : int, y : int):
    '''subtract two integers'''
    return x - y

@su.benchy
@su.register
def calc(x : int, y : int, atype : str = '+') -> int:
    '''calculates a thing'''
    if atype == '+':
        res = x + y
    elif atype == '-':
        res = x - y
    return res

add(1,2)
add(2,2)
subtract(1,2)
calc(2,3, atype='-')

After the functions have been executed, the benchmark report can be accessed with su.benchy.report.

# print the benchmark report
print(su.benchy.report)

Example output

{'add': [{'args': [{'type': 'int', 'value': 1}, {'type': 'int', 'value': 2}],
        'benchmark': 0.00015466799959540367,
        'kwargs': None,
        'result': {'type': 'int', 'value': 3}},
        {'args': [{'type': 'int', 'value': 2}, {'type': 'int', 'value': 2}],
        'benchmark': 6.068096263334155e-05,
        'kwargs': None,
        'result': {'type': 'int', 'value': 4}}],
'calc': [{'args': [{'type': 'int', 'value': 2}, {'type': 'int', 'value': 3}],
        'benchmark': 4.855601582676172e-05,
        'kwargs': {'atype': {'length': 1, 'type': 'str'}},
        'result': {'type': 'int', 'value': 5}}],
'subtract': [{'args': [{'type': 'int', 'value': 1}, {'type': 'int', 'value': 2}],
        'benchmark': 5.205394700169563e-05,
        'kwargs': None,
        'result': {'type': 'int', 'value': -1}}]}

The output of the benchmark report will adhere to the following format: function > call records. Call records consist of {args, kwargs, result, benchmark} there will be a record for each call of a given function.

NOTE: given an iterable for arg, kwarg, or result the object will be summarized in terms of vector length.

{'function_name': [{'args': [{'type': 'arg_type', 'value': int}]
                    'benchmark': float,
                    'kwargs': {'kwarg_name': {'type': 'arg_type', 'length': int, }}
                    'result': {'type': 'arg_type', 'value': float}}]}

Metadata

Release files for sutools 0.2.4

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

Source distribution (sdist)

Source distribution for sutools 0.2.4
File Size Uploaded
sutools-0.2.4.tar.gz 19.4 kB Details

Built distribution (wheel)

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

Total release size: 31.6 kB

Release files / sutools-0.2.4.tar.gz

Download URL sutools-0.2.4.tar.gz
Size 19.4 kB
Tags Source
SHA-256 checksum
How to use checksums
794b462794102871c371d0239cd5b77b70888ae2d418d8cf8a3e67c2180666ec
BLAKE2b-256 checksum
How to use checksums
c3e3a95a1f5943d1d3974fa482de0309ae26600aa09afedec404d58c3d9730be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.11.4

Release files / sutools-0.2.4-py3-none-any.whl

Download URL sutools-0.2.4-py3-none-any.whl
Size 12.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
925d88d8aa7f6c81ff96d1e0d945278f8c8f7d426eefca0d308c2fb579406889
BLAKE2b-256 checksum
How to use checksums
591d2c9af19715ef589b00865d1986e9bab3b0d283a946fb068c98138cafa548
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.11.4

Release history Release notifications | RSS feed

This release

0.2.4 This release

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

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