.. image:: https://raw.githubusercontent.com/BrianPugh/autoregistry/main/assets/logo_400w.png
|Python compat| |PyPi| |GHA tests| |Codecov report| |readthedocs|
.. inclusion-marker-do-not-remove
AutoRegistry
============
Invoking functions and class-constructors from a string is a common design pattern
that AutoRegistry aims to solve.
For example, a user might specify a backend of type ``"sqlite"`` in a yaml configuration
file, for which our program needs to construct the ``SQLite`` subclass of our ``Database`` class.
Classically, you would need to manually create a lookup, mapping the string ``"sqlite"`` to
the ``SQLite`` constructor.
With AutoRegistry, the lookup is automatically created for you.
AutoRegistry has a single powerful class ``Registry`` that can do the following:
* Be inherited to automatically register subclasses by their name.
* Be directly invoked ``my_registry = Registry()`` to create a decorator
for registering callables like functions.
* Traverse and automatically create registries for other python libraries.
.. inclusion-marker-remove
AutoRegistry is also highly configurable, with features like name-schema-enforcement and name-conversion-rules.
`Checkout the docs for more information <https://autoregistry.readthedocs.io/en/latest/?badge=latest/>`_.
`Watch AutoRegistry in action! <https://youtu.be/4No_NE7bUOM>`_
Installation
============
AutoRegistry requires Python ``>=3.8``.
.. code-block:: bash
python -m pip install autoregistry
Examples
========
Class Inheritance
^^^^^^^^^^^^^^^^^
``Registry`` adds a dictionary-like interface to class constructors
for looking up subclasses.
.. code-block:: python
from abc import abstractmethod
from dataclasses import dataclass
from autoregistry import Registry
@dataclass
class Pokemon(Registry):
level: int
hp: int
@abstractmethod
def attack(self, target):
"""Attack another Pokemon."""
class Charmander(Pokemon):
def attack(self, target):
return 1
class Pikachu(Pokemon):
def attack(self, target):
return 2
class SurfingPikachu(Pikachu):
def attack(self, target):
return 3
print(f"{len(Pokemon)} Pokemon types registered:")
print(f" {list(Pokemon)}")
# By default, lookup is case-insensitive
charmander = Pokemon["cHaRmAnDer"](level=7, hp=31)
print(f"Created Pokemon: {charmander}")
This code block produces the following output:
.. code-block::
3 Pokemon types registered:
['charmander', 'pikachu', 'surfingpikachu']
Created Pokemon: Charmander(level=7, hp=31)
Function Registry
^^^^^^^^^^^^^^^^^
Directly instantiating a ``Registry`` object allows you to
register functions by decorating them.
.. code-block:: python
from autoregistry import Registry
pokeballs = Registry()
@pokeballs
def masterball(target):
return 1.0
@pokeballs
def pokeball(target):
return 0.1
for ball in ["pokeball", "masterball"]:
success_rate = pokeballs[ball](None)
print(f"Ash used {ball} and had {success_rate=}")
This code block produces the following output:
.. code-block:: text
Ash used pokeball and had success_rate=0.1
Ash used masterball and had success_rate=1.0
Module Registry
^^^^^^^^^^^^^^^
Create a registry for another python module.
.. code-block:: python
import torch
from autoregistry import Registry
optims = Registry(torch.optim)
# "adamw" and ``lr`` could be coming from a configuration file.
optimizer = optims["adamw"](model.parameters(), lr=3e-3)
assert list(optims) == [
"asgd",
"adadelta",
"adagrad",
"adam",
"adamw",
"adamax",
"lbfgs",
"nadam",
"optimizer",
"radam",
"rmsprop",
"rprop",
"sgd",
"sparseadam",
"lr_scheduler",
"swa_utils",
]
.. |GHA tests| image:: https://github.com/BrianPugh/autoregistry/workflows/tests/badge.svg
:target: https://github.com/BrianPugh/autoregistry/actions?query=workflow%3Atests
:alt: GHA Status
.. |Codecov report| image:: https://codecov.io/github/BrianPugh/autoregistry/coverage.svg?branch=main
:target: https://codecov.io/github/BrianPugh/autoregistry?branch=main
:alt: Coverage
.. |readthedocs| image:: https://readthedocs.org/projects/autoregistry/badge/?version=latest
:target: https://autoregistry.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. |Python compat| image:: https://img.shields.io/badge/>=python-3.8-blue.svg
.. |PyPi| image:: https://img.shields.io/pypi/v/autoregistry.svg
:target: https://pypi.python.org/pypi/autoregistry
Raw data
{
"_id": null,
"home_page": "https://github.com/BrianPugh/autoregistry",
"name": "autoregistry",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "",
"author": "Brian Pugh",
"author_email": "",
"download_url": "https://files.pythonhosted.org/packages/5a/8d/f1f61295090add147b0f98e6d8506ab719543477abd65e755e9fea416782/autoregistry-1.1.1.tar.gz",
"platform": null,
"description": ".. image:: https://raw.githubusercontent.com/BrianPugh/autoregistry/main/assets/logo_400w.png\n\n|Python compat| |PyPi| |GHA tests| |Codecov report| |readthedocs|\n\n.. inclusion-marker-do-not-remove\n\nAutoRegistry\n============\n\nInvoking functions and class-constructors from a string is a common design pattern\nthat AutoRegistry aims to solve.\nFor example, a user might specify a backend of type ``\"sqlite\"`` in a yaml configuration\nfile, for which our program needs to construct the ``SQLite`` subclass of our ``Database`` class.\nClassically, you would need to manually create a lookup, mapping the string ``\"sqlite\"`` to\nthe ``SQLite`` constructor.\nWith AutoRegistry, the lookup is automatically created for you.\n\n\nAutoRegistry has a single powerful class ``Registry`` that can do the following:\n\n* Be inherited to automatically register subclasses by their name.\n\n* Be directly invoked ``my_registry = Registry()`` to create a decorator\n for registering callables like functions.\n\n* Traverse and automatically create registries for other python libraries.\n\n.. inclusion-marker-remove\n\nAutoRegistry is also highly configurable, with features like name-schema-enforcement and name-conversion-rules.\n`Checkout the docs for more information <https://autoregistry.readthedocs.io/en/latest/?badge=latest/>`_.\n\n`Watch AutoRegistry in action! <https://youtu.be/4No_NE7bUOM>`_\n\nInstallation\n============\nAutoRegistry requires Python ``>=3.8``.\n\n.. code-block:: bash\n\n python -m pip install autoregistry\n\n\nExamples\n========\n\nClass Inheritance\n^^^^^^^^^^^^^^^^^\n\n``Registry`` adds a dictionary-like interface to class constructors\nfor looking up subclasses.\n\n.. code-block:: python\n\n from abc import abstractmethod\n from dataclasses import dataclass\n from autoregistry import Registry\n\n\n @dataclass\n class Pokemon(Registry):\n level: int\n hp: int\n\n @abstractmethod\n def attack(self, target):\n \"\"\"Attack another Pokemon.\"\"\"\n\n\n class Charmander(Pokemon):\n def attack(self, target):\n return 1\n\n\n class Pikachu(Pokemon):\n def attack(self, target):\n return 2\n\n\n class SurfingPikachu(Pikachu):\n def attack(self, target):\n return 3\n\n\n print(f\"{len(Pokemon)} Pokemon types registered:\")\n print(f\" {list(Pokemon)}\")\n # By default, lookup is case-insensitive\n charmander = Pokemon[\"cHaRmAnDer\"](level=7, hp=31)\n print(f\"Created Pokemon: {charmander}\")\n\nThis code block produces the following output:\n\n.. code-block::\n\n 3 Pokemon types registered:\n ['charmander', 'pikachu', 'surfingpikachu']\n Created Pokemon: Charmander(level=7, hp=31)\n\n\nFunction Registry\n^^^^^^^^^^^^^^^^^\n\nDirectly instantiating a ``Registry`` object allows you to\nregister functions by decorating them.\n\n.. code-block:: python\n\n from autoregistry import Registry\n\n pokeballs = Registry()\n\n\n @pokeballs\n def masterball(target):\n return 1.0\n\n\n @pokeballs\n def pokeball(target):\n return 0.1\n\n\n for ball in [\"pokeball\", \"masterball\"]:\n success_rate = pokeballs[ball](None)\n print(f\"Ash used {ball} and had {success_rate=}\")\n\nThis code block produces the following output:\n\n.. code-block:: text\n\n Ash used pokeball and had success_rate=0.1\n Ash used masterball and had success_rate=1.0\n\n\nModule Registry\n^^^^^^^^^^^^^^^\n\nCreate a registry for another python module.\n\n.. code-block:: python\n\n import torch\n from autoregistry import Registry\n\n optims = Registry(torch.optim)\n\n # \"adamw\" and ``lr`` could be coming from a configuration file.\n optimizer = optims[\"adamw\"](model.parameters(), lr=3e-3)\n\n assert list(optims) == [\n \"asgd\",\n \"adadelta\",\n \"adagrad\",\n \"adam\",\n \"adamw\",\n \"adamax\",\n \"lbfgs\",\n \"nadam\",\n \"optimizer\",\n \"radam\",\n \"rmsprop\",\n \"rprop\",\n \"sgd\",\n \"sparseadam\",\n \"lr_scheduler\",\n \"swa_utils\",\n ]\n\n\n.. |GHA tests| image:: https://github.com/BrianPugh/autoregistry/workflows/tests/badge.svg\n :target: https://github.com/BrianPugh/autoregistry/actions?query=workflow%3Atests\n :alt: GHA Status\n.. |Codecov report| image:: https://codecov.io/github/BrianPugh/autoregistry/coverage.svg?branch=main\n :target: https://codecov.io/github/BrianPugh/autoregistry?branch=main\n :alt: Coverage\n.. |readthedocs| image:: https://readthedocs.org/projects/autoregistry/badge/?version=latest\n :target: https://autoregistry.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n.. |Python compat| image:: https://img.shields.io/badge/>=python-3.8-blue.svg\n.. |PyPi| image:: https://img.shields.io/pypi/v/autoregistry.svg\n :target: https://pypi.python.org/pypi/autoregistry\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "Automatic registry design-pattern for mapping names to functionality.",
"version": "1.1.1",
"project_urls": {
"Homepage": "https://github.com/BrianPugh/autoregistry",
"Repository": "https://github.com/BrianPugh/autoregistry"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d969764e05ebe148c6f103428c633cea863ede91aa18dbd177cb8696ee768933",
"md5": "fa065655d2893243b8628cf2946bd445",
"sha256": "2efb7ff26edd941736a004061aa8e7a519f4611b000b77d4233d412e51ab58c9"
},
"downloads": -1,
"filename": "autoregistry-1.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "fa065655d2893243b8628cf2946bd445",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 14051,
"upload_time": "2023-10-31T19:21:35",
"upload_time_iso_8601": "2023-10-31T19:21:35.409150Z",
"url": "https://files.pythonhosted.org/packages/d9/69/764e05ebe148c6f103428c633cea863ede91aa18dbd177cb8696ee768933/autoregistry-1.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "5a8df1f61295090add147b0f98e6d8506ab719543477abd65e755e9fea416782",
"md5": "7de1c0fcd0a581d62c9cf52ca6f1ae62",
"sha256": "2ad9850d74e1a88c154c43c81469684472d84623d3b4903b8e4b5fc0365d1ba4"
},
"downloads": -1,
"filename": "autoregistry-1.1.1.tar.gz",
"has_sig": false,
"md5_digest": "7de1c0fcd0a581d62c9cf52ca6f1ae62",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 14851,
"upload_time": "2023-10-31T19:21:36",
"upload_time_iso_8601": "2023-10-31T19:21:36.919232Z",
"url": "https://files.pythonhosted.org/packages/5a/8d/f1f61295090add147b0f98e6d8506ab719543477abd65e755e9fea416782/autoregistry-1.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-31 19:21:36",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "BrianPugh",
"github_project": "autoregistry",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "autoregistry"
}