This release is a pre-release and may not be stable for production use.
Hermes Device Manager (hermes-dm)
Hermes-DM is a lightweight, high-performance, and asynchronous device manager that provides a native, modern software interface for classic test and measurement hardware.
By leveraging ZeroMQ (ZMQ) for swift, non-blocking message passing and SCPI (Standard Commands for Programmable Instruments) for hardware communication, Hermes allows you to seamlessly control, monitor, and log data from generic lab instruments.
Features
- Asynchronous Architecture: Built on top of ZeroMQ for high-throughput, low-latency telemetry logging.
- Generic SCPI Support: Easily extensible to any programmable instrument (Power supplies, Oscilloscopes, DMMs, etc.).
- Decoupled Logging: Devices stream data asynchronously, isolating measurement constraints from data storage layers.
- Lightweight Footprint: Avoids heavy industrial middleware framework bloat.
Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ BACKGROUND DAEMON (hermes-daemon) │
│ │
│ [ SCPI Instruments ] ◄──── (PyVISA) ────► [ Async Server ] │
│ │ │ │
│ [ SQLite DB Logs ] ◄────── (Database) ─────────┘ │ │
└───────────────────────────────────────────────────────┼─────┘
│
(ZeroMQ: Ports 5555 REP & 5556 PUB)
│
┌───────────────────────────────────────────────────────▼─────┐
│ USER ENVIRONMENT (hermes_dm.client) │
│ │
│ [ HermesClient Library ] │
│ │ │
│ ▼ │
│ [ Standalone Scripts | Jupyter Notebooks | GUI App ] │
└─────────────────────────────────────────────────────────────┘
Installation
pip install hermes-dm
Quick Start
Hermes operates on a robust Client-Server architecture to ensure your hardware polling never blocks your user interfaces or scripts.
1. Start the Background Daemon
Run this in your terminal to start the background hardware manager:
hermes-daemon --db-dir ./lab_data --cmd-port 5555
2. Control via Python Script
In a separate terminal, Jupyter notebook, or GUI, use the client library to issue commands to the daemon:
from hermes_dm.client import HermesClient
# Connect to the background daemon
client = HermesClient(host="localhost", port=5555)
# Connect the hardware (driver logic is handled by the daemon)
client.connect_device(
name="Main_PSU",
model="Keithley2410",
identifier="TCPIP::111.222.33.44::INSTR"
)
# Configure the instrument
client.configure_device("Main_PSU", {"source_mode": "VOLT", "output_enabled": True})
# Start continuous asynchronous logging to SQLite
client.start_logging()
Developer Guide
Welcome! This section covers everything you need to know to set up a local development environment, understand the underlying architecture, and contribute to hermes-dm.
System Architecture Overview
hermes-dm uses a decoupled, event-driven, client-server architecture designed for high-performance, non-blocking laboratory hardware control.
- The Hermes Client: A lightweight, synchronous Python API exposed to user scripts or notebooks. It handles telemetry requests, sends command packets over ZeroMQ, and translates backend JSON error states back into native Python exceptions.
- The Hermes Daemon: A persistent, asynchronous background process (
asyncio) handling incoming network traffic via ZeroMQ. - Isolated Thread Pools: To prevent slow hardware I/O (like instrument connection scans or legacy GPIB commands) from locking up the main asynchronous network event loop, the daemon uses dedicated OS thread pools (
asyncio.to_threadand customThreadPoolExecutorinstances) to isolate synchronous PyVISA drivers.
Environment Setup
Follow these steps to set up an isolated development environment running your code in editable mode with all developer tools active.
-
Clone the repository and navigate to the root directory:
git clone [https://github.com/cbeiraod/hermes-dm.git](https://github.com/cbeiraod/hermes-dm.git) cd hermes-dm
-
Create a virtual environment:
python -m venv .venv
-
Activate the environment:
- Linux / macOS:
source .venv/bin/activate - Windows (Cmd):
.venv\Scripts\activate.bat - Windows (PowerShell):
.venv\Scripts\Activate.ps1
- Linux / macOS:
-
Install the package in editable mode with development extras:
pip install -e ".[dev]"
Note: If you are using Zsh, make sure to wrap the target in quotes:
pip install -e ".[dev]"Optionally, install the package in editable mode with development, testing, and documentation extras:
pip install -e ".[dev,docs]"
-
Install the local Git hooks:
python -m pre_commit install
Development Tools Stack
We use a modern, consolidated tool stack to enforce code quality, verify async test patterns, and automate package distribution.
| Tool | Purpose | Standalone Command |
|---|---|---|
| Pytest | Test runner for client, server routing, and database logs | pytest |
| Ruff | Lightning-fast linter, formatter, and import sorter | ruff check (lint) ruff format (style) |
| Pre-commit | Framework managing local Git hooks and code safety | python -m pre_commit run --all-files |
| Sphinx | Documentation generator extracting structural Python docstrings | sphinx-build -b html docs/ docs/_build/html |
| Bump-my-version | Automated single-source-of-truth version bumping | bump-my-version bump [patch|minor|major] |
| Build | Creates standard PEP 517 source archives and wheels | python -m build |
| Twine | Securely uploads distribution wheels to PyPI | twine upload dist/* |
Running Tools Standalone
-
Running the Test Suite: To execute all test suites with verbose execution details:
pytest -v -
Running Linter/Formatter Manually: While
pre-commitintercepts formatting issues during git tracking, you can trigger individual sweeps manually:ruff check --fix # Evaluates code quality rules and auto-fixes violations ruff format # Enforces your project's code style rules across all files
-
Simulating a Pre-commit Run: If you want to evaluate all files against the entire pre-commit stack (including trailing whitespace, end-of-file fixers, and forgotten debug statements) without committing code:
python -m pre_commit run --all-files
-
Building Documentation Locally: To compile your
.rstdesign layout and extract code docstrings via Sphinx into a responsive, dark-mode-ready static HTML site using the Furo theme:python -m sphinx -b html docs/ docs/_build/html
After compilation, open
docs/_build/html/index.htmlin your browser to preview the output. -
Executing a Release Version Bump: To safely increment versions across your
pyproject.tomland package__init__.pywhile auto-generating tracking commits and release candidate tags:bump-my-version bump minor
CI/CD Infrastructure (GitHub Actions)
Automation pipelines are tracked inside .github/workflows/. They isolate compute footprints to keep automation efficient and free.
1. Continuous Integration (ci.yml)
Triggers automatically on every push to main, pull request tracking, or creation of version tags (v*.*.*).
- Fail-Fast Lint Gate: Automatically triggers a clean cloud environment to test the full codebase against
pre-commit. If formatting is irregular or a straybreakpoint()is exposed, the job drops immediately. - Linux Test Core: Executes the complete async test matrix under an optimized caching system to evaluate package installs in seconds.
- Extended Multi-OS Testing: To control costs, tests targeting Windows and macOS runners are restricted. They execute only when a formal version release tag (e.g.,
v0.2.0) is discovered or when manually requested via the GitHub Actions UI.
2. PyPI Package Deployment (Coming Soon)
- Triggers exclusively on published GitHub Releases.
- Automatically triggers the
buildpipeline, verifies package architecture integrity viatwine check, and deploys clean production wheels securely onto the Python Package Index (PyPI).
License
This project is licensed under the zlib/libpng License - see the LICENSE file for details.
Metadata
Release files for hermes-dm 0.0.1a1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hermes_dm-0.0.1a1.tar.gz | 25.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hermes_dm-0.0.1a1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.4 kB
Release files / hermes_dm-0.0.1a1.tar.gz
| Download URL | hermes_dm-0.0.1a1.tar.gz |
|---|---|
| Size | 25.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c0cc8c35375f9da7048b82d136eb4af1433b6ba11a7b68416a5d5d3278ca6e5c
|
|
BLAKE2b-256 checksum How to use checksums |
4e80489904858752c633556986fa2b4db0e8c8deaaeed2a43a8e63cba09bdf4e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 4, 2026.
Transparency logRelease files / hermes_dm-0.0.1a1-py3-none-any.whl
| Download URL | hermes_dm-0.0.1a1-py3-none-any.whl |
|---|---|
| Size | 24.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4389ac1255037cd90929e386dca0aca464b88a1527a4c08ff78980a87928c0da
|
|
BLAKE2b-256 checksum How to use checksums |
b54868a7f5e0c8b7488f0c8e60b1d2b175b50800abc731012664b4666c44a1ce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 4, 2026.
Transparency log