Various small but useful Python utilities, experiments, and scripts collected in one place. Some are stand‑alone command‑line tools, others are small libraries or demo apps. A Docker image is provided to bundle the collection for easy, reproducible execution on multiple CPU architectures.
Quick links:
- Project Docker image: built from the repo‑root
Dockerfileand published via multi‑arch builds - CI: mypy + pytest, and a multi‑arch Docker build/push workflow (see badges above)
Contents overview (Python packages/modules):
dinogame: pathfinding/visualization playground inspired by "The Farmer Was Replaced"dnsstuff: SPF resolution helper and ipset updater for allow‑listing email senders (e.g. pcbway.com)ecowittstuff: simple client/types for Ecowitt weather station APIgcalstuff: CLI tool for creating Google Calendar events with day‑view confirmationhydromailstuff: assemble and send "hydro"/weather summary emails, pulling data from MQTT/Netatmok3shelperstuff: K3s kubeconfig credential synchronization utilityllmstuff: helpers for working with LLM APIs and local OCRdhcpstuff: DHCP discover tool and diagnostic script for unwanted DHCP on Linuxnetatmostuff: Netatmo data fetch helper and deployment examplesipstuff: moved to standalone repo — github.com/vroomfondel/sipstuff (seesipstuff/README.md)- Root helpers:
Helper.py, configs (config.yaml,config.py, optionalconfig.local.yaml), scripts - External packages:
mqttstuffandreputils(via PyPI)
Standalone Docker image sub‑projects (each with own Dockerfile and build.sh):
tangstuff: Tang server for LUKS/Clevis network‑bound disk encryptionmosquitto-2.1: Mosquitto 2.1 MQTT broker with dynamic securitypython314jit: Python 3.14 base image with JIT supportpython314pandasmultiarch: Python 3.14 base image with pandas (multi‑arch)nfs-subdir-external-provisioner: Kubernetes NFS provisioner (external submodule with local overlay)
Local prerequisites:
- Python 3.14+ recommended (repo and Docker image currently use
python:3.14-trixie) pipand a virtualenv of your choice
Install dependencies:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
Configuration:
config.yamlcontains sample/defaults. Do not commit secrets. If needed, createconfig.local.yamlto override locally (kept out of the image by default). Some modules read credentials/API keys from here (e.g. Ecowitt, Netatmo, MQTT, email settings). Adjust as needed before running modules that require it.
Run tests and type checks:
pytest -q
mypy .
Secret scanning with gitleaks:
- Gitleaks runs as a pre‑commit hook (see
.pre-commit-config.yaml) and catches secrets before they are committed. - The repo‑level
.gitleaks.tomlextends the default ruleset ([extend] useDefault = true) and allowlists paths that are expected to contain local‑only or generated content (.venv,.mypy_cache,.idea,__pycache__,*local*files,docker-config). - To scan the entire repo on demand:
make gitleaks
# or directly:
gitleaks dir . -v
DHCP discovery and diagnostic tools. Includes a Python DHCP Discover sender that displays all responses (including Proxy DHCP/PXE boot servers) and a bash diagnostic script for finding unwanted DHCP on physical interfaces (Ubuntu Server).
- CLI usage (requires root):
sudo python -m dhcpstuff -i eth0 -a efi64- Flags:
-iinterface,-ttimeout,-mMAC,-aPXE architecture (bios,efi64,efi64-http). - The bash script
diagnose-dhcp.shchecks cloud-init, netplan, systemd-networkd, NetworkManager, kernel cmdline, leases, and hooks for unwanted DHCP sources. - No external dependencies (stdlib only).
- Usefulness: quickly identify all DHCP/PXE servers on a network segment, or diagnose why a Linux host is unexpectedly obtaining a DHCP lease.
Pathfinding toy project and visualization to prototype search/planning strategies on a grid world, loosely inspired by “The Farmer Was Replaced”. Useful to experiment with A* heuristics and safe‑move constraints while visualizing planning vs execution.
- Entrypoint example:
dinogame/dinogame.pycontains amain()that renders a GIF of a planning/execution sequence. - Requirements:
matplotlib,numpy(matplotlibis commented out inrequirements.txtby default; enable it to use this module). - Run locally:
python -m dinogame.dinogame
This saves an animated GIF (via pillow) to your desktop by default; see code comments to tweak world size and frame count.
Script to crawl SPF records (including nested include: chains) for one or more domains, resolve them to IPv4 ranges/addresses, then update an ipset. The ipset can be used by your MTA/firewall to allowlist specific SMTP sources. Originally motivated by receiving mails from pcbway.com while using country‑based IP blocks.
- CLI usage:
python -m dnsstuff.spf_ipset_updater [--ipset-name NAME] [--ipset-type TYPE] [--dry-run] [domain ...]
- Behavior:
- Logs resolved IPv4s for each domain and combined total.
- If running as root (
UID 0), updates/swap‑refreshes the target ipset (default:smtpallowlist) usingpyroute2.ipset. - If not root, it only reports and skips the ipset update step.
- Dependencies:
dnspython,pyroute2. - Usefulness: automate building an SMTP allowlist from domains you trust, keeping it fresh even with complex SPF chains.
Small client types and functions to call the Ecowitt API and parse real‑time weather data into typed models.
- Main bits:
ecowittstuff/ecowittapi.pydefinespydanticmodels (e.g.WeatherStationResponse) andget_realtime_data(). - Config required:
ecowitt.application_key,ecowitt.api_key,ecowitt.mac, URLs inconfig.yaml. - Example:
python -c "from ecowittstuff.ecowittapi import get_realtime_data; print(get_realtime_data())"
- Usefulness: convenient, typed access to your Ecowitt station’s real‑time metrics for dashboards, alerts, and reports.
CLI tool for creating Google Calendar events via OAuth2 Desktop flow. Shows all existing events for the target day across all user calendars and requires explicit confirmation before creating the new event.
- Entrypoint:
gcalstuff/gcal_event.py - Setup: download OAuth2 Desktop credentials from Google Cloud Console to
~/.config/gcal/credentials.json. On first run the browser‑based OAuth flow creates~/.config/gcal/token.json. - CLI usage:
python -m gcalstuff.gcal_event "Meeting" 2025-07-15 14:00
python -m gcalstuff.gcal_event "Lunch" 2025-07-15 12:00 -d 90 --description "Team lunch"
- Dependencies:
google-auth,google-auth-oauthlib,google-api-python-client. - Docker: the initial OAuth flow opens a browser, so run it on the host first. After that, mount
~/.config/gcalinto the container (read‑write, since the token gets refreshed). ThedstartMakefile target already includes this mount. - Usefulness: quick calendar event creation from the terminal with conflict visibility.
Compose and send a status email summarizing recent measurements (e.g., water level, rain totals, ambient data). Pulls latest values from MQTT topics and Netatmo.
- Entrypoint:
hydromailstuff/hydromail.py→do_main_stuff(). - Needs config: email settings, MQTT (
mqtt.*), and Netatmo credentials undernetatmo.*inconfig.yaml. - There are example deployment/cron YAMLs in
hydromailstuff/somestuff_hydromail_cronjob.yml. - Usefulness: periodic email digests for environmental monitoring.
Helper utilities to interact with LLM providers or local OCR pipelines.
- Files:
llmstuff/llmhelper.py,llmbatchhelper.py,ollamadeepseekocr.py. - Config: keys under
google.*andanthropic.*inconfig.yamlif you want to call those providers. - Usefulness: quick building blocks when experimenting with LLMs and OCR.
Minimal MQTT wrapper(s) and helpers. This is now an external package — see GitHub and PyPI.
- Config:
mqtt.*andmqtt_topics.*inconfig.yaml(topics include metadata such as subscribe flag and default metadata). - Usefulness: standardize how topics are named and read/published across scripts.
Read Netatmo measurements and provide a deployment example.
- Files:
netatmostuff/lnetatmo.py, deployment examplesomestuff_netatmo_deployment.yml. - Config:
netatmo.username/password/client_id/client_secret(and optional module IDs) inconfig.yaml. - Usefulness: sourcing outdoor temperature, rainfall, pressure, etc., for dashboards or mail digests.
K3s kubeconfig credential synchronization utility. Fetches the kubeconfig from a remote K3s server via SSH, compares user credentials and cluster CA data against the local ~/.kube/config, and interactively updates any differences.
- Entrypoint:
k3shelperstuff/update_local_k3s_keys.py - CLI usage:
python -m k3shelperstuff.update_local_k3s_keys
python -m k3shelperstuff.update_local_k3s_keys -H myserver -c my-k3s-context
- Remote host and context are auto‑detected from the current‑context in the local kubeconfig if not provided.
- Docker: mount
~/.kubeinto the container (read‑write, since the script updates the local kubeconfig). ThedstartMakefile target already includes this mount. The script SSHs to the remote host, so~/.sshmust also be accessible. - Usefulness: keep local kubeconfig credentials in sync with a remote K3s server after certificate rotation.
The SIP caller module has been moved to its own standalone repository with significantly expanded features:
github.com/vroomfondel/sipstuff — Docker image: xomoxcc/sipstuff
The Flickr photo backup functionality has been moved to a standalone repository: github.com/vroomfondel/flickrtoimmich
The Docker image is still available at Docker Hub: xomoxcc/flickr-download.
Helper.py: JSON helpers including aComplexEncoderto serialize datetimes, UUIDs, and custom objects withrepr_json()/as_string().config.py: config loader/merger; useconfig.local.yamlto keep secrets out of VCS and override defaults.scripts/update_badge.py: helper used in CI to update the clones badge.tests/: basic test scaffold.
There is a single Docker image defined by the repo‑root Dockerfile. The image:
- Uses
python:3.14-slim-trixiebase (commented alternatives exist for 3.13/ PyPy). - Single‑stage build. Installs system tools (
htop,dnsutils,tini,ffmpeg, etc.) and Python deps viarequirements.txt. - Creates a non‑root user (
pythonuser, configurable via build argsUID,GID,UNAME). - Copies the packages into
/appand setsPYTHONPATHaccordingly. - Accepts build‑time metadata args and exports them as envs:
GITHUB_REF,GITHUB_SHA,BUILDTIME. - Entrypoint is
tini --, defaultCMDtails the log (adjust for your workload).
Why this is useful:
- Reproducible environment across machines/architectures.
- Non‑root execution by default improves container security.
- Multi‑arch support (amd64 + arm64) for running on laptops, servers, and SBCs alike.
docker build \
--build-arg buildtime="$(date +'%Y-%m-%d %H:%M:%S %Z')" \
-t xomoxcc/somestuff:python-3.14-slim-trixie \
.
Run interactively (example):
docker run --rm -it \
-v $(pwd)/config.yaml:/app/config.yaml:ro \
xomoxcc/somestuff:python-3.14-slim-trixie \
python -m dnsstuff.spf_ipset_updater pcbway.com
This repo includes a helper script build.sh that:
- Logs in (expects
DOCKER_TOKENUSERandDOCKER_TOKENin env on first run) - Ensures a
buildxbuilder exists (and installs binfmt/qemu if needed) - Builds locally and also performs a
docker buildx build --platform linux/amd64,linux/arm64 --pushwith tags - Writes local build logs to
docker_build_local.log
Usage:
./build.sh # multi‑arch build & push
./build.sh onlylocal # local build only (no push)
The script also sets DOCKER_CONFIG to the bundled docker-config/ directory so the builder state is isolated per‑repo. The primary tag is xomoxcc/somestuff:python-3.14-slim-trixie and an additional :latest tag is automatically added if missing.
Verify which permissions (pull, push, delete) a Docker Hub token has for all repositories in a namespace:
make check-dockerhub-token
This uses DOCKER_TOKENUSER and DOCKER_TOKEN from scripts/include.sh (overridden by scripts/include.local.sh). Additional namespaces defined in the DOCKERHUB_NAMESPACES bash array are passed automatically. The script can also be called directly:
python3 scripts/check_dockerhub_token.py <username> <token> -n <extra-namespace> -n <another>
To update the Docker Hub repository descriptions from the DOCKERHUB_OVERVIEW.md files:
make update-all-dockerhub-readmes
This updates all Docker Hub repos (somestuff, python314-jit, pythonpandasmultiarch, mosquitto, tang) using the credentials from docker-config/config.json.
.github/workflows/buildmultiarchandpush.ymlbuilds and pushes multi‑arch images. Triggers automatically after a successful mypy/pytest run (only rebuilds sub‑project images when their directory changed). Can also be triggered manually via Actions → BuildAndPushMultiarch → Run workflow, where checkboxes let you select which images to build (main somestuff, mosquitto, tang, python314‑jit, pythonpandasmultiarch)..github/workflows/mypynpytests.ymlruns mypy + pytest..github/workflows/checkblack.ymlchecks code style..github/workflows/update-clone-badge.ymlupdates the clones badge.
Each sub‑project has its own Dockerfile, build.sh, and README.md:
Python 3.14 base image with JIT support for experimenting with Python 3.14's new features and performance.
- Docker Hub
- See
python314jit/README.mdfor details.
Python 3.14 base image with pandas pre‑installed, built for multi‑arch (amd64 + arm64).
- Docker Hub
- See
python314pandasmultiarch/README.mdfor details.
Mosquitto 2.1 MQTT broker with dynamic security plugin, multi‑arch build.
- Docker Hub
- See
mosquitto-2.1/README.mdfor details.
Tang server for LUKS/Clevis network‑bound disk encryption (NBDE), enabling automatic disk unlock on trusted networks.
- Docker Hub
- See
tangstuff/README.mdfor details.
Kubernetes NFS external provisioner (git submodule from upstream). Local modifications are stored in overlays/nfs-subdir-external-provisioner/ and applied at build time.
- Build:
make build-nfs(applies overlay, then builds) - See upstream repo for documentation.
This is a living collection; no strict semantic versioning. Expect occasional breaking changes. A rough, humorous version might be “-0.42”.
This project is licensed under the LGPL where applicable/possible — see LICENSE.md. Some files/parts may use other licenses: MIT | GPL | LGPL. Always check per‑file headers/comments.
- Repo owner (primary author)
- Additional attributions are noted inline in code comments
- Inspirations and snippets are referenced in code comments where appropriate.
This is a development/experimental project. For production use, review security settings, customize configurations, and test thoroughly in your environment. Provided "as is" without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software. Use at your own risk.
