# Purpose of `holehe/core.py`: The Central Orchestrator of Email OSINT Probing

> Discover the purpose of holehe/core.py, the central orchestrator for email OSINT probing. Learn how it handles CLI parsing, module discovery, async execution, and result formatting.

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

---

**[`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) serves as the central orchestrator of the holehe project, handling CLI parsing, dynamic module discovery, asynchronous HTTP execution, and formatted result output for email-to-service correlation checks.**

This file acts as the heart of megadose/holehe — a popular open-source OSINT tool that determines which websites are associated with a given email address. Rather than containing site-specific logic, [`core.py`](https://github.com/megadose/holehe/blob/main/core.py) coordinates all infrastructure: it loads dozens of service modules, runs them concurrently, and presents findings in color-coded tables or CSV exports.

## Core Responsibilities of [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py)

The 100+ line module consolidates seven distinct responsibilities that transform a single email input into a comprehensive cross-service footprint report.

### Command-Line Interface and Argument Parsing

Between lines 80-96, [`core.py`](https://github.com/megadose/holehe/blob/main/core.py) configures `argparse` to handle user input:

```python

# Parsed options include:

# --only-used      Filter to show only registered accounts

# --no-color       Disable terminal color output

# --csv            Export results to timestamped CSV

# --timeout        Set HTTP request timeout (default: 10s)

```

These flags directly shape execution behavior downstream, from network policy to output formatting.

### Version Checking and Self-Update

Lines 65-87 implement automatic version synchronization against PyPI. When `check_update()` detects that the local `__version__` lags behind the published release, it executes `pip install --upgrade holehe` (or the Windows-equivalent command) and exits with a restart prompt.

This ensures users consistently run the latest service modules without manual intervention.

### Dynamic Module Discovery and Loading

Rather than hardcoding supported sites, [`core.py`](https://github.com/megadose/holehe/blob/main/core.py) introspects the package structure using two key utilities at lines 37-48 and 50-63:

- **`import_submodules("holehe.modules")`** — Recursively discovers all Python files in the modules directory
- **`get_functions(modules, args)`** — Converts each module into an executable lookup function

This architecture enables contributors to add new services by simply dropping a `.py` file into `holehe/modules/` — no registry edits required.

### Asynchronous Execution with Trio

The networking layer (lines 13-14, 18-21, 24-30) leverages **Trio** for structured concurrency:

```python
async with httpx.AsyncClient(timeout=args.timeout) as client:
    async with trio.open_nursery() as nursery:
        for module in websites:
            nursery.start_soon(launch_module, module, email, client, out)

```

Each site probe runs in its own task, allowing 50+ services to be queried in seconds rather than minutes. The `TrioProgress` instrument (defined in [`holehe/instruments.py`](https://github.com/megadose/holehe/blob/main/holehe/instruments.py)) provides real-time progress feedback.

### Result Collection and Pretty Printing

Lines 22-49 aggregate module responses into a unified list sorted by service name. The `print_result()` function then renders a terminal table with four status categories:

| Status | Meaning |
|--------|---------|
| **used** | Email found in account database |
| **not used** | Email explicitly rejected or absent |
| **rate-limited** | Service temporarily blocked the request |
| **error** | Network or parsing failure |

Color coding (respecting `--no-color`) provides immediate visual triage of results.

### Optional CSV Export

When `--csv` is supplied (lines 54-64), `export_csv()` writes the complete result set to a timestamped file before program termination. This supports integration with spreadsheet workflows and archival audit trails.

### Clean Entry Point

Lines 32-34 expose a minimal `main()` function that bridges synchronous CLI entry with async execution:

```python
def main():
    trio.run(maincore)

```

This pattern allows [`setup.py`](https://github.com/megadose/holehe/blob/main/setup.py) to register `holehe` as a console script while keeping all IO-bound operations async.

## Usage Examples

### Running from Command Line

```bash
holehe alice@example.com --csv --no-color --timeout 15

```

**What happens:**
- Email and flags parsed via `argparse`
- All modules discovered via `import_submodules`
- Concurrent probes executed via Trio nursery
- Plain-text table printed to stdout
- Results saved to `holehe_results_20240115_143022.csv`

### Programmatic Integration

```python
import asyncio
import holehe.core as hc

class Args:
    onlyused = False
    nocolor = True
    noclear = True
    nopasswordrecovery = False
    csvoutput = False
    timeout = 10

email = "bob@example.com"

async def run_check():
    modules = hc.import_submodules("holehe.modules")
    websites = hc.get_functions(modules, Args)
    
    async with httpx.AsyncClient(timeout=Args.timeout) as client:
        out = []
        for site in websites:
            await hc.launch_module(site, email, client, out)
        hc.print_result(out, Args, email, start_time=0, websites=websites)

asyncio.run(run_check())

```

This reproduces `maincore()`'s workflow for embedding holehe into larger Python applications.

### Triggering Self-Update

```python
import holehe.core as hc

hc.check_update()  # Exits with pip upgrade if version mismatch detected

```

## Related Architecture Files

| File | Role |
|------|------|
| [`holehe/localuseragent.py`](https://github.com/megadose/holehe/blob/main/holehe/localuseragent.py) | Rotates random User-Agent strings per request |
| [`holehe/instruments.py`](https://github.com/megadose/holehe/blob/main/holehe/instruments.py) | Implements `TrioProgress` progress-bar integration |
| `holehe/modules/*` | Site-specific lookup implementations (Facebook, GitHub, etc.) |

## Summary

- **[`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py)** is the single entry point and coordination layer for all holehe operations
- **Dynamic module loading** eliminates manual registry maintenance when adding services
- **Trio-based async execution** enables scalable concurrent probing without callback complexity
- **Self-updating mechanism** ensures users automatically benefit from new site modules
- **Flexible output** supports both human-readable tables and machine-parseable CSV

## Frequently Asked Questions

### How does [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) discover new services automatically?

Instead of maintaining a static list, [`core.py`](https://github.com/megadose/holehe/blob/main/core.py) calls `import_submodules("holehe.modules")` which uses Python's `importlib` to walk the modules directory. Any `.py` file containing a properly named function becomes available for execution without touching [`core.py`](https://github.com/megadose/holehe/blob/main/core.py) itself.

### Why does [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) use Trio instead of asyncio?

The codebase predates modern `asyncio` patterns and leverages Trio's structured concurrency guarantees. The `TrioProgress` instrument in [`instruments.py`](https://github.com/megadose/holehe/blob/main/instruments.py) integrates cleanly with Trio's nursery API for cancellable, exception-propagating task groups.

### Can I use [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) functions in my own Python project?

Yes. The example above demonstrates importing `holehe.core` directly and calling `import_submodules()`, `get_functions()`, and `launch_module()` programmatically. This bypasses the CLI layer while preserving the full async execution model.

### Where does the actual site-by-site login checking happen?

Not in [`core.py`](https://github.com/megadose/holehe/blob/main/core.py). Individual modules in `holehe/modules/` (such as [`facebook.py`](https://github.com/megadose/holehe/blob/main/facebook.py) or [`github.py`](https://github.com/megadose/holehe/blob/main/github.py)) implement site-specific HTTP logic. [`core.py`](https://github.com/megadose/holehe/blob/main/core.py) only orchestrates their loading and execution — the modules themselves handle cookie jars, CSRF tokens, and response parsing.