How to Use Holehe Programmatically to Check Multiple Modules: A Complete Guide

You can use Holehe programmatically by importing its async core functions from holehe/core.py, which automatically discover all detection modules and run them concurrently with Trio and httpx.

Holehe is an open-source OSINT tool for email account discovery across hundreds of services. While it provides a CLI, its true power lies in the Python API exposed through holehe/core.py. This guide shows you how to embed Holehe in your own scripts to check single modules, run everything, or cherry-pick specific services.

Understanding Holehe's Async Architecture

Holehe follows a lightweight asynchronous design built around three core concepts: dynamic module discovery, consistent coroutine signatures, and Trio-based concurrency.

Module Discovery in holehe/core.py

The function import_submodules("holehe.modules") walks the entire holehe/modules/ package tree and imports every Python file. The helper get_functions() then extracts the public coroutine from each module—typically named after the service (e.g., twitter, snapchat)【/cache/repos/github.com/megadose/holehe/master/holehe/core.py#L37-L64】.

This means new modules added to the repository are automatically available without code changes.

Standardized Module Interface

Every detection module implements the same async signature:

async def service_name(email: str, client: httpx.AsyncClient, out: list) -> None:
    # Queries the service and appends result dict to `out`

The launch_module() wrapper in holehe/core.py handles exceptions and converts them to standardized result objects, ensuring uniform output regardless of individual module failures【/cache/repos/github.com/megadose/holehe/master/holehe/core.py#L66-L78】.

Concurrent Execution with Trio

A Trio nursery spawns all modules simultaneously. The TrioProgress instrument attaches to Trio's low-level instrumentation for progress tracking【/cache/repos/github.com/megadose/holehe/master/holehe/core.py#L16-L22】. Results are collected into a shared list, then sorted and processed【/cache/repos/github.com/megadose/holehe/master/holehe/core.py#L124-L131】.

Running a Single Module Manually

For targeted checks, import and call any module directly. Here's the Snapchat module in action:

import trio
import httpx
from holehe.modules.social_media.snapchat import snapchat

async def demo_one():
    email = "test@example.com"
    out = []
    client = httpx.AsyncClient()
    await snapchat(email, client, out)
    print(out)
    await client.aclose()

trio.run(demo_one)

Each module file lives under holehe/modules/ by category. For example, the Twitter check is implemented in holehe/modules/social_media/twitter.py【/cache/repos/github.com/megadose/holehe/master/holehe/modules/social_media/twitter.py#L5-L37】.

Running All Available Modules Automatically

To execute every discovered service concurrently, use Holehe's core orchestration:

import trio
import httpx
from holehe.core import import_submodules, get_functions, launch_module, TrioProgress

async def demo_all():
    email = "test@example.com"

    # 1. Discover every detection module

    modules = import_submodules("holehe.modules")
    
    # 2. Convert to list of callable coroutines

    websites = get_functions(modules)

    client = httpx.AsyncClient()
    out = []
    
    # Optional: add progress bar

    instrument = TrioProgress(len(websites))
    trio.lowlevel.add_instrument(instrument)

    # 3. Launch all modules concurrently

    async with trio.open_nursery() as nursery:
        for website in websites:
            nursery.start_soon(launch_module, website, email, client, out)

    trio.lowlevel.remove_instrument(instrument)
    await client.aclose()
    
    # Sort results alphabetically by service name

    out = sorted(out, key=lambda i: i["name"])
    print(out)

trio.run(demo_all)

This pattern is exactly how Holehe's CLI operates. The launch_module wrapper ensures failures in one module don't crash the entire run.

Selecting a Custom Subset of Modules

When you need specific services rather than everything, import modules individually and invoke them directly:

import trio
import httpx
from holehe.modules.social_media.twitter import twitter
from holehe.modules.social_media.instagram import instagram

async def demo_subset():
    email = "test@example.com"
    out = []
    client = httpx.AsyncClient()
    
    for fn in (twitter, instagram):
        await fn(email, client, out)  # sequential execution

    
    await client.aclose()
    print(out)

trio.run(demo_subset)

For concurrent execution of a subset, swap the for loop for a Trio nursery with your chosen functions.

Integrating Holehe Results into Pipelines

Each result dictionary contains standardized keys you can process programmatically:

  • name — service name (e.g., "twitter")
  • domain — service domain
  • method — detection technique used
  • frequent_rate_limit — boolean indicating rate-limit likelihood
  • exists — boolean or None for account existence
  • emailrecovery — partial recovery email if leaked
  • phoneNumber — partial phone if leaked
  • others — additional metadata

This structure makes Holehe ideal for feeding OSINT data into databases, SIEMs, or custom enrichment workflows.

Key Source Files Reference

File Purpose
holehe/core.py Orchestrates discovery, async execution, result aggregation, and CSV export
holehe/modules/*/*.py One file per service—each defines an async detection function
holehe/instruments.py TrioProgress progress-bar implementation
holehe/localuseragent.py Default User-Agent for HTTP requests

Summary

  • Single module: Import directly from holehe.modules.* and call with (email, client, out).
  • All modules: Use import_submodules() and get_functions() from holehe/core.py, then spawn with launch_module() in a Trio nursery.
  • Custom subset: Import specific modules and invoke them sequentially or concurrently.
  • Shared client: Pass one httpx.AsyncClient instance to all calls for connection reuse.
  • Consistent output: Every module appends a standardized dictionary to the out list.

Frequently Asked Questions

What Python version does Holehe require?

Holehe requires Python 3.7+ due to its reliance on Trio and httpx.AsyncClient. The async/await syntax and low-level Trio instrumentation used in holehe/core.py depend on modern Python features.

Can I run Holehe without the progress bar?

Yes. Simply omit the TrioProgress instrument creation and the add_instrument/remove_instrument calls. The core functionality in holehe/core.py works without any instrumentation—progress tracking is purely optional UI sugar.

How do I add a custom detection module to Holehe?

Create a new Python file under holehe/modules/ (in an existing or new category folder) with an async function following the signature async def yourservice(email, client, out). The next time import_submodules("holehe.modules") runs, your module will be discovered automatically.

Does Holehe handle rate limits automatically?

Individual modules set a frequent_rate_limit flag in results to warn about rate-limited services, but Holehe does not implement automatic backoff or retry logic. According to the source code in holehe/core.py, failed requests are caught by launch_module() and converted to error result objects without interrupting other modules.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →