# `passlib.registry` - Password Handler Registry

This module contains the code Passlib uses to track all password hash handlers that it knows about. While custom handlers can be used directly within an application, or even handed to a `CryptContext`; it is frequently useful to register them globally within a process and then refer to them by name. This module provides facilities for that, as well as programmatically querying Passlib to detect what algorithms are available.

Warning

This module is primarily used as an internal support module. Its interface has not been finalized yet, and may be changed somewhat between major releases of Passlib, as the internal code is cleaned up and simplified.

Applications should access hashes through the `passlib.hash` module where possible (new ones may also be registered by writing to that module).

## Interface

passlib.registry.get_crypt_handler(name[, default])

  return handler for specified password hash scheme.

  this method looks up a handler for the specified scheme. if the handler is not already loaded, it checks if the location is known, and loads it first.

  Parameters:

    - name – name of handler to return

    - default – optional default value to return if no handler with specified name is found.

  Raises:

    KeyError – if no handler matching that name is found, and no default specified, a KeyError will be raised.

  Returns:

    handler attached to name, or default value (if specified).

passlib.registry.list_crypt_handlers(loaded_only=False)

  return sorted list of all known crypt handler names.

  Parameters:

    loaded_only – if `True`, only returns names of handlers which have actually been loaded.

  Returns:

    list of names of all known handlers

passlib.registry.register_crypt_handler_path(name, path)

  register location to lazy-load handler when requested.

  custom hashes may be registered via `register_crypt_handler()`, or they may be registered by this function, which will delay actually importing and loading the handler until a call to `get_crypt_handler()` is made for the specified name.

  Parameters:

    - name – name of handler

    - path – module import path

  the specified module path should contain a password hash handler called `name`, or the path may contain a colon, specifying the module and module attribute to use. for example, the following would cause `get_handler("myhash")` to look for a class named `myhash` within the `myapp.helpers` module:

      >>> from passlib.registry import registry_crypt_handler_path
      >>> registry_crypt_handler_path("myhash", "myapp.helpers")

  …while this form would cause `get_handler("myhash")` to look for a class name `MyHash` within the `myapp.helpers` module:

      >>> from passlib.registry import registry_crypt_handler_path
      >>> registry_crypt_handler_path("myhash", "myapp.helpers:MyHash")

passlib.registry.register_crypt_handler(handler, force=False)

  register password hash handler.

  this method immediately registers a handler with the internal passlib registry, so that it will be returned by `get_crypt_handler()` when requested.

  Parameters:

    - handler – the password hash handler to register

    - force – force override of existing handler (defaults to False)

    - _attr – [internal kwd] if specified, ensures `handler.name` matches this value, or raises `ValueError`.

  Raises:

    - TypeError – if the specified object does not appear to be a valid handler.

    - ValueError – if the specified object’s name (or other required attributes) contain invalid values.

    - KeyError – if a (different) handler was already registered with the same name, and `force=True` was not specified.

Note

All password hashes registered with passlib can be imported by name from the `passlib.hash` module. This is true not just of the built-in hashes, but for any hash registered with the registration functions in this module.

## Usage

Example showing how to use `registry_crypt_handler_path()`:

    >>> # register the location of a handler without loading it
    >>> from passlib.registry import register_crypt_handler_path
    >>> register_crypt_handler_path("myhash", "myapp.support.hashes")

    >>> # even before being loaded, its name will show up as available
    >>> from passlib.registry import list_crypt_handlers
    >>> 'myhash' in list_crypt_handlers()
    True
    >>> 'myhash' in list_crypt_handlers(loaded_only=True)
    False

    >>> # when the name "myhash" is next referenced,
    >>> # the class "myhash" will be imported from the module "myapp.support.hashes"
    >>> from passlib.context import CryptContext
    >>> cc = CryptContext(schemes=["myhash"]) #<-- this will cause autoimport

Example showing how to load a hash by name:

    >>> from passlib.registry import get_crypt_handler
    >>> get_crypt_handler("sha512_crypt")
    <class 'passlib.handlers.sha2_crypt.sha512_crypt'>

    >>> get_crypt_handler("missing_hash")
    KeyError: "no crypt handler found for algorithm: 'missing_hash'"

    >>> get_crypt_handler("missing_hash", None)
    None