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

> Learn how to import and use Sherlock as a Python library. Install the package and call the sherlock function with required arguments for structured results.

- Repository: [Sherlock/sherlock](https://github.com/sherlock-project/sherlock)
- Tags: how-to-guide
- Published: 2026-03-02

---

**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`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/sherlock.py)

The heart of the library is the **`sherlock()`** function (implemented in lines 70‑530 of [`sherlock_project/sherlock.py`](https://github.com/sherlock-project/sherlock/blob/main/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`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/sites.py)

The **`SitesInformation`** class (lines 78‑113 of [`sherlock_project/sites.py`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/sites.py)) loads the site manifest ([`data.json`](https://github.com/sherlock-project/sherlock/blob/main/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`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/notify.py)

Sherlock uses a pluggable notifier pattern. The concrete implementation **`QueryNotifyPrint`** (lines 82‑155 of [`sherlock_project/notify.py`](https://github.com/sherlock-project/sherlock/blob/main/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`](https://github.com/sherlock-project/sherlock/blob/main/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`](https://github.com/sherlock-project/sherlock/blob/main/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:

```python
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:

```python
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:

```python
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`](https://github.com/sherlock-project/sherlock/blob/main/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:

```python
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`](https://github.com/sherlock-project/sherlock/blob/main/data.json):

```python
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`](https://github.com/sherlock-project/sherlock/blob/main/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`](https://github.com/sherlock-project/sherlock/blob/main/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`](https://github.com/sherlock-project/sherlock/blob/main/data.json) manifest.