Currently, is version 0.4.14.
supports Python 3.11 and above.
It has no dependencies outside of the Python standard library.
Write Python at hacker-level speeds.
(pronounced exactly like the word suitcase)
All files in this repository are licensed under the Apache License 2.0, including source code, examples, documentation, tests, site content code, and everything else.
pip install suitkaise
Explicitly supported Python versions: 3.11 and above
Currently, is version 0.4.14.
contains the following modules:
cucumber : serialization enginecircuits : flow control with the Circuit and BreakingCircuit classesprocessing : upgraded multiprocessing with easy shared statepaths : upgraded path class and utilities for path opssk : modifiers for functions and class methodstiming : timer class with deep statistics usable in many waysAll documentation is available for download.
CLI (downloads to project root, cwd must be within project root):
suitkaise docs
Python:
from suitkaise import docs
# download to project root
docs .download()
# download to a specific path within your project
docs .download("path/within/project")
To place docs outside your project root, use the Permission context manager.
from suitkaise import docs
with docs .Permission():
docs .download("/Users/joe/Documents")
You can also view more at suitkaise.info.
from suitkaise .processing import Share , Pool , Skprocess
import logging
share = Share( )
share.counter = 0
share.results = []
share.log = logging.getLogger("worker")
class Worker(Skprocess ):
def __init__(self, share, item):
self.share = share
self.item = item
def __run__ (self):
result = self.item * 2
self.share.results.append(result)
self.share.counter += 1
self.share.log.info(f"done: {result}")
pool = Pool( workers=4)
pool.star() .map (Worker, [(share, x) for x in range(20)])
print(share.counter) # 20
print(len(share.results)) # 20
print(share.log.handlers) # still works
from suitkaise import cucumber
data = cucumber .serialize (any_object)
restored = cucumber .deserialize (data)
from suitkaise .timing import timethis
@timethis()
def my_function():
do_work()
my_function()
print(my_function.timer .mean )
from suitkaise import sk
@sk
def fetch(url):
return requests.get(url).json()
data = fetch.retry (3).timeout (5.0)("https://api.example.com")
from suitkaise .paths import Skpath
path = Skpath( "data/file.txt")
print(path.rp ) # "data/file.txt" — same on every machine, every OS
from suitkaise import Circuit
circuit = Circuit( num_shorts_to_trip=5, sleep_time_after_trip=1.0)
for request in requests:
try:
process(request)
except ServiceError:
circuit .short()
For more, see the full documentation at suitkaise.info or download the docs with suitkaise docs in your terminal after installation.
Apache License 2.0
Copyright 2025-2026 Casey Eddings
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License.
"Derivative Works" shall mean any work that is based on (or derived
from) the Work.
"Contribution" shall mean any work of authorship intentionally
submitted to the Licensor for inclusion in the Work.
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License.
3. Grant of Patent License.
4. Redistribution.
5. Submission of Contributions.
6. Trademarks.
7. Disclaimer of Warranty. THE WORK IS PROVIDED ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND.
8. Limitation of Liability.
9. Accepting Warranty or Additional Liability.
END OF TERMS AND CONDITIONS
Copyright 2025-2026 Casey Eddings
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Changelog is maintained from version 0.3.0 forward.
Share counter-registry manager locks now use bounded acquisition with recovery/retry, preventing worker hangs on stale manager lock proxies under multiprocessing spawn workloads.Skprocess IPC proxy cleanup is now best-effort during object teardown to reduce intermittent Bad file descriptor warnings from multiprocessing connection finalizers.Share manager counter retry now recovers stale manager lock handles that surface as TypeError: 'NoneType' object cannot be interpreted as an integer in worker write paths.cucumber handler detection in Share so handler-backed objects (like sqlite3.Connection) resolve to reconnectors instead of being incorrectly proxied.User-defined vs user-defined).Share .__serialize__ now caches live coordinator-state bytes so repeated Pool payload serialization does not repickle manager proxies on every item (spawn-stability regression guard).share.lst = share.lst + [...], share.s = share.s | {...}, share.d = share.d | {...}) to preserve regular-Python ergonomics under concurrency.Share .__deserialize__ now caches live coordinator-bound Share instances per worker process, preventing repeated manager-proxy reconstruction for every mapped task item.Share primitive assignments now behave consistently in multiprocessing for plain Python types (int, float, bool, str, bytes, tuple, frozenset, complex), including atomic augmented operations (+=, -=, *=, etc.).Share snapshot restores in client mode from overwriting active coordinator state.logging.Logger proxy deadlocks in shared objects by treating logger handlers as non-proxied.cucumber deserializer cleanup guard for reconstruction path underflow (pop from empty list).Share write paths that could fail with OSError: handle is closed in long-running Pool .star().map(...) workers.Sktimer is now fork-safe in subprocess workers.Circuit and BreakingCircuit now serialize without carrying live threading.RLock internals._Coordinator.stop() skipped SharedMemory cleanup when called on an already-stopped coordinator.Share ._META_CACHE used a plain dict, preventing garbage collection. Changed to weakref.WeakKeyDictionary.Sktimer ._sessions grew unboundedly as threads were created and destroyed.Pool worker multiprocessing.Queue resources were not cleaned up after worker timeout/termination._AtomicCounterRegistry.remove_object() only unlinked SharedMemory segments for the owning process._Coordinator.destroy() / __del__ split for restartable vs. permanent shutdown.cucumber .serialize() and cucumber .deserialize() replaced module-level singletons with per-thread instances via threading.local().TemporaryFileHandler no longer crashes on _TemporaryFileCloser objects.Sktimer .percentile(), get_time(), get_statistics() returned None through Share proxy.TimeThis recorded partial measurements when exceptions were raised.@sk modifier methods bypassed outer decorators like @timethis .Skpath comparison operators (<, >, <=, >=) now work correctly.None for method calls on plain user classes (no @sk ).@sk class .asynced() non-blocking methods are now uniformly awaitable.cucumber deserializer guard for missing placeholder in registry.list, set, dict assigned to Share are now proxied._ObjectProxy: __len__, __iter__, __contains__, __bool__, __getitem__, __setitem__, __delitem__, __str__.Sktimer blocks timing methods when used through Share . Use add_time(elapsed) instead.Circuit is now disallowed in Share . Use BreakingCircuit instead.BreakingCircuit short() and trip() skip sleep when called through Share .Processing:
Pool .unordered_map() — returns a list in completion order.Skprocess .run() now supports .timeout() , .background() , and .asynced() modifiers.processing .Pipe for inter-process communication.@autoreconnect decorator to automatically reconnect resources after deserialization.Cucumber:
Reconnector class with consistent .reconnect() API.cucumber .reconnect_all (obj, **kwargs) for recursive reconnection.cucumber , circuits , processing , paths , sk , timing ..pyi) for IDE autocompletion.py.typed marker for PEP 561 compliance.suitkaise CLI entrypoint with version, info, modules, and docs commands.Run suitkaise from the terminal after installation. If no command is provided, the help menu is printed.
suitkaise --versionPrint the current version of .
$ suitkaise --version
0.4.14
suitkaise infoPrint version, module list, and supported Python versions.
$ suitkaise info
suitkaise 0.4.14
Website: https://suitkaise.info
Download docs: suitkaise docs
suitkaise modulesList all available modules, one per line.
$ suitkaise modules
timing
paths
circuits
cucumber
processing
sk
suitkaise docsDownload the full documentation to your project root. Your current working directory must be inside the project root.
$ suitkaise docs
You can also download docs from Python:
from suitkaise import docs
docs .download()
# or to a specific path within your project
docs .download("path/within/project")
To place docs outside your project root, use the Permission context manager:
from suitkaise import docs
with docs .Permission():
docs .download("/Users/joe/Documents")
cucumber Serialization engine that eliminates PicklingErrors by handling types that pickle, cloudpickle, and dill cannot — threads, queues, sockets, generators, database connections, and more. Provides live resource reconnection and supports classes defined in __main__ for multiprocessing.
from suitkaise .cucumber import (
serialize ,
deserialize ,
serialize_ir ,
reconnect_all ,
ir_to_jsonable ,
ir_to_json ,
to_jsonable ,
to_json ,
SerializationError,
DeserializationError,
)
Or from the top level:
from suitkaise import serialize , deserialize , reconnect_all
circuits Circuit breaker module for managing failures with exponential backoff, jitter, and thread-safe coordination. auto-resets after sleeping. stays broken until manually reset. Works with for cross-process failure coordination.
from suitkaise .circuits import (
Circuit ,
BreakingCircuit ,
)
processing Parallel processing module with class-based processes (), easy shared state (), and automatic serialization using . Supports lifecycle hooks, automatic retries, timeouts, and inter-process communication via .
from suitkaise .processing import (
Skprocess ,
Pool ,
Share ,
Pipe ,
autoreconnect ,
ProcessTimers,
ProcessError,
PreRunError,
RunError,
PostRunError,
OnFinishError,
ResultError,
ErrorHandlerError,
ProcessTimeoutError,
ResultTimeoutError,
)
paths Cross-platform path handling with project-relative paths. Automatically detects project root, normalizes separators, and provides for automatic type conversion. Drop-in upgrade from pathlib.Path.
from suitkaise .paths import (
Skpath ,
AnyPath ,
autopath ,
CustomRoot ,
set_custom_root ,
get_custom_root ,
clear_custom_root ,
get_project_root ,
get_caller_path ,
get_current_dir ,
get_cwd ,
get_module_path ,
get_id ,
get_project_paths ,
get_project_structure ,
get_formatted_project_tree ,
is_valid_filename ,
streamline_path ,
PathDetectionError,
NotAFileError,
)
sk Modifier system that adds retry, timeout, background execution, rate limiting, and async support to any function or class. Modifiers are applied at the call site, not the definition.
from suitkaise .sk import (
sk ,
blocking ,
SkModifierError,
FunctionTimeoutError,
)
timing Performance timing with deep statistics (mean, median, stdev, percentiles) and thread-safe measurement. Use , , or directly. Works with for cross-process aggregation.
from suitkaise .timing import (
time ,
sleep ,
elapsed ,
Sktimer ,
TimeThis ,
timethis ,
clear_global_timers ,
)