sc92-public-define
Personal shared utilities extracted from everyday scripts:
- Single-instance file lock —
check_running_lock(): if the script is already running elsewhere, exit (or return False) immediately. - Rotating logging setup —
init_logging_config(): one call to get*_debug.log+*_info.log(10 MB × 7 backups) + console output. If another library already configured the root logger it now warns on stderr instead of silently doing nothing (passforce=Trueto take over); with no console (pythonw.exe, PyInstaller--noconsole) the console handler is skipped. - Global exception hooks —
enable_exception_logging(): uncaught exceptions are written to the log instead of only printed to stderr — for the main thread and for worker threads (threading.excepthook, whichsys.excepthooknever covers). - MQTT publisher —
MqttPublisher.publish(): one-shot connect → publish → disconnect. Credentials are taken from explicit constructor args only (no hardcoded defaults, no environment variables) — keep them in your local YAML config file and pass the values in. - YAML config helpers —
read_yaml()/write_yaml(): first run writes a default template intoconfigs/next to the script and exits for review; Chinese keys and insertion order are preserved, and a file saved as ANSI/GBK or broken YAML now fails with a readable message instead of a rawUnicodeDecodeError.
All helpers are PyInstaller-frozen aware and default to paths derived from the entry script, so typical usage needs zero arguments.
The derived name is <script dir>/…/<script name>…, so one instance means
"one running copy of this script in this directory": a renamed or copied script
is a separate instance. python -m pkg[.mod] is handled as module pkg[.mod]
with the current working directory as its base — it never writes into
site-packages.
Install
pip install sc92-public-define
Requires Python >= 3.11 (filelock>=4.0, paho-mqtt>=2.0, PyYAML>=6.0).
Typical usage (top of any script)
import logging
from sc92_public_define import (
check_running_lock, # single-instance lock
init_logging_config, # rotating logs + console
enable_exception_logging, # uncaught exception -> log
)
init_logging_config() # logs/<script name>_debug.log / _info.log
check_running_lock() # <script name>.running.lock next to the script;
# exits with status 1 when another copy is running
enable_exception_logging()
logging.info("main started")
MQTT publishing (credentials live in your YAML config, never in code)
from sc92_public_define import MqttPublisher, read_yaml
server = read_yaml()["mqtt服务器"] # nested dict in <script>.config.yaml
pub = MqttPublisher(host=server["地址"], port=server["端口"],
username=server["用户名"] or None,
password=server["密码"] or None,
topic=server["主题"])
pub.publish("hello") # uses instance topic/qos
pub.publish("hello", topic="other/t", qos=1) # per-call override
YAML config
from sc92_public_define import read_yaml, write_yaml
cfg = read_yaml(default_config={"服务器": "127.0.0.1", "端口": 8080})
# first run: creates configs/<script>.config.yaml next to the script, logs a hint, exits
cfg["端口"] = 9090
write_yaml(config_dict=cfg) # writes back to the same default file
API
| Function | Default | Notes |
|---|---|---|
check_running_lock(lock_file=None, on_conflict="exit") |
<script dir>/<script>.running.lock |
on_conflict="exit" → logs an error and exits with status 1; "return" → returns False; True when acquired |
init_logging_config(log_file=None, max_bytes=10MB, backup_count=7, force=False) |
<script dir>/logs/<script> |
warns on stderr and does nothing if the root logger already has handlers (force=True takes over); console handler skipped when there is no console |
enable_exception_logging() / handle_global_exception / handle_thread_exception |
— | sets sys.excepthook and threading.excepthook, writes tracebacks via logging.error |
MqttPublisher(host, port=1883, username=None, password=None, topic=None, qos=2, client_id=None, connect_timeout=5, publish_timeout=10) |
explicit args only | raises ValueError if host/topic missing; connect_timeout caps DNS + TCP + the wait for CONNACK |
MqttPublisher.publish(msg, topic=None, qos=None) |
instance defaults | True only when the message really got through: QoS 1/2 require the broker acknowledgement, QoS 0 has none (written to the socket only). Wrong password, missing CONNACK, an unacknowledged publish or any network error → False plus a logging.error, never raises. bytes/bytearray payloads are sent as-is, anything else is str()-ed |
read_yaml(config_file=None, default_config=None, on_missing="exit", merge_defaults=False) |
<script dir>/configs/<script>.config.yaml |
missing → write template + exit(1); empty file or {} → overwrite with the template + exit(1); non-UTF-8 / broken YAML / top level not a mapping → ValueError; merge_defaults=True fills keys that only exist in default_config into the returned dict (the file on disk is untouched); the returned template is a deep copy |
write_yaml(config_file=None, config_dict=None) |
same default file | config_dict is required (None or a non-dict raises ValueError); utf-8, Chinese keys & order preserved |
script_dir() / script_name() |
— | entry-script path/name; frozen exe → exe folder/stem; python -m pkg → cwd + pkg |
default_lock_file() / default_log_file() / default_config_file() |
— | expose the derived default paths |
Notes
- The lock is released automatically by the OS when the process exits; the lock file is left on disk (harmless, reuse next time).
- The first
read_yaml()run on a machine without a config file deliberately exits with status 1 after writing the template: edit it, then run again. init_logging_config()must come beforecheck_running_lock()/read_yaml(), otherwise their "抢锁结果 / 配置已加载" INFO lines are dropped (only the ERROR lines still reach stderr through logging's last-resort handler).- See the
demo/folder in the source tree for runnable examples (it is not shipped inside the wheel or sdist).
Metadata
Release files for sc92-public-define 0.3.1
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 | Actions |
|---|---|---|---|---|
| sc92_public_define-0.3.1.tar.gz | 14.6 kB | Without provenance | Details for sc92_public_define-0.3.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| sc92_public_define-0.3.1-py3-none-any.whl | Python 3 | none | any | Details for sc92_public_define-0.3.1-py3-none-any.whl |
Total release size: 28.9 kB
Release files / sc92_public_define-0.3.1.tar.gz
| Download URL | sc92_public_define-0.3.1.tar.gz |
|---|---|
| Size | 14.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e508301a47037858c636be21f746301ef0efcdcc5da2da608ef9248edd779715
|
|
BLAKE2b-256 checksum How to use checksums |
35198268dda4cd5b182f80b7b70113494c79f23879b967f016ba16b50aded22e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Release files / sc92_public_define-0.3.1-py3-none-any.whl
| Download URL | sc92_public_define-0.3.1-py3-none-any.whl |
|---|---|
| Size | 14.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dac1b8f51d6d963219d070d5453f38142be4a1ea01f603817b91ff8a0881980a
|
|
BLAKE2b-256 checksum How to use checksums |
e47a64806dbb88ac20d6a27eafa4b4af5f4b1543c9c84cc611487024fa5dc8f9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Security for sc92-public-define 0.3.1
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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.