How to Use holehe as a Python API: Programmatic OSINT Integration
You can use holehe as a Python API by importing functions from holehe.core and holehe.modules to programmatically execute the same 200+ site checks that the CLI performs, receiving structured JSON-like results without spawning subprocesses.
The megadose/holehe repository is an open-source email OSINT (Open Source Intelligence) tool designed to identify account registration across hundreds of websites. While the command-line interface is the most common entry point, the codebase is structured as a Python package that allows you to use holehe as a Python API, embedding its reconnaissance engine directly into your own scripts, data pipelines, or security automation workflows.
Core Architecture for API Usage
The library separates concerns between module discovery, HTTP client management, and execution orchestration. Understanding these layers is essential for stable programmatic integration.
Module Discovery via holehe.core
According to the source code in [holehe/core.py](https://github.com/megadose/holehe/blob/master/holehe/core.py), the package exposes three critical functions for API usage:
import_submodules(package)– Dynamically walks theholehe.modulespackage tree and imports every site-specific check function.get_functions(modules, args=None)– Filters the imported modules to extract only the callable check functions, returning a list of coroutines ready for execution.launch_module(module, email, client, out)– An async wrapper that executes a single site check, handles exceptions gracefully, and appends a standardized result dictionary to your output list.
The Async HTTP Client
Every module in holehe.modules expects an httpx.AsyncClient instance as its second argument. The client handles all network I/O, and you should instantiate it once with your desired timeout configuration, then pass it to all concurrent checks. The library uses httpx rather than requests to support high-concurrency async patterns.
Step-by-Step API Implementation
To use holehe as a Python API, follow this workflow based on the CLI implementation in holehe/core.py:
-
Import all site modules using
import_submodules("holehe.modules")to load the 200+ site checkers. -
Extract check functions via
get_functions(modules)to obtain a list of callable coroutines. -
Initialize the HTTP client with
httpx.AsyncClient(timeout=10)(or your preferred timeout). -
Execute checks concurrently using an async nursery (the example below uses
trio) orasyncio.gather, callinglaunch_modulefor each site function. -
Collect standardized results from the mutable
outlist passed tolaunch_module, which will contain dictionaries with keys includingname,domain,exists,emailrecovery, andrateLimit.
Complete Working Example
Below is a self-contained implementation that demonstrates how to query an email address against all supported platforms programmatically:
import asyncio
import httpx
import trio
from holehe.core import import_submodules, get_functions, launch_module
from holehe.instruments import TrioProgress
async def check_email_osint(email: str, timeout: int = 10):
"""
Run holehe checks against *email* using the Python API.
Returns a list of result dictionaries.
"""
# 1️⃣ Load all site modules from holehe.modules
modules = import_submodules("holehe.modules")
# 2️⃣ Extract the callable site functions
websites = get_functions(modules)
# 3️⃣ Prepare the async HTTP client
client = httpx.AsyncClient(timeout=timeout)
# 4️⃣ Container for results
out = []
# 5️⃣ Optional: Add progress instrumentation
instrument = TrioProgress(len(websites))
trio.lowlevel.add_instrument(instrument)
# 6️⃣ Execute all checks concurrently
async with trio.open_nursery() as nursery:
for site_fn in websites:
nursery.start_soon(launch_module, site_fn, email, client, out)
# 7️⃣ Cleanup
trio.lowlevel.remove_instrument(instrument)
await client.aclose()
# 8️⃣ Return sorted results
return sorted(out, key=lambda x: x["name"])
# ----------------------------------------------------------------------
# Example usage
if __name__ == "__main__":
target_email = "alice@example.com"
results = trio.run(check_email_osint, target_email)
# Display results
for site in results:
status = "[+]" if site["exists"] else "[-]"
print(f"{status} {site['domain']}: Account exists = {site['exists']}")
Understanding the Result Structure
Each entry in the returned list is a standardized dictionary defined in the site modules (e.g., [holehe/modules/social_media/twitter.py](https://github.com/megadose/holehe/blob/master/holehe/modules/social_media/twitter.py)):
{
"name": "twitter",
"domain": "twitter.com",
"exists": True,
"emailrecovery": None,
"phoneNumber": None,
"rateLimit": False,
"error": False,
"others": {"FullName": "Alice Smith"}
}
exists: Boolean indicating whether the email is registered on the platform.emailrecovery: Partial email address if the site exposes recovery information.phoneNumber: Partial phone number if exposed by the service.rateLimit: True if the module detected throttling or blocking.others: Dictionary containing additional metadata scraped by the module (e.g., full name, profile URL).
Key Source Files for API Developers
| File | Purpose | API Relevance |
|---|---|---|
holehe/core.py |
Defines import_submodules, get_functions, and launch_module; contains the main async driver logic. |
Core API entry points |
holehe/modules/__init__.py |
Package initialization that enables dynamic module loading. | Required for discovery |
holehe/instruments.py |
Provides TrioProgress for real-time progress tracking. |
Optional UI enhancement |
holehe/localuseragent.py |
Supplies randomized User-Agent strings via ua variable. |
Useful for custom HTTP clients |
Summary
holehe.coreexposes the essential functions (import_submodules,get_functions,launch_module) needed to use holehe as a Python API.- The API requires an
httpx.AsyncClientand async execution context (trioorasyncio) to run the 200+ built-in site checks concurrently. - Results are returned as standardized dictionaries containing
exists,emailrecovery,phoneNumber, andrateLimitfields. - You can integrate the library without CLI dependencies by importing directly from the package structure defined in
megadose/holehe.
Frequently Asked Questions
Do I need to install the CLI to use the holehe Python API?
No. Once you install holehe via pip install holehe, you can import holehe.core and holehe.modules directly in your Python scripts. The CLI in holehe/core.py is simply a wrapper around these same API functions that parses command-line arguments.
Can I run checks against specific websites only instead of all modules?
Yes. While get_functions(modules) returns all available site checkers by default, you can filter the returned list before execution. Each function object has a __module__ attribute containing the site name (e.g., "holehe.modules.social_media.twitter"), allowing you to whitelist or blacklist specific platforms programmatically.
How does the API handle rate limiting and timeouts?
Each site module sets rateLimit to True in the result dictionary when it detects throttling (HTTP 429 or similar). The httpx.AsyncClient passed to launch_module controls the timeout; if a request exceeds this limit, the exception is caught and recorded in the error field without crashing the entire batch.
Is the holehe Python API compatible with standard asyncio?
Yes. While the provided example uses trio for concurrency (matching the CLI's default behavior), the underlying site check functions are standard async coroutines. You can replace the trio.open_nursery() pattern with asyncio.gather() or asyncio.TaskGroup if you prefer using asyncio for your event loop.
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 →