How to Import and Use Sherlock as a Python Library: A Complete Guide

You can import Sherlock as a library by installing the sherlock-project package and importing the sherlock() function from sherlock_project.sherlock, then passing it a username, a site dictionary from SitesInformation, and a notifier instance to retrieve structured results.

The Sherlock Project is a powerful open-source intelligence (OSINT) tool for finding usernames across hundreds of social networks. While commonly used via command line, the underlying sherlock_project package provides a clean Python API that allows you to embed username detection directly into applications, automation pipelines, or data processing workflows.

Core Components of the Sherlock Library API

Understanding the three primary modules is essential before implementing Sherlock in your codebase. The library follows a modular architecture separating detection logic, site definitions, and notification handling.

The Detection Engine: sherlock_project/sherlock.py

The heart of the library is the sherlock() function (implemented in lines 70‑530 of sherlock_project/sherlock.py). This function manages a threaded request session, iterates over site definitions, fires HTTP requests, interprets responses, and constructs a nested result dictionary.

Key implementation details include:

  • SherlockFuturesSession (lines 48‑110): Handles concurrent HTTP requests with Futures
  • Request handling logic (lines 120‑500): Manages response interpretation and error handling
  • Return value: A dictionary keyed by site name containing QueryResult objects, URLs, and status metadata

Site Definitions: sherlock_project/sites.py

The SitesInformation class (lines 78‑113 of sherlock_project/sites.py) loads the site manifest (data.json) from the official remote repository or a local file. This class constructs SiteInformation objects that define how Sherlock probes each platform, including URL patterns, error types, and HTTP headers.

The module also provides remove_nsfw_sites() (lines 133‑150) for filtering adult content sites when required.

Notification System: sherlock_project/notify.py

Sherlock uses a pluggable notifier pattern. The concrete implementation QueryNotifyPrint (lines 82‑155 of sherlock_project/notify.py) prints results to stdout and optionally opens found profiles in a browser.

The base class QueryNotify allows you to implement custom output handlers, including silent operation modes that capture results without printing. The update() method (lines 82‑155) handles per-site status reporting, while finish() (lines 59‑76) summarizes total hits.

Result Types and Metadata

The QueryStatus enum and QueryResult data class (defined in sherlock_project/result.py) standardize status codes like CLAIMED, AVAILABLE, or UNKNOWN across the library.

Package metadata including __version__, __shortname__, and the get_version() helper are available in sherlock_project/__init__.py (lines 13‑30), useful for logging or dependency verification.

How to Import Sherlock in Python Code

To use Sherlock programmatically, import these three primary components:

from sherlock_project.sherlock import sherlock
from sherlock_project.sites import SitesInformation
from sherlock_project.notify import QueryNotifyPrint

The sherlock_project package name is the primary namespace when using the library distribution. Do not import from the legacy sherlock directory used by the CLI script.

Practical Usage Examples

Basic Username Lookup

This minimal example loads the official site definitions and checks a single username:

from sherlock_project.sherlock import sherlock
from sherlock_project.sites import SitesInformation
from sherlock_project.notify import QueryNotifyPrint

# Load site definitions from the remote data.json manifest

sites = SitesInformation()
site_dict = {s.name: s.information for s in sites}

# Initialize a notifier that prints results to stdout

notifier = QueryNotifyPrint(verbose=False, print_all=False)

# Execute the search

results = sherlock("alice", site_dict, notifier)

# Filter for successfully found accounts

found_sites = [
    site for site, data in results.items() 
    if data["status"].status.name == "CLAIMED"
]
print(f"Found on: {found_sites}")

The results dictionary maps site names to metadata including url_user, status, and response times.

Batch Processing Multiple Usernames

For checking multiple usernames efficiently, reuse the SitesInformation instance:

from typing import List, Dict
from sherlock_project.sherlock import sherlock
from sherlock_project.sites import SitesInformation
from sherlock_project.notify import QueryNotifyPrint

