Skip to main content

Everything you need to implement maintainable and easy to use registry patterns in your project.

Project description

Registerer

pypi ci codecov license

Implement maintainable and easy to use registry patterns in your project.

TLDR; Write this:

import registerer

command_handler_registry = registerer.Registerer()


@command_handler_registry.register()
def hello(args):
    return "hello to you too"


@command_handler_registry.register()
def info(args):
    return "how can i help you?"


@command_handler_registry.register()
def play(args):
    return "let me play a song for you"


command = "info"
args = {}
assert command_handler_registry[command](args) == "how can i help you?"

Instead of this, which violates the Open-Closed Principle (OCP):

def hello2(args):
    return "hello to you too"


def info2(args):
    return "how can i help you?"


def play2(args):
    return "let me play a song for you"


def command_handler(command, args):
    if command == "hello":
        return hello2(args)
    if command == "info":
        return info2(args)
    if command == "play":
        return play2(args)


command = "info"
args = {}
assert command_handler(command, args) == "how can i help you?"

Installation

pip install registerer

Usage

In order to use registerer, you need to instantiate from the registerer.Registerer.

There is several optional arguments you can pass to the Registerer constructor to manage how registry object should behave (Read more in reference section).

let's create a registry:

import abc
import typing


class Animal(abc.ABC):
    slug: str
    is_wild: bool

    def walk(self):
        pass


# Animal class registry
animal_registry = registerer.Registerer(
    parent_class=Animal,
    max_size=5,  # only 5 items can register
    slug_attr="slug",  # set the slug of item as attribute on it
    validators=[
        registerer.RegistryValidator(
            lambda item: item.is_wild is False,  # check passed if returns True
            error="can't register wild animal.",
        ),
    ],
)

Now with animal_registry you can register your classes:

# use the name of class as unique identifier:
@animal_registry.register()
class Sheep(Animal):
    is_wild = False

    def walk(self):
        return "sheep walks"


# use your custom slug as unique identifier:
@animal_registry.register("kitty")
class Cat(Animal):
    is_wild = False

    def walk(self):
        return "cat walks"


assert animal_registry["Sheep"] == Sheep
assert animal_registry["kitty"] == Cat

assert animal_registry.items == [Sheep, Cat]
assert animal_registry._registry_dict == {"Sheep": Sheep, "kitty": Cat}

assert animal_registry["Sheep"]().walk() == "sheep walks"
assert animal_registry["kitty"]().walk() == "cat walks"

The register method will also set an attribute on the registered item as registry_slug. You can change the attribute name when creating the Registerer object. So, in last example we have:

assert Cat.slug == "kitty"
assert animal_registry["kitty"].slug == "kitty"

if you need to add attributes on the registered item on registration (it's optional), you can pass kwargs to the register method.
This is useful when registering functions. for example:

# function registry
test_database_registry = registerer.Registerer(
    validators=[
        registerer.RegistryValidator(
            lambda item: item.db_type == "test",
        ),
    ]
)

# use the name of function as unique identifier:
@test_database_registry.register(db_type="test")
def sqlite(name: str):
    return f"sqlite connection {name}"


# use your custom slug as unique identifier:
@test_database_registry.register("postgresql", db_type="test")
def postgresql_test(name: str):
    return f"postgresql connection {name}"


assert test_database_registry["sqlite"]("quera") == f"sqlite connection quera"
assert test_database_registry["postgresql"]("quera") == f"postgresql connection quera"

Exceptions

module registerer.exceptions


class RegistryCreationError

Errors that occurs on creating a registry object.


class RegistrationError

Errors that occurs on registering new item.


class ItemNotRegistered

You've tried to get a item that is not registered.

Reference

Here is all the things you can do with the Registerer class:

class Registerer

A utility that can be used to create a registry object to register class or functions.

method Registerer.__init__

__init__(
    parent_class: Optional[Type[~T]] = None,
    slug_attr: Optional[str] = None,
    max_size: Optional[int] = None,
    validators: Optional[List[registerer.validators.RegistryValidator]] = None
)

Args:

  • parent_class: The class of parent. If you set this, the registered class should be subclass of the this, If it's not the register method going to raise RegistrationError. Also by setting this you'll be benefit from type hints in your IDE.
  • slug_attr: Pass the attribute name of registered item that you want to set registry slug to or read from registered item.
  • max_size: allowed size of registered items. Defaults to None which means there is no limit.
  • validators: custom validation for on registering items.

Raises:

  • RegistryCreationError: Can't create proper registry object.

property Registerer.items

get actual registered items as list (classes or functions)


method Registerer.is_registered

is_registered(slug: str)  bool

is the slug registered?


method Registerer.register

register(custom_slug: Optional[str] = None, **kwargs)

register a class or item to the registry

example:

# register the item with it's name
@registry.register()
class Foo:
     pass

assert registry["Foo"] == Foo


# register the item with a custom name
@registry.register("bar")
class Bar:
     pass

assert registry["bar"] == Bar


# register the item with a custom name and also add some other attributes to it.
# it is more useful when registering functions.
@db_registry.register("postgresql", env="prod")
def postgresql_connection:
     pass

assert registry["postgresql"] == postgresql_connection
assert postgresql_connection.env == "prod"

Args:

  • custom_slug (str): the unique identifier for the item.

Raises:

  • ItemAlreadyRegistered: There is another item already registered with this slug.
  • RegistrationError: can't register this item.

method Registerer.validate

validate(item: Type[~T])

validate the item during registration.

Args:

  • item (T): item want to register.

Raises:

  • RegistrationError: can't register this item.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

registerer-0.5.0.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

registerer-0.5.0-py3-none-any.whl (7.2 kB view details)

Uploaded Python 3

File details

Details for the file registerer-0.5.0.tar.gz.

File metadata

  • Download URL: registerer-0.5.0.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.2.1 CPython/3.10.8 Linux/6.0.2-arch1-1

File hashes

Hashes for registerer-0.5.0.tar.gz
Algorithm Hash digest
SHA256 0463e46ce80ec3d94ccc634a050323b6898d02cbcb133a41fdd11b27e769aadf
MD5 470f8263c881193f88d9041b5586ae44
BLAKE2b-256 19db39ea0f4bdade9ca8346461a21f4dd48b30c2ea4b3745ba2b5abe84205d91

See more details on using hashes here.

File details

Details for the file registerer-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: registerer-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 7.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.2.1 CPython/3.10.8 Linux/6.0.2-arch1-1

File hashes

Hashes for registerer-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c542e9d065db987b80b6fd6fd7d1ae3f5883e34f13e7d127e7eeef9ee7093a4e
MD5 8e4a3d0b21c7a014fdf4da47ce9a7dfc
BLAKE2b-256 191db9f3439e40ee2c08490bd17d793e03e4a40b60123a0d385b092c4f789a99

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page