Holehe Module Signature: Standard Async Interface for Email Osint Modules
Holehe modules follow a strict three-argument async signature: async def module_name(email, client, out) where email is the target address, client is an httpx.AsyncClient instance, and out is a mutable list for result dictionaries.
Holehe is an open-source email osint (open source intelligence) tool by megadose that checks whether an email address is registered on hundreds of platforms. Its modular architecture depends on a uniform callable interface that every service-specific module must implement. Understanding this Holehe module signature is essential for contributors building new modules or developers integrating Holehe into their own pipelines.
The Standard Three-Argument Signature
Every Holehe module is implemented as an asynchronous function with exactly three positional parameters. This contract is enforced by the core engine in holehe/core.py when it discovers and invokes modules.
async def <module_name>(email, client, out):
Parameter Breakdown
| Parameter | Type | Purpose |
|---|---|---|
str |
The target email address to verify on the service | |
| client | httpx.AsyncClient |
Async HTTP client for making web requests without blocking |
| out | list |
Mutable result container; modules append their findings as dictionaries |
This signature appears identically across all modules, from holehe/modules/transport/blablacar.py to holehe/modules/software/office365.py. The core orchestrator relies on this consistency to load modules dynamically and execute them concurrently.
Required Result Dictionary Structure
Modules append a standardized dictionary to the out list. According to the source code in existing modules like blablacar.py, this dictionary must contain these keys:
name— Internal module identifier (typically matching the function name)domain— Domain being probed (e.g.,blablacar.com,office365.com)method— Interaction type:"register","login", or"other"frequent_rate_limit—boolindicating if the service aggressively rate-limitsrateLimit—Trueif the current request was throttledexists—boolindicating whether the email is registered on the service
Optional fields provide additional osint data:
emailrecovery— Secondary email recovered from the servicephoneNumber— Phone number associated with the accountothers— Service-specific metadata as a dictionary
Implementing and Calling a Holehe Module
Direct Module Invocation
You can import and call individual modules directly when testing or building selective checks:
import asyncio
import httpx
from holehe.modules.transport.blablacar import blablacar
async def check_blablacar(email: str) -> dict:
async with httpx.AsyncClient() as client:
out = []
await blablacar(email, client, out)
return out[0] # Single result dict for this service
result = asyncio.run(check_blablacar("example@example.com"))
print(result)
This pattern mirrors exactly how the core engine invokes modules, passing the same three arguments.
Full Scanner Integration
The run_modules function in holehe/core.py iterates all registered modules using this signature:
import asyncio
import httpx
from holehe.core import run_modules # Core orchestrator
async def scan_email(email: str):
async with httpx.AsyncClient() as client:
results = await run_modules(email, client) # Calls each module with (email, client, out)
for r in results:
print(f"{r['name']}: exists={r['exists']}")
asyncio.run(scan_email("example@example.com"))
The core loader discovers modules via holehe/modules/__init__.py, then instantiates each with the standard email, client, out signature.
Key Source Files Defining the Contract
| File | Role in Module Signature |
|---|---|
holehe/core.py |
Implements run_modules() that enforces the three-argument call pattern |
holehe/modules/__init__.py |
Registers all modules for dynamic discovery |
holehe/modules/transport/blablacar.py |
Reference implementation showing proper signature usage |
holehe/modules/software/office365.py |
Alternative module demonstrating the same interface |
holehe/localuseragent.py |
Supplies ua dictionary for User-Agent rotation in requests |
These files collectively establish the Holehe module signature as a rigid contract. Any deviation prevents proper integration with the core engine.
Summary
- Holehe module signature requires exactly three arguments:
email,client, andout - All modules must be async functions to enable non-blocking concurrent execution
- Results are appended to
outas dictionaries with mandatory keys:name,domain,method,frequent_rate_limit,rateLimit, andexists - The core engine in
holehe/core.pydepends on this uniformity for module discovery and orchestration - Reference implementations in
blablacar.pyandoffice365.pydemonstrate proper adherence to the contract
Frequently Asked Questions
What happens if a Holehe module doesn't follow the standard signature?
The core engine in holehe/core.py will fail to invoke the module correctly. Modules are called with positional arguments (email, client, out), so any deviation in parameter count or order causes a TypeError. The module discovery mechanism in holehe/modules/__init__.py assumes all registered functions conform to this interface.
Can I use a different HTTP client instead of httpx.AsyncClient?
No. The client parameter is always an httpx.AsyncClient instance passed by the core engine. Modules rely on its specific API (get, post, headers manipulation). Replacing it would break compatibility with existing modules and the core runner.
Is the out list strictly necessary, or can modules return values directly?
The out list is mandatory. Holehe's concurrent execution model uses mutable containers to collect results from multiple async tasks. Modules must append their result dictionary to out rather than returning values, as shown in blablacar.py and all other reference implementations.
Which key in the result dictionary indicates successful account discovery?
The exists boolean determines whether the email is registered. A value of True confirms the account exists on the service; False means unregistered or indeterminate. This is the primary output consumers check when aggregating Holehe results across multiple services.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →