("yoots"): utilities I've missed in the Python standard library
- Install
- Use
utz.process
:subprocess
wrappers; shell out to commands, parse outpututz.collections
: Collection/list helpersutz.cd
: "change directory" contextmanagerutz.ctxs
: composecontextmanager
sutz.fn
: decorator/function utilitiesutz.plot
: Plotly helpersutz.setup
:setup.py
helperutz.test
:dataclass
test cases,raises
helperutz.docker
,utz.tmpdir
, etc.
pip install utz
0 dependencies, but several "extras" available.
I usually do this at the top of Jupyter notebooks:
from utz import *
This imports most standard library modules/functions (via stdlb
), as well as the utz.*
members below.
Some specific modules, in rough order of how often I use them:
utz.process
: subprocess
wrappers; shell out to commands, parse output
from utz.process import *
# Run a command
run('git', 'commit', '-m', 'message') # Commit staged changes
# Return `list[str]` of stdout lines
lines('git', 'log', '-n5', '--format=%h') # Last 5 commit SHAs
# Verify exactly one line of stdout, return it
line('git', 'log', '-1', '--format=%h') # Current HEAD commit SHA
# Return stdout as a single string
output('git', 'log', '-1', '--format=%B') # Current HEAD commit message
# Check whether a command succeeds, suppress output
check('git', 'diff', '--exit-code', '--quiet') # `True` iff there are no uncommitted changes
err("This will be output to stderr")
See also: test_process.py
.
utz.collections
: Collection/list helpers
from utz.collections import *
# Verify a collection has one element, return it
singleton(["aaa"]) # "aaa"
singleton(["aaa", "bbb"]) # error
See also: test_collections.py
.
utz.cd
: "change directory" contextmanager
from utz import cd
with cd('..'): # change to parent dir
...
utz.ctxs
: compose contextmanager
s
from utz import *
with ctxs(NamedTemporaryFile(), NamedTemporaryFile()) as (f1, f2):
...
See also: test_context.py
.
utz.fn
: decorator/function utilities
from utz import decos
from click import option
common_opts = decos(
option('-n', type=int),
option('-v', is_flag=True),
)
@common_opts
def subcmd1(n: int, v: bool):
...
@common_opts
def subcmd2(n: int, v: bool):
...
from utz.fn import call
def fn1(a, b):
...
def fn2(a, c):
...
kwargs = dict(a=11, b='22', c=33)
call(fn1, kwargs) # only pass {a, b}
call(fn2, kwargs) # only pass {a, c}
Helpers for Plotly transformations I make frequently, e.g.:
from utz import plot
import plotly.express as px
fig = px.bar(x=[1, 2, 3], y=[4, 5, 6])
plot(
fig,
name='my-plot', # Filename stem. will save my-plot.png, my-plot.json, optional my-plot.html
title=['Some Title', 'Some subtitle'], # Plot title, followed by "subtitle" line(s) (smaller font, just below)
bg='white', xgrid='#ccc', # white background, grey x-gridlines
hoverx=True, # show x-values on hover
x="X-axis title", # x-axis title or configs
y=dict(title="Y-axis title", zerolines=True), # y-axis title or configs
# ...
)
Example usages: hudcostreets/nj-crashes, ryan-williams/arrayloader-benchmarks.
utz.setup
: setup.py
helper
utz/setup.py
provides defaults for various setuptools.setup()
params:
name
: use parent directory nameversion
: parse from git tag (otherwise fromgit describe --tags
)install_requires
: readrequirements.txt
author_{name,email}
: infer from last commitlong_description
: parseREADME.md
(and setlong_description_content_type
)description
: parse first<p>
under opening<h1>
fromREADME.md
license
: parse fromLICENSE
file (MIT and Apache v2 supported)
For an example, see gsmo==0.0.1
(and corresponding release).
This library also "self-hosts" using utz.setup
; see pyproject.toml:
[build-system]
requires = ["setuptools", "utz[setup]==0.4.2", "wheel"]
build-backend = "setuptools.build_meta"
and setup.py:
from utz.setup import setup
extras_require = {
# …
}
# Various fields auto-populated from git, README.md, requirements.txt, …
setup(
name="utz",
version="0.8.0",
extras_require=extras_require,
url="https://github.com/runsascoded/utz",
python_requires=">=3.10",
)
The setup
helper can be installed via a pip "extra":
pip install utz[setup]
utz.test
: dataclass
test cases, raises
helper
utz.parametrize
: pytest.mark.parametrize
wrapper, accepts dataclass
instances
from utz import parametrize
from dataclasses import dataclass
def fn(f: float, fmt: str) -> str:
"""Example function, to be tested with ``Case``s below."""
return f"{f:{fmt}}"
@dataclass
class case:
"""Container for a test-case; float, format, and expected output."""
f: float
fmt: str
expected: str
@property
def id(self):
return f"fmt-{self.f}-{self.fmt}"
@parametrize(
case(1.23, "0.1f", "1.2"),
case(123.456, "0.1e", "1.2e+02"),
case(-123.456, ".0f", "-123"),
)
def test_fn(f, fmt, expected):
"""Example test, "paraametrized" by several ``Cases``s."""
assert fn(f, fmt) == expected
Example above is from test_parametrize.py
, parametrize
is adapted from TileDB-SOMA (example use).
utz.docker
, utz.tmpdir
, etc.
Misc other modules:
- o:
dict
wrapper exposing keys as attrs (e.g.:o({'a':1}).a == 1
) - docker: DSL for programmatically creating Dockerfiles (and building images from them)
- ssh: SSH tunnel wrapped in a context manager
- time:
now()
/today()
helpers with convenient / no-nonsense ISO string serialization and UTC bias - bases:
int
⟺str
codecs with improvements over standard base64 et al. - tmpdir: make temporary directories with a specific basename
- escape: escaping split/join helpers
- backoff: exponential-backoff utility
- git: Git helpers, wrappers around GitPython
- pnds: pandas imports and helpers