A lightweight, zero-dependency Python library for registering, discovering, and managing functions or classes with attached metadata.
MicroReg acts as a strict, flat-namespace catalog for software components — useful for plugin systems, sensor registries, tool catalogs, and anything that benefits from a central lookup table of callables.
- Zero dependencies — standard library only
- Strict uniqueness — duplicate names raise an error immediately; no silent overwrites
- Passive storage — metadata is stored as-is; no schema validation
- Dynamic discovery — auto-import modules to trigger decorator-based registrations
- Fully typed — passes
mypy --strict
pip install micro-regRequires Python 3.10+.
from micro_reg import Registry
reg = Registry("hardware_tools")
@reg.register(name="read_voltage", type="sensor", unit="V")
def read_voltage() -> float:
return 5.0
func, meta = reg.get("read_voltage")
print(func()) # 5.0
print(meta) # {'type': 'sensor', 'unit': 'V'}Creates a new registry with a given label. The label is for identification only and does not affect behaviour.
reg = Registry("my_tools")
print(reg.name) # "my_tools"Decorator that registers a callable under a unique name with optional metadata.
@reg.register(name="greet", language="en")
def greet() -> str:
return "hello"namemust be unique within the registry.- Any additional keyword arguments are stored as metadata.
- The original callable is returned unwrapped — its behaviour is unchanged.
Raises: DuplicateRegistrationError if name is already registered.
Retrieves a registered callable and its metadata by name.
func, meta = reg.get("greet")
func() # "hello"
meta # {"language": "en"}Raises: KeyError if name is not registered.
Dynamically imports all Python modules found under search_path. Any module that uses @reg.register(...) at the top level will trigger those registrations as a side effect of being imported.
reg.discover("/path/to/plugins")Raises:
FileNotFoundErrorif the path does not exist.NotADirectoryErrorif the path is not a directory.
See Advanced: Discovery for a full example.
Raised when attempting to register a name that already exists in the registry.
from micro_reg import DuplicateRegistrationError
try:
@reg.register(name="read_voltage")
def another_sensor() -> float:
return 0.0
except DuplicateRegistrationError as e:
print(e.name) # "read_voltage"
print(e) # Name already registered: 'read_voltage'Attributes:
name: str— the name that caused the conflict.
The discovery pattern is useful for plugin systems where callables live in separate modules and should be loaded automatically.
Directory layout:
my_project/
plugins/
__init__.py
sensors.py
actuators.py
main.py
plugins/sensors.py:
from main import reg
@reg.register(name="temperature", unit="C")
def read_temperature() -> float:
return 22.5plugins/actuators.py:
from main import reg
@reg.register(name="motor", type="actuator")
def spin_motor() -> bool:
return Truemain.py:
from micro_reg import Registry
reg = Registry("hardware")
reg.discover("plugins")
func, meta = reg.get("temperature")
print(func()) # 22.5
print(meta) # {"unit": "C"}discover() walks the directory, imports each module, and the decorators run as side effects — populating the registry without any manual wiring.
from micro_reg import Registry, DuplicateRegistrationError
reg = Registry("tools")
@reg.register(name="ping")
def ping() -> str:
return "pong"
# Duplicate name
try:
@reg.register(name="ping")
def ping2() -> str:
return "pong2"
except DuplicateRegistrationError as e:
print(f"Conflict: {e.name}") # Conflict: ping
# Missing name
try:
reg.get("nonexistent")
except KeyError:
print("Not found")See the examples/ directory for runnable scripts:
basic_usage.py— register and retrieve callables with metadatadiscovery_usage.py— auto-discover and import plugin modules
git clone https://gitlab.com/your-username/micro-reg.git
cd micro-reg
pip install -e ".[dev]"
# Run tests
pytest
# Type checking
mypy micro_reg --strict
# Lint & format
ruff check .
ruff format .All public classes, methods, and functions require docstrings. Code must pass mypy --strict and ruff check before submitting.
MIT — see LICENSE.