A Python package for dynamic class registration and instantiation
Project description
KeyRegistry
KeyRegistry is a lightweight Python package designed to simplify dynamic class registration and instantiation in Python projects. It enables developers to register classes across a project using a decorator and instantiate them by name, without hardcoding import paths. This is particularly useful for projects with modular components, such as machine learning models, plugins, or extensible systems.
What is KeyRegistry?
KeyRegistry provides a registry system that automatically scans a project directory for Python classes decorated with @KeyRegistry.register. It maps class names to their module locations, allowing dynamic instantiation of classes based on their registered names and categories. KeyRegistry eliminates the need to manually import modules or maintain a centralised list of classes, making it ideal for projects with many components or frequent additions.
Key features:
- Automatic Discovery: Scans project directories for registered classes using AST parsing.
- Flexible Imports: Supports dynamic imports without requiring package structures (e.g.,
__init__.pyfiles). - Category-Based Organisation: Groups classes by user-defined categories (e.g., "models", "plugins").
- Convenient Registration: Optionally uses class names as default registration names, requiring only a category.
- Performance Optimisation: Caches scan results to minimise overhead.
What Can It Do?
KeyRegistry enables the following:
- Register Classes Dynamically: Use the
@KeyRegistry.register(category="category_name")decorator to register classes, with an optionalnameparameter (defaults to the class name). - Instantiate Classes by Name: Create instances of registered classes using a simple API, passing arbitrary arguments.
- Support Non-Package Directories: Works with directories lacking
__init__.py, making it flexible for various project structures. - Handle Large Projects: Efficiently scans and caches results for projects with many Python files.
- Error Handling: Provides clear error messages for missing classes, unimportable modules, or syntax errors in scanned files.
Installation
To install KeyRegistry, install it as a Python package:
pip install KeyRegistry
Requirements
- Python 3.6+
- No external dependencies
How to Use It
1. Registering Classes
Decorate your classes with @KeyRegistry.register, specifying a category and an optional name. If name is omitted, the class name is used.
Example (models/my_model.py):
from key_registry import KeyRegistry
@KeyRegistry.register(category="models") # Name defaults to "MyModel"
class MyModel:
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
Or, with a custom name:
@KeyRegistry.register(category="models", name="CustomModel")
class MyModel:
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
2. Instantiating Classes
Use the KeyRegistry.access and ModelBuilder.build methods to create instances.
Example:
from key_registry import KeyRegistry
# Access the registry for a category
model_builder = KeyRegistry.access(category="models", project_root="/path/to/your/project")
# Instantiate a model
model = model_builder.build("MyModel", param1=1, param2="value")
print(model.param1) # Output: 1
The project_root parameter defaults to the current working directory if not specified.
3. Project Structure
KeyRegistry scans all .py files in the specified project_root (recursively) for decorated classes. It works with or without __init__.py files in directories, making it flexible for various project layouts.
Example structure:
my_project/
├── models/
│ ├── my_model.py
│ ├── another_model.py
├── other_components/
│ ├── plugin.py
├── key_registry/
│ ├── __init__.py
│ ├── registry.py
├── main.py
4. Error Handling
KeyRegistry provides informative errors:
KeyError: If the requested class name or category isn’t registered.ImportError: If a module cannot be imported (e.g., due to missing files or syntax errors).- Warnings: Logged for files with syntax errors (e.g., mixed tabs and spaces).
Examples of Situations Where KeyRegistry is Needed
-
Machine Learning Projects:
- In a computer vision project with multiple models (e.g.,
AlexNet,ResNet,UNet), KeyRegistry allows you to register models in different files and instantiate them by name without manual imports. This is useful for experimenting with different architectures or adding new models without changing the main codebase. - Example: Register models in
backbones/alexnet.pyandsegmentation/unet.py, then instantiate them dynamically in a training script.
- In a computer vision project with multiple models (e.g.,
-
Plugin Systems:
- For applications with pluggable components (e.g., data processors, APIs), KeyRegistry enables developers to add new plugins by dropping Python files with decorated classes into a directory, without modifying import statements.
-
Extensible Frameworks:
- In frameworks where users contribute components (e.g., custom optimisers, loss functions), KeyRegistry simplifies integration by automatically discovering and registering user-defined classes.
-
Testing and Prototyping:
- When prototyping, KeyRegistry allows quick iteration by registering new classes in separate files, enabling dynamic instantiation for testing without hardcoding imports.
Example Usage
Example 1: Machine Learning Models
Project structure:
Computer-Vision-Models/
├── backbones/
│ ├── alexnet.py
├── segmentation/
│ ├── unet.py
├── main.py
backbones/alexnet.py:
import torch
from torch import nn
from key_registry import KeyRegistry
@KeyRegistry.register(category="models")
class AlexNet(nn.Module):
def __init__(self, in_channels, num_classes):
super().__init__()
self.in_channels = in_channels
self.num_classes = num_classes
# ... model definition ...
main.py:
from key_registry import KeyRegistry
model_builder = KeyRegistry.access(category="models")
alex_net = model_builder.build("AlexNet", in_channels=3, num_classes=1000)
print(alex_net) # Output: AlexNet(...)
Example 2: Plugin System
Register plugins in a directory and instantiate them dynamically:
from key_registry import KeyRegistry
plugin_builder = KeyRegistry.access(category="plugins", project_root="./plugins")
plugin = plugin_builder.build("MyPlugin", config="settings.yaml")
plugin.run()
Author
- Name: Le Hoang Viet
- Contact: lehoangviet2k@gmail.com
Contributing
Contributions are welcome! Please submit issues or pull requests to the GitHub repository. To contribute:
- Fork the repository.
- Create a feature branch (
git checkout -b feature/new-feature). - Commit your changes (
git commit -m "Add new feature"). - Push to the branch (
git push origin feature/new-feature). - Open a pull request.
Licence
KeyRegistry is licensed under the Apache License 2.0. See the LICENSE file for details.
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 keyregistry-0.1.0.tar.gz.
File metadata
- Download URL: keyregistry-0.1.0.tar.gz
- Upload date:
- Size: 10.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c8b1fc053cc856835cbe4732f5a31b52b0bfb1a9658eaef4aa4ab3d5b7de164
|
|
| MD5 |
19f0cba90a8d65f83d853394e5bcce64
|
|
| BLAKE2b-256 |
3ec991b35778ca3ee22b2ee724b83dab1293c0838927a92b009f711c506e02b9
|
File details
Details for the file keyregistry-0.1.0-py3-none-any.whl.
File metadata
- Download URL: keyregistry-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5bef72ee5b1715918ded4d49f9386c6eaa691c50168baac893988187c8ae9631
|
|
| MD5 |
c59983c6fd0239e7dce863657eb91977
|
|
| BLAKE2b-256 |
b0a4608c599ee5ee79e2b58c95dc6b09d3492fb1e83ba6a1c757c013df262c3a
|