# What Libraries Does Holehe Use for Asynchronous HTTP Requests?

> Discover Holehe's async HTTP request libraries. Learn how it leverages httpx and trio for efficient, concurrent execution in your projects.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: internals
- Published: 2026-08-17

---

**Holehe uses the `httpx` library for asynchronous HTTP requests and `trio` as the underlying async runtime to manage concurrent execution.**

Holehe is an open-source OSINT tool by megadose that checks whether an email address is registered on hundreds of websites. To perform these checks rapidly without blocking, the codebase relies on modern Python async primitives. Specifically, [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) instantiates a shared `httpx.AsyncClient`, while [`holehe/instruments.py`](https://github.com/megadose/holehe/blob/main/holehe/instruments.py) leverages `trio` to schedule parallel requests across multiple services.

## The HTTP Client: httpx

Holehe delegates all network I/O to **httpx**, a fully featured HTTP client that supports synchronous and asynchronous APIs. In [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), the tool creates a single `httpx.AsyncClient` instance that persists for the entire execution lifecycle.

This client configuration includes a **30-second timeout** to prevent hung connections from stalling the scan. By reusing one client across all modules, Holehe benefits from HTTP connection pooling and keep-alive optimizations, significantly reducing latency when querying hundreds of endpoints.

The AsyncClient is injected into every service-specific module. For example, functions like `github()` in [`holehe/modules/programing/github.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/programing/github.py) and `spotify()` in [`holehe/modules/music/spotify.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/music/spotify.py) accept the client as a parameter, allowing them to issue non-blocking `await client.get()` or `await client.post()` calls.

```python
import httpx

# Configuration as implemented in holehe/core.py

timeout = httpx.Timeout(30.0)

async with httpx.AsyncClient(timeout=timeout) as client:
    # Client is passed to each module for reuse

    from holehe.modules.programing.github import github
    await github(email, client, out=[])

```

## The Async Runtime: trio

While `httpx` handles the protocol layer, **trio** provides the event loop and structured concurrency primitives. According to the source code in [`holehe/instruments.py`](https://github.com/megadose/holehe/blob/main/holehe/instruments.py), trio is imported to manage task groups and nursery scopes that supervise concurrent execution.

Trio's "structured concurrency" model ensures that if one service check fails or raises an exception, the entire operation cancels cleanly without leaking background tasks. This is critical for Holehe's reliability when scanning unpredictable third-party APIs.

The entry point in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) uses `trio.run()` to bootstrap the async workflow, passing the main coroutine into trio's event loop.

## How httpx and trio Work Together

The architecture follows a simple but effective pattern: trio schedules the tasks, and httpx executes the network calls within those tasks. This combination allows Holehe to query dozens of services simultaneously without multithreading overhead.

Here is the complete pattern as implemented in the codebase:

```python
import httpx
import trio

async def run_checks(email: str):
    # 30-second timeout for all requests

    timeout = httpx.Timeout(30.0)

    # One shared async client for the whole run

    async with httpx.AsyncClient(timeout=timeout) as client:
        # Example: check if the email is registered on GitHub

        from holehe.modules.programing.github import github
        await github(email, client, out=[])

        # Example: check if the email appears on Spotify

        from holehe.modules.music.spotify import spotify
        await spotify(email, client, out=[])

# Execute the coroutine with trio's event loop

trio.run(run_checks, "alice@example.com")

```

**Key implementation details:**

- **`httpx.AsyncClient`** – Created in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) with a 30-second timeout, enabling persistent connections and HTTP/2 support where available.
- **Shared client injection** – Each module in `holehe/modules/*` receives the client instance, ensuring consistent header handling and connection reuse.
- **`trio.run()`** – Called at the application entry point to initialize the event loop and execute the top-level coroutine.
- **Dependency declaration** – Both libraries are listed as runtime requirements in [`setup.py`](https://github.com/megadose/holehe/blob/main/setup.py), ensuring they are installed via pip when deploying Holehe.

## Summary

- Holehe relies on `httpx` for all asynchronous HTTP requests, specifically utilizing `httpx.AsyncClient` configured with a 30-second timeout in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py).
- The async runtime is powered by `trio`, which is imported in [`holehe/instruments.py`](https://github.com/megadose/holehe/blob/main/holehe/instruments.py) to provide structured concurrency and task management.
- Individual service modules (e.g., [`github.py`](https://github.com/megadose/holehe/blob/main/github.py), [`spotify.py`](https://github.com/megadose/holehe/blob/main/spotify.py)) receive the shared AsyncClient as a function argument, allowing concurrent non-blocking network calls.
- This dual-library approach allows Holehe to check hundreds of services in parallel while maintaining clean error handling and resource management.

## Frequently Asked Questions

### Why does Holehe use httpx instead of aiohttp?

Holehe uses `httpx` because it provides a modern, Requests-compatible API with full async support and HTTP/2 capabilities. The `httpx.AsyncClient` offers robust connection pooling and timeout handling that aligns with Holehe's needs for reliable, high-concurrency OSINT scanning. While `aiohttp` is an alternative, the maintainers chose `httpx` for its standardized API and superior testing utilities.

### What role does trio play in Holehe's architecture?

Trio acts as the asynchronous runtime and event loop. According to [`holehe/instruments.py`](https://github.com/megadose/holehe/blob/main/holehe/instruments.py), trio manages the structured concurrency through nurseries and task groups, ensuring that if one service check crashes or hangs, all related tasks cancel properly. This prevents resource leaks and zombie connections when scanning unreliable third-party endpoints.

### Can I use asyncio instead of trio with Holehe?

No, Holehe is specifically designed around trio's structured concurrency primitives. The code in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) and [`holehe/instruments.py`](https://github.com/megadose/holehe/blob/main/holehe/instruments.py) imports `trio` directly and uses `trio.run()` as the entry point. While `httpx` itself supports both `asyncio` and `trio`, Holehe's internal task management and synchronization logic depend on trio's unique cancellation semantics.

### How is the HTTP client configured for timeouts?

In [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), the `httpx.AsyncClient` is instantiated with `httpx.Timeout(30.0)` to set a global 30-second timeout for all requests. This timeout applies to connection establishment, request sending, and response reading, protecting the tool from slow or unresponsive services during bulk email verification tasks.