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.builder() returns a HashManagerBuilder that lets you compose a HashManager through a fluent, chainable API. While HashManager.from_algorithms() is convenient for default-parameter setups, the builder is the right tool whenever you need to tune algorithm-specific parameters, mix pre-configured hasher instances with named algorithms, or explicitly declare which algorithm should be preferred for new hashes — all without manually constructing individual hasher objects.
Prefer HashManager.builder() over HashManager.from_algorithms() whenever you need custom algorithm parameters such as a higher Argon2 time_cost, non-default bcrypt rounds, or a specific PBKDF2 iterations count. from_algorithms() always uses library defaults.
Basic Usage
Call HashManager.builder(), chain one or more .with_algorithm() calls, then call .build() to get a fully configured HashManager.
from hash_forge import HashManager
manager = (
HashManager.builder()
.with_algorithm("argon2")
.with_algorithm("bcrypt")
.build()
)
hashed = manager.hash("password123")
print(manager.preferred_hasher.algorithm) # argon2 (first added = preferred)
Builder Methods
with_algorithm(algorithm, **kwargs)
Add an algorithm by name and pass any hasher-specific keyword arguments. The algorithm is instantiated immediately via the internal factory.
manager = (
HashManager.builder()
.with_algorithm("argon2", time_cost=4, memory_cost=65536, parallelism=2)
.with_algorithm("bcrypt", rounds=14)
.with_algorithm("pbkdf2_sha256", iterations=200_000)
.build()
)
Supported kwargs per algorithm:
| Algorithm | Parameters |
|---|
argon2 | time_cost, memory_cost, parallelism, hash_len |
bcrypt / bcrypt_sha256 | rounds |
pbkdf2_sha256 / pbkdf2_sha1 | iterations, salt_length |
scrypt | work_factor, block_size, parallelism |
with_hasher(hasher)
Add a pre-configured hasher instance directly. Use this when you need to reuse an existing hasher object or when the hasher requires constructor arguments not available through with_algorithm.
from hash_forge import HashManager
from hash_forge.hashers import PBKDF2Sha256Hasher
custom_pbkdf2 = PBKDF2Sha256Hasher(iterations=300_000, salt_length=32)
manager = (
HashManager.builder()
.with_hasher(custom_pbkdf2) # pre-configured instance
.with_algorithm("bcrypt", rounds=12)
.with_algorithm("argon2")
.build()
)
with_preferred(algorithm)
Override which algorithm is used for new hashes. Without this call, the first algorithm added becomes the preferred one. The algorithm passed to with_preferred() must already be present in the builder.
manager = (
HashManager.builder()
.with_algorithm("pbkdf2_sha256")
.with_algorithm("argon2")
.with_algorithm("bcrypt")
.with_preferred("argon2") # override: argon2 used for new hashes
.build()
)
print(manager.preferred_hasher.algorithm) # argon2
build()
Validates the builder state and returns a configured HashManager. Raises ValueError if no hashers were added, or if with_preferred() was called with an algorithm that was not added to the builder.
manager = (
HashManager.builder()
.with_algorithm("argon2", time_cost=4)
.with_algorithm("bcrypt", rounds=14)
.with_preferred("argon2")
.build()
)
Migration Setup
Use the builder to create a manager that hashes new passwords with Argon2 while still being able to verify legacy PBKDF2 and bcrypt hashes stored in your database.
from hash_forge import HashManager
migration_manager = (
HashManager.builder()
.with_algorithm("argon2") # new hashes use this
.with_algorithm("pbkdf2_sha256") # can verify old PBKDF2 hashes
.with_algorithm("bcrypt") # can verify old bcrypt hashes
.with_preferred("argon2") # explicitly prefer Argon2
.build()
)
# New registrations get Argon2
new_hash = migration_manager.hash("new_user_password")
# Legacy PBKDF2 hash still verifiable
is_valid, new_hash = migration_manager.verify_and_update(
"old_user_password",
legacy_pbkdf2_hash,
)
if new_hash:
save_to_db(new_hash) # transparently upgraded to Argon2
Web Application Setup
A typical web application configuration with a high-security primary algorithm and a legacy fallback:
from hash_forge import HashManager
web_app_manager = (
HashManager.builder()
.with_algorithm("argon2", time_cost=3, memory_cost=65536) # primary
.with_algorithm("bcrypt", rounds=12) # legacy fallback
.with_preferred("argon2")
.build()
)
# Register a new user
user_hash = web_app_manager.hash("WebAppSecurePass123!")
print(f"Registered with: {web_app_manager.preferred_hasher.algorithm}") # argon2
# Verify on login
is_valid = web_app_manager.verify("WebAppSecurePass123!", user_hash)
print(f"Login successful: {is_valid}") # True
Error Handling
The builder validates its state at .build() time and raises ValueError in two cases:
No hashers added:
try:
empty_manager = HashManager.builder().build()
except ValueError as e:
print(e)
# At least one hasher must be added to the builder
Preferred algorithm not in the builder:
try:
invalid_manager = (
HashManager.builder()
.with_algorithm("bcrypt")
.with_preferred("argon2") # argon2 was never added!
.build()
)
except ValueError as e:
print(e)
# Preferred algorithm 'argon2' was not added to the builder