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.

AsyncHashMixin is a mixin class that HashManager inherits from, giving every HashManager instance a full suite of async hashing methods. Because password hashing algorithms like Argon2, bcrypt, and PBKDF2 are intentionally CPU-intensive, running them directly in an async event loop would block other coroutines. AsyncHashMixin solves this by offloading each synchronous operation to Python’s default thread-pool executor via asyncio.get_running_loop().run_in_executor(None, ...), keeping the event loop free.
You do not import or instantiate AsyncHashMixin directly. All HashManager instances already have these methods available — simply await them from any async context.
import asyncio
from hash_forge import HashManager

manager = HashManager.from_algorithms("argon2")

async def main():
    hashed = await manager.hash_async("my_password")
    valid = await manager.verify_async("my_password", hashed)
    print(valid)  # True

asyncio.run(main())

Methods

hash_async

async def hash_async(self, string: str) -> str
Asynchronously hashes a string using the preferred_hasher by running the synchronous hash() method in a thread-pool executor.
string
str
required
The plaintext string to hash.
Returns: str — the hashed string, identical to what hash() would produce.
hashed = await manager.hash_async("correct-horse-battery-staple")

verify_async

async def verify_async(self, string: str, hashed_string: str) -> bool
Asynchronously verifies a plaintext string against a hash by running the synchronous verify() method in a thread-pool executor. Algorithm routing behaves identically to the synchronous version.
string
str
required
The plaintext string to verify.
hashed_string
str
required
The stored hash to compare against.
Returns: boolTrue if the string matches the hash, False otherwise.
is_valid = await manager.verify_async("correct-horse-battery-staple", hashed)

needs_rehash_async

async def needs_rehash_async(self, hashed_string: str) -> bool
Asynchronously checks whether a hash needs to be replaced by running the synchronous needs_rehash() method in a thread-pool executor.
hashed_string
str
required
The stored hash to evaluate.
Returns: boolTrue if the hash should be regenerated.
if await manager.needs_rehash_async(stored_hash):
    stored_hash = await manager.hash_async(plaintext)

hash_many_async

async def hash_many_async(self, strings: list[str]) -> list[str]
Hashes multiple strings concurrently by scheduling individual hash_async calls as tasks and awaiting them together with asyncio.gather. The output list preserves the same order as the input list.
strings
list[str]
required
A list of plaintext strings to hash.
Returns: list[str] — hashed strings in the same order as the input.
passwords = ["password1", "password2", "password3"]
hashes = await manager.hash_many_async(passwords)
For bulk user registration or batch migration tasks, hash_many_async can significantly reduce wall-clock time compared to hashing sequentially — especially when parallelism is set on Argon2 or when multiple CPU cores are available.

verify_many_async

async def verify_many_async(self, pairs: list[tuple[str, str]]) -> list[bool]
Verifies multiple plaintext/hash pairs concurrently using asyncio.gather. Each pair is verified independently and the results are returned in the same order as the input.
pairs
list[tuple[str, str]]
required
A list of (plaintext, hashed_string) tuples to verify.
Returns: list[bool] — verification results in the same order as the input.
pairs = [
    ("password1", hash1),
    ("password2", hash2),
    ("password3", hash3),
]
results = await manager.verify_many_async(pairs)
# [True, False, True]

Concurrency Model

All five methods delegate to asyncio.get_running_loop().run_in_executor(None, ...), which submits work to Python’s default ThreadPoolExecutor. This means:
  • The event loop is never blocked — other coroutines continue to run while hashing is in progress.
  • Hashing work is distributed across OS threads, providing true concurrency for I/O-bound async applications.
  • The default executor uses min(32, os.cpu_count() + 4) threads (Python 3.8+). For workloads with very high parallelism, supply a custom executor to the event loop via loop.set_default_executor.
Python’s Global Interpreter Lock (GIL) limits true CPU parallelism for pure-Python code, but most cryptographic hashers (Argon2, bcrypt, scrypt) release the GIL during their C-extension work, so thread-pool concurrency is effective in practice.

Build docs developers (and LLMs) love