def batch_lookup(usernames: List[str]) -> Dict[str, List[str]]:
    """
    Returns a mapping of usernames to lists of sites where they exist.
    """
    sites = SitesInformation()
    site_dict = {s.name: s.information for s in sites}
    notifier = QueryNotifyPrint(verbose=False, print_all=False)
    
    results_map: Dict[str, List[str]] = {}
    
    for username in usernames:
        result = sherlock(username, site_dict, notifier)
        claimed = [
            site for site, data in result.items()
            if data["status"].status.name == "CLAIMED"
        ]
        results_map[username] = claimed
    
    return results_map

# Usage

print(batch_lookup(["alice", "bob", "charlie"]))

Reusing the same SitesInformation instance avoids reloading the remote data.json for each check, improving performance for bulk operations.

Silent Execution Without Console Output

For server environments or automated pipelines, subclass QueryNotify to suppress output:

from sherlock_project.sherlock import sherlock
from sherlock_project.sites import SitesInformation
from sherlock_project.notify import QueryNotify

class SilentNotifier(QueryNotify):
    """A notifier that captures results without printing to stdout."""
    def start(self, message=None):
        pass
    
    def update(self, result):
        pass
    
    def finish(self, message=None):
        pass

sites = SitesInformation()
site_dict = {s.name: s.information for s in sites}
silent = SilentNotifier()

result = sherlock("target_user", site_dict, silent)

# Result dictionary contains full data; nothing printed to console

This pattern is essential when integrating Sherlock into web applications or CI/CD pipelines where console noise is undesirable.

Adding Custom Site Definitions

You can extend Sherlock with proprietary or internal platforms without modifying the upstream data.json:

custom_definitions = {
    "InternalWiki": {
        "urlMain": "https://wiki.company.com",
        "url": "https://wiki.company.com/users/{}",
        "username_claimed": "admin",
        "errorType": "status_code",
        "errorCode": 404,
        "headers": {"User-Agent": "CompanyBot/1.0"},
    }
}

sites = SitesInformation()
site_dict = {s.name: s.information for s in sites}
site_dict.update(custom_definitions)  # Merge custom sites

notifier = QueryNotifyPrint()
results = sherlock("jsmith", site_dict, notifier)

The site_dict accepts standard Sherlock site definition schemas, allowing you to probe internal APIs or niche platforms alongside the standard social networks.

Summary

  • Import from sherlock_project: The package exposes sherlock(), SitesInformation, and QueryNotifyPrint as its primary public API.
  • Initialize sites once: Load SitesInformation() to fetch the current data.json manifest, then convert it to a dictionary for the sherlock() function.
  • Control output with notifiers: Use QueryNotifyPrint for debugging or subclass QueryNotify for silent operation in production environments.
  • Receive structured data: The function returns a dictionary mapping site names to QueryResult objects containing status codes, URLs, and probe metadata.
  • Extend with custom sites: Merge additional site definitions into the dictionary before calling sherlock() to check internal or specialized platforms.

Frequently Asked Questions

What is the correct Python import statement for Sherlock?

Use from sherlock_project.sherlock import sherlock rather than importing from a sherlock module. The library installs under the sherlock_project namespace to avoid conflicts with other packages. Also import SitesInformation from sherlock_project.sites and QueryNotifyPrint from sherlock_project.notify to handle site definitions and output formatting.

How can I suppress all console output when using Sherlock as a library?

Create a subclass of QueryNotify (from sherlock_project.notify) that overrides start(), update(), and finish() as no-op methods. Pass an instance of this silent notifier to the sherlock() function. This captures results into the return dictionary without printing to stdout, which is essential for server environments or when integrating into larger applications.

How do I check which version of the Sherlock library is installed?

Access the __version__ constant directly from the package: from sherlock_project import __version__. Alternatively, call the get_version() helper function from the same module, which reads the version from the installed distribution metadata or falls back to parsing pyproject.toml if running from source.

Can I use Sherlock to check usernames on custom or internal websites?

Yes. Construct a site definition dictionary following the Sherlock schema (including keys like url, errorType, errorCode, and headers), then merge it into the site dictionary obtained from SitesInformation. Pass this merged dictionary to sherlock(). This allows you to probe company-specific platforms, forums, or APIs alongside the standard social networks defined in the official data.json manifest.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →