Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Zozi96/hash-forge/llms.txt

Use this file to discover all available pages before exploring further.

HashManager is the central orchestrator for all hashing operations in Hash Forge. It holds an ordered collection of hasher instances, routes verification requests to the correct hasher automatically, and optionally enforces a PasswordHashPolicy. Import it directly from the top-level package:
from hash_forge import HashManager

Constructor

HashManager(*hashers: PHasher)
Accepts one or more hasher instances. The first hasher supplied becomes the preferred_hasher and is used for all new hashes. Hashers are stored in insertion order so that verify and needs_rehash can route to the appropriate algorithm by inspecting the hash string prefix.
hashers
PHasher
required
One or more hasher instances that conform to the PHasher protocol. At least one must be provided.
Constructing a HashManager with no arguments raises InvalidHasherError. Always pass at least one hasher, or use one of the factory classmethods below.

Factory Classmethods

from_algorithms

@classmethod
def from_algorithms(cls, *algorithms: AlgorithmType, **kwargs: Any) -> HashManager
Creates a HashManager by name — Hash Forge instantiates the underlying hashers for you via the internal HasherFactory. The first algorithm in the list becomes the preferred hasher. Any **kwargs are forwarded to every hasher constructor.
algorithms
AlgorithmType
required
One or more algorithm identifier strings, e.g. "argon2", "pbkdf2_sha256". See AlgorithmType for all valid values.
**kwargs
Any
Additional keyword arguments forwarded to each hasher’s constructor — useful for quick one-algorithm managers. For per-algorithm control, use from_config or the builder.
from hash_forge import HashManager

manager = HashManager.from_algorithms("argon2", "pbkdf2_sha256", "bcrypt")
Raises UnsupportedAlgorithmError if any algorithm string is not recognised by the factory.

from_config

@classmethod
def from_config(cls, config: HashForgeConfig, *algorithms: AlgorithmType) -> HashManager
Creates a HashManager from a HashForgeConfig object. Each algorithm’s constructor parameters are pulled from the config automatically via config.get_hasher_config(algorithm).
config
HashForgeConfig
required
A HashForgeConfig instance loaded from environment variables, a JSON file, or a dict.
algorithms
AlgorithmType
required
Algorithm identifiers to instantiate. Ordering determines the preferred hasher.
from hash_forge import HashManager
from hash_forge.config.config_loader import HashForgeConfig

config = HashForgeConfig.from_env()
manager = HashManager.from_config(config, "pbkdf2_sha256", "bcrypt")

from_policy

@classmethod
def from_policy(cls, policy: PasswordHashPolicy) -> HashManager
Creates a HashManager whose algorithm set, constructor options, and enforcement rules are all driven by a PasswordHashPolicy. The policy is attached to the manager instance and is consulted during hash, verify, and needs_rehash calls.
policy
PasswordHashPolicy
required
A PasswordHashPolicy instance. The policy’s preferred_algorithm becomes the manager’s preferred hasher; remaining algorithms are registered for verification and migration.
from hash_forge import HashManager, PasswordHashPolicy

policy = PasswordHashPolicy.recommended()
manager = HashManager.from_policy(policy)

quick_hash (static method)

@staticmethod
def quick_hash(string: str, algorithm: AlgorithmType = "pbkdf2_sha256", **kwargs: Any) -> str
One-shot convenience method. Creates a temporary hasher, hashes the string, and returns the result — no persistent HashManager instance is created.
string
str
required
The plaintext string to hash.
algorithm
AlgorithmType
Algorithm to use. Defaults to "pbkdf2_sha256".
**kwargs
Any
Additional arguments forwarded to the hasher constructor (e.g. iterations=300000).
from hash_forge import HashManager

hashed = HashManager.quick_hash("my_password", algorithm="argon2", time_cost=4)
quick_hash is ideal for scripts or one-off tasks. For production applications that hash many strings, create a persistent HashManager once to avoid repeated hasher instantiation overhead.

builder (static method)

@staticmethod
def builder() -> HashManagerBuilder
Returns a new HashManagerBuilder instance for fluent, chainable configuration.
from hash_forge import HashManager

manager = (
    HashManager.builder()
    .with_algorithm("argon2", time_cost=4)
    .with_algorithm("bcrypt", rounds=14)
    .with_preferred("argon2")
    .build()
)

Instance Methods

hash

