A foundational toolkit of pure Python utilities and helpers.
Project description
soniclue-basekit
A foundational toolkit of pure Python utilities and helpers.
Installation
pip install soniclue-basekit
# or
uv add soniclue-basekit
Modules
ExecTimer
Times a block of code using wall-clock elapsed time. Works as a context manager or function decorator. Optionally logs elapsed time and fires a post-action callback.
from soniclue_basekit import ExecTimer
# Context manager
with ExecTimer("loading data") as t:
load_data()
print(t.interval) # seconds elapsed
# Decorator
@ExecTimer("train step")
def train():
...
ExecTimeProfiler
Profiles execution time across named stages within a single thread. Supports nested stages, inner-time exclusion, and summary statistics (mean, std dev).
from soniclue_basekit import ExecTimeProfiler
profiler = ExecTimeProfiler()
with profiler.stage("preprocess"):
...
with profiler.stage("inference"):
...
profiler.print_report()
Attempter
Wraps a callable and re-invokes it on failure according to a pluggable retry strategy. Raise NoMoreAttempt inside the callable to abort retrying immediately.
from soniclue_basekit import Attempter, ExponentialBackoff, NoMoreAttempt
def fetch():
resp = requests.get(url)
if resp.status_code == 404:
raise NoMoreAttempt() # no point retrying
resp.raise_for_status()
return resp.json()
result = Attempter(fetch).execute(ExponentialBackoff(base=1.0, multiplier=2.0), max_attempts=5)
Retry strategies:
| Class | Behaviour |
|---|---|
ConstantPause(interval) |
Fixed wait between retries |
RandomPause(low, high) |
Uniform random wait in [low, high] |
ExponentialBackoff(base, multiplier, jitter) |
base × multiplierᵃᵗᵗᵉᵐᵖᵗ + optional random jitter |
LockProtector
Wraps an object with a threading.Lock. Supports enforcing lock acquisition order across protectors and optional profiling of contention.
from soniclue_basekit import LockProtector
state = LockProtector({"count": 0})
with state.acquire() as s:
s["count"] += 1
DaemonThread / TerminableThread
Thread base classes with graceful shutdown support. TerminableThread exposes is_terminating() / set_terminating(). DaemonThread adds periodic-task scaffolding and optional OS-level thread naming (Linux).
from soniclue_basekit import DaemonThread
class Poller(DaemonThread):
def _run_once(self):
check_queue()
poller = Poller(interval_sec=5, name="poller")
poller.start()
...
poller.set_terminating()
poller.join()
ScriptRunner
Runs shell scripts (written as Python strings) in a subprocess with optional timeout, stdout/stderr capture, and streaming line callbacks.
from soniclue_basekit import ScriptRunner
runner = ScriptRunner("echo hello && echo world")
runner.run()
CliFormatter
Fluent builder for CLI argument strings passed to subprocess. Handles shell-quoting, key prefixes, and multi-value flags.
from soniclue_basekit import CliFormatter
cmd = (
CliFormatter("ffmpeg")
.add("-i", input_path)
.add("-vf", "scale=1280:720")
.add("-y", output_path)
.build()
)
run_in_process / run_in_process_decorator
Run a callable in an isolated subprocess and return its result (or re-raise its exception) in the calling process. Useful for isolating GPU memory, avoiding fork-safety issues, or enforcing timeouts.
from soniclue_basekit import run_in_process, run_in_process_decorator
result = run_in_process(my_fn, timeout_sec=30)
@run_in_process_decorator
def heavy_job(x):
return x * 2
is_pytest_env
Returns True when running inside a pytest session — handy for guards that should only activate during tests.
from soniclue_basekit import is_pytest_env
Development
Requires uv.
Run tests
uv run pytest
Lint
uv run ruff check src tests
Format
uv run ruff format src tests
Changelog
0.1.1
- Lowered minimum Python requirement from 3.11 to 3.10 (for ROS2 project).
0.1.0
- Initial release of featured libraries.
License
Apache 2.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
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
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file soniclue_basekit-0.1.1.tar.gz.
File metadata
- Download URL: soniclue_basekit-0.1.1.tar.gz
- Upload date:
- Size: 35.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5311815428beafbc452ea3ea4d8c5e8a301658ed7856a30dfd8f1a0796c585e
|
|
| MD5 |
be62b2f528a0e16de4112f26dad92aee
|
|
| BLAKE2b-256 |
03e93a2fbde75c835c79b4f49e5e920a0df9384c0d0c3af0df7edd1ebdb5836d
|
File details
Details for the file soniclue_basekit-0.1.1-py3-none-any.whl.
File metadata
- Download URL: soniclue_basekit-0.1.1-py3-none-any.whl
- Upload date:
- Size: 25.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe6a0cade6c4a3d8dec15789595770bcc8ed3052f07f300b8332db1c42627dcd
|
|
| MD5 |
6083a450c7c301b2d7900e9ae1bb3add
|
|
| BLAKE2b-256 |
a2e937ff5352690702cc17ad430966b4a08368e297d9474d6d380583d4dc2ec5
|