autoregistry


Nameautoregistry JSON
Version 1.1.1 PyPI version JSON
download
home_pagehttps://github.com/BrianPugh/autoregistry
SummaryAutomatic registry design-pattern for mapping names to functionality.
upload_time2023-10-31 19:21:36
maintainer
docs_urlNone
authorBrian Pugh
requires_python>=3.8
licenseApache-2.0
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. 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"
}
        
Elapsed time: 0.20567s