ATCKit
AccidentallyTheCable's Utility Kit
- ATCKit
About
This is a small kit of classes, util functions, etc that I found myself rewriting or reusing frequently, and instead of copying everywhere, they are now here.
WARNING: Version 2.0 is a breaking change from 1.x versions 2.0 Removes the static class and moves things around. Please check the docs below for where things are now
How does it work?
Do the needfuls.... do the needful dance
Literally, import whatever you need to use..
Usage
FunctionSubscriber (atckit.subscriber)
A Class container for Function callback subscription via += or -=. Functions can be retrieved in order of addition.
subscriber = FunctionSubscriber()
def a():
print("I am a teapot")
def b():
print("I am definitely totally not also a teapot, I swear")
subscriber += a
subscriber += b
for cb in subscriber.functions:
cb()
>> I am a teapot
>> I am definitely totally not also a teapot, I swear
This class uses the typing.Callable type for function storage. You can extend the FunctionSubscriber class to define the
callback function parameters, etc.
class MySubscriber(FunctionSubscriber):
"""My Function Subscriber
Callback: (bool) -> None
"""
_functions:list[Callable[[bool],None]]
def __iadd__(self,fn:Callable[[bool],None]) -> Self:
"""Inline Add. Subscribe Function
@param method \c fn Method to Subscribe
"""
return super().__iadd__(fn)
def __isub__(self,fn:Callable[[bool],None]) -> Self:
"""Inline Subtract. Unsubscribe Function
@param method \c fn Method to Unsubscribe
"""
return super().__isub__(fn)
Core Functions (atckit)
create_object_logger
Create logging.Logger instance for object specifically
create_static_logger
Create logging.Logger instance of a specified name
deltatime_str
Create datetime.timedelta from short formatted time string. Format: 0Y0M0w0d0h0m0s0ms
deep_sort
Sort a Dictionary recursively, including through lists of dicts
File Utils (atckit.files)
Classes and functions located in the files module
dump_sstr
Dump Structured Data (dict) to str of specified format. Accepts JSON, YAML, TOML
load_sstr
Load Structured Data from String. Accepts JSON, YAML, TOML
load_sfile
Load Structured Data from File, automatically determining data by file extension. Accepts JSON, YAML, TOML
scan_dir
Search a specified Path, and execute a callback function on discovered files.
- Allows exclusion of Files/Dirs via regex pattern matching
find_config_file
Look for config file in 'well defined' paths. Searches for <service>/<config>.[toml,json,yaml] in ~/.local/ and /etc/ (in that order)
add_config_search_path
Add Search Path for find_config_file
remove_config_search_path
Remove Search Path for find_config_file
add_config_search_file_ext
Add file extension for find_config_file
remove_config_search_file_ext
Remove file extension for find_config_file
Signals (atckit.signals)
Signal Handling functions located in signals
check_pid
Check if a process ID exists (via kill 0)
register_pid
Register (Write) process ID in specified directory as <service>.pid
register_signals
Register Shutdown / Restart Handlers
- Check for Shutdown via UtilFuncs.shutdown (bool)
- Check for Restart via UtilFuncs.restart (bool)
sleep
Signal-aware Sleep (replacement for time.sleep when using signals)
- Shutdown/Restart aware
- Interrupt granularity (check every N seconds (default: 1ms)); lower numbers will breakout faster at the cost of CPU
Service (atckit.service)
A Service / Daemon Class. Responds to signals properly, including HUP to restart threads
HUP does not restart main thread. So if the main configuration file needs to be re-read, the service needs to be stopped and started completely.
Entrypoint functions for services are defined under the .services FunctionSubscriber. These functions should be loopable, or be capable of starting again each time the function completes.
Create a class, which extends Service, such as MyService.
- Set Service Name:
MyService._SERVICE_NAME = "myservice" - Set Shutdown Time Limit:
MyService._SERVICE_SHUTDOWN_LIMIT = 300(default shown) - Set Thread Check Interval:
MyService._SERVICE_CHECK_TIME = 0.5(default shown) - Configuration Loading: Utilizes
UtilFuncs.find_config_file()andUtilFuncs.load_sfile(), will attempt to load<service_name>/<service_name>.[toml,yaml,json]from 'well known' paths, configuaration available inMyService._config. Additional locations can be added withUtilFuncs.add_config_search_path() - Subscribe / Create Thread:
MyService.services += <function> - Unsubscribe / Remove Thread:
MyService.services -= <function> - Shutdown: Set
MyService.shutdown(bool), UtilizesUtilfuncs.shutdown - Restart: Set
MyService.restart(bool), UtilizesUtilfuncs.restart - Run Check: Check
MyService.should_runto see if thread needs to stop - Run: Call
MyService.run() - Stop: Call
MyService.stop() - Signal Handlers: Utilizes
Utilfuncs.register_signals() - Process ID storage: Set
pid_dirin Configuration File
Example Service Functions:
import logging
from time import sleep
from atckit.service import Service
class MyService(Service):
def __init__(self) -> None:
super().__init__()
self.services += self._testloopA # Add Thread to Service
self.services += self._testloopB # Add another Thread
def _testloopA(self) -> None:
"""Test Function, Continuous loop
@retval None Nothing
"""
while self.should_run:
self.logger.info("Loop test")
sleep(1)
def _testloopB(self) -> None:
"""Test Function, One Shot, restarting at minimum every `MyService._SERVICE_CHECK_TIME` seconds
@retval None Nothing
"""
self.logger.info("Test Looop")
sleep(1)
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG) # Logging Configuration
service:MyService = MyService() # Initialize Service
service.run() # Stop with ABRT/INT/TERM CTRL+C
service.stop() # Cleanup / Wait for Shutdown
Version (atckit.version)
A Class for version manipulation.
A Version can be created from:
- Semantic String (
"1.0.0") - List of Strings or Ints of a version (
["1","0","0"]or[1,0,0]) - Tuple of Strings or Ints of a version (
("1","0","0")or(1,0,0))
Versions are comparable (>,<,>=,<=,==,!=)
Versions are addable and subtractable (a -= b, a += b)
- During subtraction, if a part goes negative, it will be set to 0
Version Search Strings
To make Version things even easier, 2 functions are also included in the Version module, which enables a list of matching versions to be created, from the search.
Version Search Strings are 1 or more entries in a specially formatted string: <comparator>:<version>,...
Supported comparators: >,<,>=,<=,==,!=
Example Searches:
- ">=:1.0.0,!=:2.0.2,<=:4.0.0"
- "<=:3.0.0,>:0.9.0"
version_locator
Given a list of versions, locate a version which matches a given search string.
- Example 1 matching:
- Any Version Newer than 1.0.0, including 1.0.0
- Not Version 2.0.2
- Any Version Older than 4.0.0, including 4.0.0
- Example 2 matching:
- Any Version Older than 3.0.0, including 3.0.0
- Any Version Newer than 0.9.0, not including 0.9.0
version_search_merge
Combine 2 Version Search Strings, creating a single string, which satisfies all searches in each string.
Given the examples above, merging these two searches, would result in the following compatible search: >=:1.0.0,<=:3.0.0,!=:2.0.2
Metadata
Release files for atckit 2.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| atckit-2.1.0.tar.gz | 92.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| atckit-2.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 121.4 kB
Release files / atckit-2.1.0.tar.gz
| Download URL | atckit-2.1.0.tar.gz |
|---|---|
| Size | 92.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b32aefda2f8317cb1b01747f12b580def14ad48c1c7d2ae75908e36aff51b8de
|
|
BLAKE2b-256 checksum How to use checksums |
646f409250e2e728a0f1f8e8f7a5617f8485d0cdae5e998d5f9a6b4283b7b10b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.2
|
Release files / atckit-2.1.0-py3-none-any.whl
| Download URL | atckit-2.1.0-py3-none-any.whl |
|---|---|
| Size | 28.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f70f752d205cf32bc99cab9846e5a9e0e58d2315dcc3e2c151ed3051b509a02b
|
|
BLAKE2b-256 checksum How to use checksums |
25de053cee7eb08fd43d418005fe25b4cec6672d808f9ab5e7aefaace0c5b33d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.2
|
Security for atckit 2.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.