Tool to consolidate python functions with multiple versions into a single access point, search by a specific version or custom search with metadata.
Project description
Function Registry
Function Registry is a Python library designed to help consolidate functions and their respective versions into a centralized catalog. Whether you’re working on a single project or need a distributable library, Function Registry provides:
- A ready-to-use
FunctionRegistryclass. - An abstract base class (
AbstractFunctionRegistry) for custom implementations.
Installation
Requirements
- Python 3.8 or higher
- pip, pipenv, or poetry
Install with pip
pip install function_registry
Install from source
git clone https://github.com/sgg10/function-registry.git
cd function-registry
pip install -e .
Quick Start
Basic Example
Here’s how to get started with the FunctionRegistry class:
from function_registry import FunctionRegistry
# Create a new function catalog
registry = FunctionRegistry()
# Save a function versions
@registry.save_version("add", version=1)
def add(a, b):
return a + b
@registry.save_version("add", version=2)
def add(*nums):
return sum(nums)
# Retrieve the saved function versions
print(registry.get_version("add", version=1)["function"](2, 3)) # 5
print(registry.get_version("add", version=2)["function"](2, 3, 4)) # 9
Features and Examples
1. Using sequential or semantic versioning
You can use sequential or semantic versioning for any function, but you must keep the same type of versioning for the same function, otherwise you will get an exception.
Example: you cannot have @registry.save_version(“add”, version=1) and then @registry.save_version(“add”, version=“1.1.0”).
@registry.save_version("add", version=1)
def add(a, b):
return a + b
@registry.save_version("add", version=2)
def add(*nums):
return sum(nums)
@registry.save_version("div", version="1.0.0")
def div(a, b):
return a / b
@registry.save_version("div", version="1.0.1")
def div(a, b):
try:
return a / b
except ZeroDivisionError:
return "Cannot divide by zero"
print(registry.get_version("add", version=1)["function"](2, 3)) # 5
print(registry.get_version("add", version=2)["function"](2, 3, 4)) # 9
print(registry.get_version("div", version="1.0.0")["function"](10, 2)) # 5.0
print(registry.get_version("div", version="1.0.1")["function"](10, 0)) # "Cannot divide by zero"
2. Using Metadata
Attach custom metadata to functions for advanced search capabilities.
from function_registry import FunctionRegistry
# Create a new function catalog
registry = FunctionRegistry()
@registry.save_version("metadata_func", version=1, metadata={"author": "John Doe"})
def metadata_func():
return "Metadata Example"
versioned_func = registry.get_version("metadata_func", version=1)
print(versioned_func["metadata"]["author"]) # Output: John Doe
3. Custom version search
You can create a custom search function to filter versions based on custom criteria.
For example, you can search for the latest version of a function that was created by a specific author.
from function_registry import FunctionRegistry
from function_registry.types import FR_VERSION_DICT_TYPE
AUTHOR = "John Doe"
# Create a new function catalog
registry = FunctionRegistry()
@registry.save_version("add", version=1, metadata={"author": "John Doe"})
def add(a, b):
return a + b
@registry.save_version("add", version=2, metadata={"author": "Jane Doe"})
def add(*nums):
return sum(nums)
@registry.save_version("add", version=3, metadata={"author": "John Doe"})
def add(*nums):
print(f"Adding {len(nums)} numbers")
return sum(nums)
def custom_search(versions: FR_VERSION_DICT_TYPE):
filtered_versions = {k: v for k, v in versions.items() if v["metadata"]["author"] == AUTHOR}
return max(filtered_versions.keys(), key=lambda v: v)
latest_version = registry.get_version("add", custom_search_function=custom_search)
print(latest_version["metadata"]["author"]) # Output: John Doe
print(latest_version["metadata"]["version"]) # Output: 3
print(latest_version["function"](2, 3, 4)) # Output: 9
4. Custom Function Registry Implementation
Leverage the AbstractFunctionRegistry base class to build your own registry.
from function_registry import AbstractFunctionRegistry
class CustomRegistry(AbstractFunctionRegistry):
def __init__(self):
self._functions = {}
def save_version(self, function_name, version=None, metadata=None):
# Custom implementation here
pass
def get_version(self, function_name, version=None, custom_search_function=None):
# Custom implementation here
pass
def extend(self):
# Custom implementation here
pass
# Example usage
custom_registry = CustomRegistry()
5. Extend Function Registry with other Registries
You can extend the FunctionRegistry class with other registries to combine their functions.
from function_registry import FunctionRegistry
catalog_1 = FunctionRegistry()
catalog_2 = FunctionRegistry()
# Save functions to catalog_1
@catalog_1.save_version("add", version=1)
def add(a, b):
return a + b
# Save functions to catalog_2
@catalog_2.save_version("sub", version=1)
def sub(a, b):
return a - b
# Extend catalog_1 with catalog_2
catalog_1.extend(catalog_2)
print(catalog_1.get_version("add", version=1)["function"](2, 3)) # 5
print(catalog_1.get_version("sub", version=1)["function"](5, 3)) # 2
6. Flexible Function Duplication Strategies
Extend registries with strategies like
- KEEP_EXISTING: Keep the existing function version and ignore the new one.
- OVERWRITE: Overwrite the existing function version with the new one.
- RAISE: Raise an exception if a function version already exists.
- MERGE_WITH_EXISTING_PRIORITY: Merge the existing and new function versions, giving priority to the existing version if one version of the function already exists.
- MERGE_WITH_NEW_PRIORITY: Merge the existing and new function versions, giving priority to the new version if one version of the function already exists.
from function_registry import FunctionRegistry
from function_registry.enums import EXTEND_DUPLICATED_STRATEGIES
catalog_1 = FunctionRegistry()
catalog_2 = FunctionRegistry()
# Save functions to catalog_1
@catalog_1.save_version("add", version=1)
def add(a, b):
return a + b
# Save functions to catalog_2
@catalog_2.save_version("add", version=1)
def add(a, b):
return a + b + 100
# Extend catalog_1 with catalog_2
catalog_1.extend(catalog_2, EXTEND_DUPLICATED_STRATEGIES.OVERWRITE)
# Call the function from catalog_1
print(catalog_1.get_version("add", version=1)["function"](1, 2)) # Output: 103
Testing
To run the unit tests, execute the following command from the project root directory:
python -m unittest discover tests
The test cases ensure the library's robustness by covering:
- Function version registration.
- Metadata handling.
- Custom search functions.
- Error handling (e.g., duplicate versions, missing versions).
Contributing
All contributions to improve Function Registry are welcome! To contribute, follow these steps:
- Fork the repository.
git clone https://github.com/sgg10/function-registry.git
cd function-registry
- Create a new branch for your changes:
git checkout -b feature/new-feature
- Make changes and test them locally.
- Submit a pull request: Open a pull request describing your changes.
For bug reports or feature requests, please visit the issues page.
License
This project is licensed under the MIT License. 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 function_registry-1.0.0.tar.gz.
File metadata
- Download URL: function_registry-1.0.0.tar.gz
- Upload date:
- Size: 12.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.9.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
135f1b28a3802612dda89eb6ebb023b363010c3d92db029b4b1f5bdb70dc58e1
|
|
| MD5 |
3d2b5f503b5e29dd45ea1590a905b690
|
|
| BLAKE2b-256 |
a2cf985903c6cc86e1a84589fc481932802d085073a36dff4c9e7b5486403769
|
File details
Details for the file function_registry-1.0.0-py3-none-any.whl.
File metadata
- Download URL: function_registry-1.0.0-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.9.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
667d2cd5dd046abfdb10949344eb65f71ffb683234fc95c87c8b5102b9099065
|
|
| MD5 |
88c87573dcfe5e9447b1183955f43d61
|
|
| BLAKE2b-256 |
055e42bc1bb7c2e443dc3100301e55eb0cad65c239f704b0e3e682791fd76148
|