Thread-safe registry framework for Python objects, plugins, strategies, handlers, or any reusable objects.
Project description
Regman : Thread-Safe Registry Framework for Python
Regman is a lightweight and flexible Python package to manage registries in a thread-safe way. It provides a simple yet powerful infrastructure for registering and managing classes, functions, and objects in a centralized, thread-safe manner.
Why Regman ?
The Problem
When building complex Python applications, you often need to:
- Manage multiple implementations of the same interface (e.g., different payment methods, data processors, or notification channels)
- Dynamically select components at runtime based on configuration or user input
- Implement design patterns like Strategy, Factory, Observer, or Plugin architectures
- Ensure thread safety when multiple threads access the same registry
- Avoid tight coupling between components and their instantiation logic
Common Solutions and Their Limitations
Manual dictionaries:
# ❌ Not thread-safe, error-prone
strategies = {
"credit_card": CreditCardStrategy,
"paypal": PayPalStrategy
}
strategy = strategies["credit_card"]() # KeyError if key doesn't exist
Simple registry classes:
# ❌ Not thread-safe, basic functionality
class SimpleRegistry:
def __init__(self):
self._items = {}
def register(self, key, value):
self._items[key] = value # Race condition in multi-threaded apps
Complex dependency injection frameworks:
# ❌ Overkill for simple use cases, heavy dependencies
from some_di_framework import Container, Service
container = Container()
container.register(Service(IPaymentStrategy), CreditCardStrategy)
# Too much boilerplate for simple registries
The Regman Solution
regman provides a simple, thread-safe, and flexible solution:
# ✅ Thread-safe, clean, and powerful
from regman import Registry, register
registry = Registry("payment_strategies")
@register(registry, "credit_card")
class CreditCardStrategy:
def pay(self, amount):
return f"Paid ${amount} with credit card"
# Safe to use from multiple threads
strategy_class = registry.get("credit_card")
strategy = strategy_class()
Key Benefits
- Thread Safety: Built-in locking ensures safe concurrent access
- Simplicity: Clean API with minimal boilerplate
- Flexibility: Works with any Python object (classes, functions, instances)
- Performance: Optimized for high-frequency access patterns
- Type Safety: Full type hints support for better IDE integration
- Design Pattern Ready: Perfect for implementing common architectural patterns
Real-World Use Cases
- Payment Processing: Different payment methods (credit card, PayPal, crypto)
- Plugin Systems: Dynamic loading and execution of plugins
- Data Processing Pipelines: Various data transformers and validators
- Notification Systems: Multiple notification channels (email, SMS, push)
- Configuration Management: Different configuration providers
- API Versioning: Multiple API implementations for different versions
Features
- Thread-Safe Registry: Store and manage objects with automatic locking for concurrent access
- Registry Manager: Centralize multiple registries for your project
- Decorator Support: Convenient
@registerdecorator for easy registration - Type Safety: Full type hints support for better IDE integration
- Lightweight: Minimal dependencies, fast performance
- Flexible: Works with any Python object (classes, functions, instances)
- Design Patterns: Perfect for implementing Strategy, Factory, Observer, and Plugin patterns
Installation
pip install regman
Or with Poetry:
poetry add regman
Quick Start
Basic Usage
from regman import Registry, register
# Create a registry
registry = Registry("my_components")
# Register a class
@register(registry, "calculator")
class Calculator:
def add(self, a: int, b: int) -> int:
return a + b
# Register a function
@register(registry, "multiplier")
def multiply(x: float, y: float) -> float:
return x * y
# Use registered objects
calc_class = registry.get("calculator")
calculator = calc_class()
result = calculator.add(5, 3) # 8
mult_func = registry.get("multiplier")
result = mult_func(4.5, 2.0) # 9.0
Registry Manager
from regman import RegistryManager, register
# Create a manager
manager = RegistryManager()
# Create multiple registries
plugins = manager.create_registry("plugins")
strategies = manager.create_registry("strategies")
# Register components
@register(plugins, "data_processor")
class DataProcessor:
def process(self, data):
return data * 2
@register(strategies, "payment_credit")
class CreditCardStrategy:
def pay(self, amount):
return f"Paid ${amount} with credit card"
# Access registries
data_processor = plugins.get("data_processor")
payment_strategy = strategies.get("payment_credit")
Advanced Usage
Strategy Pattern
from abc import ABC, abstractmethod
from regman import Registry, register
class PaymentStrategy(ABC):
@abstractmethod
def pay(self, amount: float) -> str:
pass
# Register strategies directly
registry = Registry("payment_strategies")
@register(registry, "credit_card")
class CreditCardStrategy(PaymentStrategy):
def pay(self, amount: float) -> str:
return f"Paid ${amount} with credit card"
@register(registry, "paypal")
class PayPalStrategy(PaymentStrategy):
def pay(self, amount: float) -> str:
return f"Paid ${amount} with PayPal"
# Use strategies
strategy_class = registry.get("credit_card")
strategy = strategy_class()
result = strategy.pay(100.0)
Plugin System
from abc import ABC, abstractmethod
from regman import Registry, register
class Plugin(ABC):
@abstractmethod
def execute(self, data):
pass
# Register plugins directly
registry = Registry("plugins")
@register(registry, "data_processor")
class DataProcessor(Plugin):
def execute(self, data):
return [x * 2 for x in data]
@register(registry, "text_formatter")
class TextFormatter(Plugin):
def execute(self, data):
return str(data).upper()
# Execute plugins
for plugin_name in registry.keys():
plugin_class = registry.get(plugin_name)
plugin = plugin_class()
result = plugin.execute("hello")
API Reference
Registry
The main registry class for storing and managing objects.
from regman import Registry
registry = Registry("my_registry")
Methods
add(key: str, value: Any) -> None: Add an object to the registryget(key: str) -> Any: Retrieve an object from the registryunregister(key: str) -> None: Remove an object from the registrykeys() -> List[str]: Get all registered keysclear() -> None: Remove all objects from the registry__contains__(key: str) -> bool: Check if a key exists__len__() -> int: Get the number of registered objects
RegistryManager
Manages multiple registries in a centralized way.
from regman import RegistryManager
manager = RegistryManager()
Methods
create_registry(name: str) -> Registry: Create a new registryget_registry(name: str) -> Registry: Get an existing registryall() -> Dict[str, Registry]: Get all registries
Decorators
@register
Register a class or function with a registry.
from regman import register
@register(registry, "my_key")
class MyClass:
pass
@register(registry, "my_function")
def my_function():
pass
Thread Safety
regman is designed to be thread-safe. All registry operations are protected by locks, making it safe to use in multi-threaded environments.
import threading
from regman import Registry, register
registry = Registry("thread_safe")
@register(registry, "worker")
class Worker:
def work(self):
return "Working safely!"
# Safe to use from multiple threads
def worker_thread():
worker_class = registry.get("worker")
worker = worker_class()
print(worker.work())
# Start multiple threads
threads = []
for i in range(5):
thread = threading.Thread(target=worker_thread)
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
Examples
Check out the examples directory for comprehensive usage examples:
- Basic Usage - Getting started with regman
- Plugin System - Building a plugin architecture
- Strategy Pattern - Implementing payment strategies
- Observer Pattern - Event notification system
- Factory Pattern - Object creation patterns
- Concurrent Usage - Multi-threaded applications
Run all examples:
python examples/run_all_examples.py
Testing
The package includes comprehensive tests covering:
- Unit tests for all components
- Thread safety tests
- Integration tests
- Error handling tests
Run tests:
# With pytest
pytest tests/
# With poetry
poetry run pytest
# With coverage
pytest --cov=regman tests/
Performance
regman is designed for performance:
- Minimal overhead with efficient locking
- Fast object retrieval with O(1) average case
- Memory efficient with no unnecessary allocations
- Optimized for high-frequency access patterns
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development
Setup
# Clone the repository
git clone https://github.com/mawuva/regman.git
cd regman
# Install with poetry
poetry install
# Install pre-commit hooks
poetry run pre-commit install
Code Quality
The project uses several tools to maintain code quality:
- Black: Code formatting
- isort: Import sorting
- flake8: Linting
- mypy: Type checking
- pytest: Testing
Run all quality checks:
poetry run pre-commit run --all-files
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
If you have any questions or need help, please:
- Check the examples directory
- Read the documentation
- Open an issue
Acknowledgments
- Inspired by the need for a simple, thread-safe registry system
- Built with modern Python best practices
- Designed for extensibility and performance
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file regman-0.2.0.tar.gz.
File metadata
- Download URL: regman-0.2.0.tar.gz
- Upload date:
- Size: 9.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.4 CPython/3.13.5 Windows/11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4efd9e1d22f4beaf06b4580ba806c9e226ef00d393f6e9fb9959094ab5c05115
|
|
| MD5 |
7a06241fb2f7adcf900bbe90df899619
|
|
| BLAKE2b-256 |
7e21095380e3cfd91a89fdc4cb3e1b811d26bc9956ee916ff21cb6f61d61d434
|
File details
Details for the file regman-0.2.0-py3-none-any.whl.
File metadata
- Download URL: regman-0.2.0-py3-none-any.whl
- Upload date:
- Size: 9.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.4 CPython/3.13.5 Windows/11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba9bb2f9c68f948a510f022dcb3a6abdb0a4f873332eb48d436774099eb5f646
|
|
| MD5 |
a79cb322120abbbcf48f459cc7974811
|
|
| BLAKE2b-256 |
4f5a1a3a4dce9c48b38a09c6168ea6ce70445c532ee9eb9696cb2bd35c420d17
|