CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-sherlock-project

Hunt down social media accounts by username across social networks

Pending
Overview
Eval results
Files

result-management.mddocs/

Result Management

Data structures and enumerations for handling search results from username lookups. The result management system provides structured representations of query outcomes with comprehensive metadata about each search operation.

Capabilities

Query Status Enumeration

Enumeration that represents the possible outcomes of a username search on a social media platform.

class QueryStatus(Enum):
    """
    Query Status Enumeration for username detection results.
    """
    CLAIMED = "Claimed"      # Username detected/exists on the platform
    AVAILABLE = "Available"  # Username not detected/available for registration
    UNKNOWN = "Unknown"      # Error occurred while trying to detect username
    ILLEGAL = "Illegal"      # Username format not allowable for this site
    WAF = "WAF"             # Request blocked by Web Application Firewall
    
    def __str__(self) -> str:
        """
        Convert status to string representation.
        
        Returns:
            String value of the status
        """

Query Result Object

Container object that holds comprehensive information about the result of a username query on a specific platform.

class QueryResult:
    """
    Query Result Object containing information about username detection on a site.
    """
    
    def __init__(
        self,
        username: str,
        site_name: str,
        site_url_user: str,
        status: QueryStatus,
        query_time: float = None,
        context: str = None
    ):
        """
        Create Query Result Object.
        
        Args:
            username: String indicating username that query result was about
            site_name: String which identifies the site
            site_url_user: String containing URL for username on site
                          (NOTE: may or may not exist - indicates what the URL would be)
            status: QueryStatus enumeration indicating the status of the query
            query_time: Time in seconds required to perform query (optional)
            context: String indicating additional context about the query,
                    such as error details (optional)
        """
        
    # Attributes set by constructor
    username: str       # Username that was searched
    site_name: str      # Name of the social media site
    site_url_user: str  # Full URL where the user profile would be located
    status: QueryStatus # Result status of the query
    query_time: float   # Time taken for the query in seconds (may be None)
    context: str        # Additional context information (may be None)
    
    def __str__(self) -> str:
        """
        Convert Object to String representation.
        
        Returns:
            Nicely formatted string with status and context information
        """

Types

Status Values

The QueryStatus enum provides these specific status values:

  • CLAIMED: Username exists on the platform - account was found
  • AVAILABLE: Username does not exist on the platform - available for registration
  • UNKNOWN: An error occurred during the check (network issue, site down, etc.)
  • ILLEGAL: The username format is not valid for this particular site
  • WAF: Request was blocked by a Web Application Firewall (like Cloudflare)

Result Dictionary Structure

When the main sherlock() function returns results, each site result contains:

ResultDict = {
    "url_main": str,        # Main homepage URL of the site
    "url_user": str,        # Full URL to the user's profile page
    "status": QueryResult,  # QueryResult object with detailed information
    "http_status": int,     # HTTP status code from the request
    "response_text": str    # Raw response text (may be None on errors)
}

Usage Examples

Basic Result Processing

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

# Perform search
sites = SitesInformation()
notify = QueryNotifyPrint()
results = sherlock("john_doe", sites.sites, notify)

# Process results by status
claimed_accounts = []
available_usernames = []
errors = []

for site_name, result_data in results.items():
    result = result_data['status']  # This is a QueryResult object
    
    if result.status == QueryStatus.CLAIMED:
        claimed_accounts.append({
            'site': site_name,
            'url': result.site_url_user,
            'response_time': result.query_time
        })
    elif result.status == QueryStatus.AVAILABLE:
        available_usernames.append(site_name)
    elif result.status in [QueryStatus.UNKNOWN, QueryStatus.WAF]:
        errors.append({
            'site': site_name,
            'error': result.context,
            'status': result.status.value
        })

print(f"Found accounts: {len(claimed_accounts)}")
print(f"Available on: {len(available_usernames)} sites")
print(f"Errors: {len(errors)}")

Filtering Results by Response Time

# Find accounts with fast response times (under 500ms)
fast_results = []

for site_name, result_data in results.items():
    result = result_data['status']
    if (result.status == QueryStatus.CLAIMED and 
        result.query_time and result.query_time < 0.5):
        fast_results.append({
            'site': site_name,
            'username': result.username,
            'url': result.site_url_user,
            'time': result.query_time
        })

# Sort by response time
fast_results.sort(key=lambda x: x['time'])

Creating Custom Result Objects

from sherlock_project.result import QueryResult, QueryStatus

# Create a custom result (e.g., for testing or custom site checking)
custom_result = QueryResult(
    username="test_user",
    site_name="CustomSite",
    site_url_user="https://customsite.com/user/test_user",
    status=QueryStatus.CLAIMED,
    query_time=0.234,
    context="Account verified"
)

print(f"Result: {custom_result}")  # Uses __str__ method
print(f"Status: {custom_result.status}")
print(f"URL: {custom_result.site_url_user}")

Error Handling with Context

# Process results with detailed error information
for site_name, result_data in results.items():
    result = result_data['status']
    
    if result.status == QueryStatus.UNKNOWN:
        print(f"Error on {site_name}: {result.context}")
    elif result.status == QueryStatus.WAF:
        print(f"Blocked by WAF on {site_name} - consider using proxy")
    elif result.status == QueryStatus.ILLEGAL:
        print(f"Username format invalid for {site_name}")

Export Results to Different Formats

import json
import csv

# Export claimed accounts to JSON
claimed_data = []
for site_name, result_data in results.items():
    result = result_data['status']
    if result.status == QueryStatus.CLAIMED:
        claimed_data.append({
            'username': result.username,
            'site_name': result.site_name,
            'profile_url': result.site_url_user,
            'response_time_ms': round(result.query_time * 1000) if result.query_time else None,
            'found_at': result_data.get('timestamp')  # If you add timestamps
        })

# Save to JSON
with open('sherlock_results.json', 'w') as f:
    json.dump(claimed_data, f, indent=2)

# Save to CSV
with open('sherlock_results.csv', 'w', newline='') as f:
    if claimed_data:
        writer = csv.DictWriter(f, fieldnames=claimed_data[0].keys())
        writer.writeheader()
        writer.writerows(claimed_data)

Install with Tessl CLI

npx tessl i tessl/pypi-sherlock-project

docs

core-search.md

index.md

notification-system.md

result-management.md

site-management.md

tile.json