# How to Integrate Holehe as a Python Library: Complete Developer Guide

> Integrate Holehe as a Python library to build advanced security tools. Learn how to import core functions, manage clients, and run service coroutines efficiently.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: how-to-guide
- Published: 2026-08-25

---

**You can integrate Holehe as a Python library by importing the core discovery functions from `holehe.core`, instantiating an `httpx.AsyncClient`, and executing service coroutines concurrently through `trio.open_nursery()`.**

Holehe is an open-source OSINT tool that verifies email address registrations across hundreds of websites and services. While it provides a command-line interface, the megadose/holehe repository is architected as a modular Python package that allows you to integrate Holehe as a Python library within your own async applications. The library leverages `trio` for structured concurrency and `httpx` for HTTP transport, returning standardized result dictionaries for each platform check.

## Architecture Overview

### Core Engine and Module Discovery

The library’s entry point resides in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), which exposes two critical helper functions for programmatic use. The `import_submodules()` function (lines 37-47) dynamically walks the `holehe.modules` package to load every available service module. Subsequently, `get_functions()` (lines 50-63) filters these loaded modules into a list of callable coroutines that implement the email-lookup API. This design allows the engine to automatically discover new services as they are added to the `holehe/modules/` directory without requiring manual registration.

### Service Module Interface

Each individual service module (e.g., [`holehe/modules/social_media/snapchat.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/snapchat.py)) exports a single async coroutine following the strict signature `async def <service_name>(email, client, out)`. The `email` parameter receives the target string, `client` is a shared `httpx.AsyncClient` instance for connection pooling, and `out` is a mutable list where the coroutine appends a standardized dictionary containing keys like `name`, `domain`, `exists`, `emailrecovery`, and `phoneNumber`. All I/O is asynchronous, ensuring efficient concurrent execution across hundreds of services.

## Installation and Prerequisites

Add Holehe to your project dependencies via pip:

```bash
pip install holehe

```

For development or to pin a specific version, install directly from the megadose/holehe repository:

```bash
git clone https://github.com/megadose/holehe.git
cd holehe && pip install .

```

The library requires `trio` and `httpx` as core dependencies. If you intend to embed Holehe within an existing `asyncio` codebase, you will also need `trio-asyncio` as detailed in the compatibility section below.

## Running the Full Email Scan Suite

To execute a complete check across all available modules, use the discovery helpers followed by a `trio` nursery for concurrency. The following example demonstrates the canonical integration pattern:

```python
import trio
import httpx
from holehe.core import import_submodules, get_functions, print_result

async def scan_email(email: str):
    # Discover all modules under holehe.modules

    modules = import_submodules("holehe.modules")
    websites = get_functions(modules)
    
    # Initialize async HTTP client with appropriate timeout

    client = httpx.AsyncClient(timeout=10)
    out = []
    
    # Execute all checks concurrently

    async with trio.open_nursery() as nursery:
        for site in websites:
            nursery.start_soon(site, email, client, out)
    
    await client.aclose()
    
    # Display results using Holehe's built-in formatter

    class Args:
        nocolor = False
        noclear = True
        onlyused = False
    
    print_result(out, Args(), email, start_time=0, websites=websites)

# Run the scan

trio.run(scan_email, "target@example.com")

```

This approach loads every module found in the `holehe/modules` directory, aggregates the callable functions, and runs them simultaneously. The mutable `out` list collects results from all coroutines, preserving the order of completion.

## Targeting Individual Services

For applications requiring only specific platforms (e.g., to reduce network traffic or execution time), import and call individual modules directly:

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

async def check_single_service(email: str):
    client = httpx.AsyncClient(timeout=10)
    results = []
    await snapchat(email, client, results)
    await client.aclose()
    
    # results contains: [{'name': 'snapchat', 'domain': 'snapchat.com', 'exists': True, ...}]

    return results

trio.run(check_single_service, "user@example.com")

```

Selective importing bypasses the discovery overhead of `import_submodules()` and gives you fine-grained control over which services to query.

## Asyncio Compatibility

Although Holehe is built on `trio`, you can embed it within `asyncio` applications using the `trio_asyncio` bridge. Install the compatibility layer (`pip install trio-asyncio`) and open a trio loop inside your async function:

```python
import asyncio
import trio_asyncio
import httpx
from holehe.modules.social_media.twitter import twitter

async def asyncio_wrapper(email: str):
    async with trio_asyncio.open_loop():
        client = httpx.AsyncClient(timeout=10)
        out = []
        await twitter(email, client, out)
        await client.aclose()
        return out

# Run within existing asyncio event loop

results = asyncio.run(asyncio_wrapper("test@example.com"))

```

This pattern allows you to integrate Holehe into legacy `asyncio` codebases or frameworks like FastAPI or Sanic without migrating your entire application to `trio`.

## Exporting Results Programmatically

Holehe provides utility functions for formatting and exporting results. To generate a CSV file instead of console output, use the `export_csv` function from `holehe.core`:

```python
from holehe.core import export_csv

# Assuming 'out' contains results from a scan

class CsvConfig:
    csvoutput = True

export_csv(out, CsvConfig(), email="user@example.com")

# Creates: holehe_<timestamp>_user@example.com_results.csv

```

The CSV export function handles timestamping and file naming conventions automatically, writing the standardized result dictionaries to disk with appropriate headers.

## Summary

- **Import discovery helpers** from [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) (`import_submodules`, `get_functions`) to dynamically load service modules or import specific modules directly for targeted checks.
- **Use `httpx.AsyncClient`** for connection pooling and pass it along with a mutable results list to each service coroutine.
- **Execute via `trio`** using `trio.open_nursery()` for true concurrency across hundreds of services.
- **Bridge to `asyncio`** using `trio_asyncio` when integrating into existing asyncio applications.
- **Consume standardized dictionaries** containing `name`, `domain`, `exists`, and optional recovery data to drive downstream logic.

## Frequently Asked Questions

### Can I run Holehe inside an existing asyncio application without migrating to trio?

Yes, you can integrate Holehe as a Python library within `asyncio` codebases by using the `trio-asyncio` compatibility package. Wrap the Holehe execution in an `async with trio_asyncio.open_loop()` context manager to spawn a trio event loop inside your asyncio routine.

### How do I limit the scan to specific websites instead of running all modules?

Instead of calling `import_submodules` and `get_functions`, directly import the specific modules you need from the `holehe.modules` package (e.g., `from holehe.modules.social_media.snapchat import snapchat`). Pass the coroutine directly to the nursery or await it individually with your `httpx.AsyncClient` and results list.

### What data structure does each service return?

Each service appends a standardized dictionary to the shared `out` list with keys including `name` (service identifier), `domain` (service domain), `exists` (boolean indicating if the email is registered), `emailrecovery` (partial recovery email if exposed), and `phoneNumber` (partial phone if exposed). The schema is consistent across all modules in the megadose/holehe repository.

### Where is the CLI entry point defined if I want to wrap or extend it?

The command-line interface is implemented as a thin wrapper in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) (lines 32-34). It parses arguments and invokes `trio.run(maincore)`. You can import `maincore` or the helper functions directly to build custom CLI tools that leverage the same underlying engine without shelling out to the command line.