def hash(self, string: str) -> str
Hashes string using the preferred_hasher. If a PasswordHashPolicy is attached, validate_for_hashing is called first and will raise ValueError for unsafe algorithm choices (e.g. bare digest algorithms or deprecated ones).
string
str
required
The plaintext string to hash.
Returns: str — the hashed string produced by the preferred hasher.
hashed = manager.hash("correct-horse-battery-staple")

verify

def verify(self, string: str, hashed_string: str) -> bool
Verifies a plaintext string against a hash by automatically routing to the correct hasher. The routing uses the hash’s prefix/token to look up the matching registered hasher — no manual algorithm selection is required.
string
str
required
The plaintext string to verify.
hashed_string
str
required
The previously produced hash to compare against.
Returns: boolTrue if the string matches the hash, False otherwise. Returns False (never raises) when no registered hasher can handle the hash format.
is_valid = manager.verify("correct-horse-battery-staple", hashed)
If a PasswordHashPolicy is active and it disallows verification of the hash’s algorithm (e.g. allow_legacy_verify=False), verify returns False rather than raising an exception.

needs_rehash

def needs_rehash(self, hashed_string: str) -> bool
Returns True when the hash should be replaced with a fresh one. A rehash is needed when:
  • The algorithm’s parameters (e.g. iteration count) have changed since the hash was created.
  • No registered hasher recognises the hash (treated as unknown/unsafe).
  • A PasswordHashPolicy is attached and its needs_update check determines the hash is outdated (e.g. the hash was produced by a non-preferred algorithm).
hashed_string
str
required
The hash to evaluate.
Returns: bool
if manager.needs_rehash(stored_hash):
    stored_hash = manager.hash(plaintext)

rotate

def rotate(self, string: str, old_hash: str) -> str | None
Verifies string against old_hash and, if successful, immediately re-hashes it with the preferred_hasher. This is the recommended way to migrate hashes to a new algorithm during a login flow.
string
str
required
The plaintext string to verify and re-hash.
old_hash
str
required
The existing hash to verify against.
Returns: str | None — the new hash produced by the preferred hasher, or None if verification failed.
new_hash = manager.rotate(plaintext, old_hash)
if new_hash is not None:
    # Persist new_hash to the database
    ...

verify_and_update

def verify_and_update(self, string: str, hashed_string: str) -> tuple[bool, str | None]
Combines verification with an optional rehash in a single call. Useful in login handlers where you want to update stale hashes transparently.
string
str
required
The plaintext string to verify.
hashed_string
str
required
The stored hash to verify against.
Returns: tuple[bool, str | None]
PositionTypeMeaning
[0]boolTrue if verification passed
[1]str | NoneNew hash if a rehash was needed; None if not needed or verification failed
valid, new_hash = manager.verify_and_update(plaintext, stored_hash)
if valid and new_hash is not None:
    # Save the upgraded hash
    save_hash(new_hash)

inspect

def inspect(self, hashed_string: str) -> dict[str, Any] | None
Returns metadata about a hashed string without revealing the raw hash value. Useful for auditing stored hashes or diagnosing algorithm drift.
hashed_string
str
required
The hash string to inspect.
Returns: dict[str, Any] | None — a dictionary containing at minimum:
KeyTypeDescription
"algorithm"strCanonical algorithm name
"category"strOne of "password", "legacy", "digest", "deprecated"
"deprecated"boolTrue if the algorithm is deprecated
Algorithm-specific parameters (e.g. iterations, rounds, time_cost) are included when the hasher exposes a _parse_hash method. Returns None if no registered hasher recognises the hash.
info = manager.inspect(stored_hash)
# {'algorithm': 'argon2', 'category': 'password', 'deprecated': False, 'time_cost': 3, ...}

list_algorithms

def list_algorithms(self) -> list[str]
Returns the algorithm identifier strings of all registered hashers in insertion order. Returns: list[str]
manager.list_algorithms()
# ['argon2', 'pbkdf2_sha256', 'bcrypt']

Attributes

AttributeTypeDescription
preferred_hasherPHasherThe hasher used for all new hashes (first registered).
hasherstuple[tuple[str, PHasher], ...]Ordered tuple of (algorithm_name, hasher) pairs in insertion order.
hasher_mapdict[str, PHasher]Dictionary mapping algorithm names to hashers for O(1) lookup.
policyPasswordHashPolicy | NoneThe active policy, if one was set via from_policy. None by default.

Async Methods

HashManager inherits AsyncHashMixin, which adds hash_async, verify_async, needs_rehash_async, hash_many_async, and verify_many_async for use in asyncio applications. See the AsyncHashMixin reference for details.

Build docs developers (and LLMs) love