# How to Get a List of All Available Holehe Modules Programmatically

> Programmatically get all available Holehe modules by importing submodules and calling get_functions. Discover detection plugins dynamically at runtime.

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

---

**You can retrieve every available Holehe module by calling `import_submodules("holehe.modules")` followed by `get_functions()` from the `holehe.core` module, which uses Python's `pkgutil` to dynamically discover all detection plugins at runtime.**

Holehe uses a dynamic plugin architecture to discover email detection modules at runtime. The `megadose/holehe` repository implements this discovery system in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), allowing developers to programmatically enumerate all available checking functions without invoking the command-line interface.

## Understanding Holehe's Module Discovery System

The module discovery system relies on two helper functions defined in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py). The `import_submodules()` function (lines 37-47) walks the package tree using `pkgutil.walk_packages()`, while `get_functions()` (lines 50-63) extracts the callable detection routines from the imported modules.

When you pass the string `"holehe.modules"` to `import_submodules()`, Python dynamically loads every submodule in the `holehe/modules/` directory structure. This approach ensures that new modules added to the repository are automatically available without requiring manual registration.

## Loading All Modules with import_submodules

The `import_submodules()` function returns a dictionary of loaded module objects. This is the first step toward obtaining a complete list of available services.

```python
from holehe.core import import_submodules

# Dynamically load every module under holehe.modules

modules = import_submodules("holehe.modules")
print(f"Loaded {len(modules)} module packages")

```

This function traverses the entire `holehe/modules/` package hierarchy, including subdirectories like `social_media`, `software`, and `porn`, ensuring comprehensive coverage of all detection capabilities.

## Extracting Callable Detection Functions

After loading the modules, use `get_functions()` to extract the actual checking functions. Each module contains a single async function that performs the email lookup for its respective service.

```python
from holehe.core import import_submodules, get_functions

mods = import_submodules("holehe.modules")
functions = get_functions(mods)

# Each function corresponds to a specific service check

for func in functions:
    print(f"Available: {func.__name__}")

```

The `get_functions()` method filters the imported modules and returns a flat list of callable objects. These functions correspond directly to the service identifiers used throughout Holehe, such as `facebook`, `instagram`, or `github`.

## Practical Implementation Examples

### Printing All Available Module Names

To generate a sorted list of every supported service, combine the helper functions and iterate over the function names:

```python
from holehe.core import import_submodules, get_functions

# Load all sub-modules under holehe.modules

mods = import_submodules("holehe.modules")

# Extract the callable check functions

functions = get_functions(mods)

# Print sorted list of module names

for fn in sorted(fn.__name__ for fn in functions):
    print(fn)

```

This script dynamically loads every Python file inside `holehe/modules/` and extracts the public checking function from each file.

### Running a Subset of Modules Programmatically

Once you have the full list, you can filter for specific services and execute them using `launch_module()`:

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

# Load everything

mods = import_submodules("holehe.modules")
all_funcs = get_functions(mods)

# Select specific social media checks

social_media = [fn for fn in all_funcs if fn.__name__ in {"facebook", "instagram", "twitter"}]

async def run_selected(email):
    client = httpx.AsyncClient(timeout=10)
    out = []
    async with trio.open_nursery() as nursery:
        for mod in social_media:
            nursery.start_soon(launch_module, mod, email, client, out)
    await client.aclose()
    return out

# Execute

email = "example@example.com"
result = trio.run(run_selected, email)
print(result)

```

This example demonstrates how to embed Holehe's detection logic within a custom async workflow, reusing the `launch_module()` function also defined in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py).

### Exporting the Module List to JSON

For documentation or UI integration purposes, you can serialize the module metadata to JSON:

```python
import json
from holehe.core import import_submodules, get_functions

mods = import_submodules("holehe.modules")
functions = get_functions(mods)

module_info = [{"name": fn.__name__, "doc": fn.__doc__ or ""} for fn in functions]

with open("holehe_modules.json", "w", encoding="utf-8") as f:
    json.dump(module_info, f, indent=2)

```

This creates a machine-readable catalog containing every Holehe module name and its docstring, useful for building service directories or automated documentation generators.

## Summary

- **Use `import_submodules("holehe.modules")`** to dynamically load all plugin packages from the `holehe/modules/` directory structure.
- **Call `get_functions()`** on the imported modules to extract the list of callable checking functions.
- **Access function `__name__` attributes** to identify specific services like `facebook`, `github`, or `instagram`.
- **Leverage `launch_module()`** to execute selected modules within custom async workflows.
- **The discovery system uses `pkgutil.walk_packages()`**, ensuring new modules are automatically detected without manual registration.

## Frequently Asked Questions

### Where are the Holehe module discovery functions defined?

The `import_submodules()` and `get_functions()` functions are defined in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) at lines 37-47 and 50-63 respectively. These utilities implement the dynamic plugin discovery system using Python's `pkgutil` module.

### Do I need to manually update the list when new modules are added?

No. Because Holehe uses `pkgutil.walk_packages()` to scan the `holehe/modules/` directory at runtime, any new module files added to the package are automatically discovered when you call `import_submodules("holehe.modules")`.

### Can I filter modules by category (e.g., only social media sites)?

Yes. After calling `get_functions()`, you can filter the returned list using standard Python list comprehensions. Check the `__name__` attribute of each function against a set of desired service identifiers, or inspect the module's `__file__` path to determine its categorical subdirectory.

### Is it possible to run these modules without the Holehe CLI?

Absolutely. The `launch_module()` function in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) allows you to execute individual checking functions programmatically. Pass the function object, an email address, an `httpx.AsyncClient` instance, and an output list to integrate Holehe's detection capabilities directly into your Python applications.