How Holehe Modules Are Organized by Category: A Technical Guide
Holehe groups all service-specific checks into the holehe.modules package, where each sub-directory represents a distinct category (social media, shopping, programming, etc.) and every Python file implements a check for a specific platform.
Understanding how Holehe modules are organized by category is essential for contributing to the megadose/holehe repository or extending its reconnaissance capabilities. The project uses a clean hierarchical structure that separates services by domain, allowing the core loader to dynamically discover and execute checks without manual registration.
The holehe.modules Package Structure
The repository stores every service check inside the holehe/modules/ directory. Each immediate sub-directory represents a category (or domain), while individual .py files within those folders implement concrete platform checks.
For example, the path holehe/modules/social_media/twitter.py indicates:
- Category:
social_media - Service:
twitter
The current categories reflected in the source tree include:
- transport –
blablacar.pyand other travel platforms - sport –
bodybuilding.pyand fitness communities - software –
office365.py,lastpass.py,adobe.py - social_media –
twitter.py,instagram.py,facebook.py - shopping –
amazon.py,ebay.py,vivino.py - real_estate –
vrbo.pyand property rental services - programing –
github.py,codecademy.py,replit.py - porn –
pornhub.py,xvideos.py - music –
spotify.py,soundcloud.py,lastfm.py - medias –
flickr.py,ello.py,komoot.py - mails –
yahoo.py,gmail.py,mail_ru.py - forum –
mybb.py,blackworldforum.py,codeigniter.py - crm –
hubspot.py,zoho.py,pipedrive.py - company – Reserved package for future corporate services
Each category folder contains an intentionally empty __init__.py. The loader does not require explicit imports; it discovers modules by traversing the directory tree.
How the Core Loader Discovers Categories
In holehe/core.py, the import_submodules function walks the package tree using pkgutil.walk_packages to import every file dynamically:
modules = import_submodules("holehe.modules")
websites = get_functions(modules, args)
The import_submodules utility preserves the hierarchical path, importing modules as fully-qualified names like holehe.modules.social_media.twitter. Subsequently, get_functions extracts callable objects whose fully-qualified names contain more than three parts, converting each service file into an asynchronous function ready for execution.
This design means no registration is required when adding new services. Placing a new .py file in the appropriate category folder automatically includes it in the next run.
Programmatically Listing Modules by Category
You can inspect the categorical organization at runtime using the same utilities the core employs:
from holehe.core import import_submodules, get_functions
# Load every submodule under holehe.modules
all_modules = import_submodules("holehe.modules")
# Retrieve the callable check functions
functions = get_functions(all_modules)
# Print the category and module name
for fn in functions:
print(f"Category: {fn.__module__}") # e.g., holehe.modules.social_media.twitter
print(f"Function: {fn.__name__}") # e.g., twitter
The output reveals the module structure, showing which services belong to which categories based on their import paths.
Running Individual Category Checks
To execute a specific check from a category manually, import the function directly from its category path and run it asynchronously:
import httpx
import trio
from holehe.modules.social_media.twitter import twitter
async def run_check(email):
async with httpx.AsyncClient() as client:
out = []
await twitter(email, client, out)
print(out)
# Execute the check
trio.run(run_check, "example@example.com")
This pattern works for any service, whether from holehe.modules.shopping.amazon or holehe.modules.programing.github.
Extending Categories with New Services
Adding coverage for a new platform requires only two steps:
- Identify the appropriate category folder (or create a new one if the domain is unique)
- Place a Python file implementing the async check function into that folder
The core loader in holehe/core.py will automatically detect the new file on the next execution, preserving the categorical organization without modifying the main program logic.
Summary
- Holehe modules are organized by category through sub-directories under
holehe/modules/, where folder names represent service domains (social_media, shopping, programing, etc.) - Dynamic loading occurs via
import_submodulesinholehe/core.py, which walks the package tree and imports every module without explicit registration - Individual checks reside as Python files within category folders (e.g.,
holehe/modules/social_media/twitter.py) - Empty
__init__.pyfiles mark directories as Python packages while allowing the loader to discover contents automatically - Extensibility is built-in: adding a new service requires only placing a file in the correct category directory
Frequently Asked Questions
How does Holehe load modules from different categories?
Holehe uses pkgutil.walk_packages in the import_submodules function (located in holehe/core.py) to recursively discover all Python files under holehe/modules/. It imports each file while preserving the hierarchical path structure, then get_functions extracts the callable check objects. This dynamic approach eliminates the need for a central registry or manual imports when new categories or services are added.
Where are the social media checks located in Holehe?
Social media checks reside in the holehe/modules/social_media/ directory. Specific implementations include twitter.py, instagram.py, and facebook.py. Each file contains an async function matching the filename (e.g., async def twitter(...)), which the core loader executes when checking for account existence on those platforms.
Can I add my own custom category to Holehe?
Yes. Create a new sub-directory under holehe/modules/ with the desired category name (e.g., holehe/modules/crypto/), include an empty __init__.py file, and place your service check files inside. The next time Holehe runs, import_submodules will automatically detect the new category and load any Python files it contains, making them available for execution alongside existing categories.
Why are the __init__.py files empty in category folders?
The empty __init__.py files serve only as package markers to designate directories as Python packages, enabling pkgutil.walk_packages to traverse them. Since holehe/core.py discovers modules by walking the filesystem rather than importing specific names, no initialization code or explicit imports are required in these files. This keeps the category structure clean and minimizes maintenance when adding or removing services.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →