Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions .github/workflows/exclusions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,24 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.13'

- name: Install Poetry
uses: abatilo/actions-poetry@v4
- uses: astral-sh/setup-uv@v7
with:
poetry-version: 'latest'
activate-environment: true

- name: Install dependencies
run: |
poetry install --no-interaction --with dev
uv sync --group dev

- name: Run false positive tests
run: |
$(poetry env activate)
pytest -q --tb no -m validate_targets_fp -n 20 | tee fp_test_results.txt
deactivate

- name: Parse false positive detections by desired categories
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/update-site-list.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ jobs:
steps:
# Check out the code at the specified pull request head commit
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0

# Install Python 3
- name: Install Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.x'

Expand Down
16 changes: 6 additions & 10 deletions .github/workflows/validate_modified_targets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
# Checkout the base branch but fetch all history to avoid a second fetch call
ref: ${{ github.base_ref }}
Expand All @@ -26,14 +26,10 @@ jobs:
with:
python-version: "3.13"

- name: Install Poetry
uses: abatilo/actions-poetry@v4
with:
poetry-version: "latest"

- uses: astral-sh/setup-uv@v7
- name: Install dependencies
run: |
poetry install --no-interaction --with dev
uv sync --group dev

- name: Prepare JSON versions for comparison
run: |
Expand Down Expand Up @@ -85,15 +81,15 @@ jobs:
- name: Validate remote manifest against local schema
if: steps.discover-modified.outputs.changed_targets != ''
run: |
poetry run pytest tests/test_manifest.py::test_validate_manifest_against_local_schema
uv run --frozen pytest tests/test_manifest.py::test_validate_manifest_against_local_schema

# --- The rest of the steps below are unchanged ---

- name: Validate modified targets
if: steps.discover-modified.outputs.changed_targets != ''
continue-on-error: true
run: |
poetry run pytest -q --tb no -rA -m validate_targets -n 20 \
uv run --frozen pytest -q --tb no -rA -m validate_targets -n 20 \
--chunked-sites "${{ steps.discover-modified.outputs.changed_targets }}" \
--junitxml=validation_results.xml

Expand All @@ -102,7 +98,7 @@ jobs:
id: prepare-summary
run: |
summary=$(
poetry run python devel/summarize_site_validation.py validation_results.xml || echo "Failed to generate summary of test results"
uv run --frozen python devel/summarize_site_validation.py validation_results.xml || echo "Failed to generate summary of test results"
)
echo "$summary" > validation_summary.md

Expand Down
74 changes: 36 additions & 38 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
[build-system]
requires = [ "poetry-core>=1.2.0" ]
build-backend = "poetry.core.masonry.api"
# poetry-core 1.8 not available in .fc39. Can upgrade to 1.8.0 at .fc39 EOL
requires = ["pdm-backend>=2.4.8"]
build-backend = "pdm.backend"

[tool.poetry-version-plugin]
source = "init"
[tool.pdm.version]
path = "sherlock_project/__init__.py"

[tool.poetry]
[project]
name = "sherlock-project"
version = "0.16.0"
dynamic = ["version"]
description = "Hunt down social media accounts by username across social networks"
license = "MIT"
license = {text="MIT"}
authors = [
"Siddharth Dushantha <[email protected]>"
{ name="Siddharth Dushantha", email="[email protected]" }
]
maintainers = [
"Paul Pfeister <[email protected]>",
"Matheus Felipe <[email protected]>",
"Sondre Karlsen Dyrnes <[email protected]>"
{ name="Paul Pfeister", email="[email protected]" },
{ name="Matheus Felipe", email="[email protected]" },
{ name="Sondre Karlsen Dyrnes", email="[email protected]" }
]
readme = "docs/pyproject/README.md"
packages = [ { include = "sherlock_project"} ]
keywords = [ "osint", "reconnaissance", "information gathering" ]
classifiers = [
"Development Status :: 5 - Production/Stable",
Expand All @@ -33,36 +31,36 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Topic :: Security"
]
requires-python = ">=3.9"
dependencies = [
"certifi >=2019.6.16",
"colorama >=0.4.1",
"PySocks >=1.7.0",
"requests >=2.22.0",
"requests-futures >=1.0.0",
"stem >=1.8.0",
"pandas >=2.2.1",
"openpyxl >=3.0.10",
]

[project.urls]
homepage = "https://sherlockproject.xyz/"
repository = "https://github.com/sherlock-project/sherlock"


[tool.poetry.urls]
"Bug Tracker" = "https://github.com/sherlock-project/sherlock/issues"

[tool.poetry.dependencies]
python = "^3.9"
certifi = ">=2019.6.16"
colorama = "^0.4.1"
PySocks = "^1.7.0"
requests = "^2.22.0"
requests-futures = "^1.0.0"
stem = "^1.8.0"
pandas = "^2.2.1"
openpyxl = "^3.0.10"
tomli = "^2.2.1"

[tool.poetry.group.dev.dependencies]
jsonschema = "^4.0.0"
rstr = "^3.2.2"
pytest = "^8.4.2"
pytest-xdist = "^3.8.0"


[tool.poetry.group.ci.dependencies]
defusedxml = "^0.7.1"
[dependency-groups]
dev = [
"jsonschema >=4.0.0",
"rstr >=3.2.2",
"pytest >=8.4.2",
"pytest-xdist >=3.8.0"
]
ci = [
"defusedxml >=0.7.1"
]

[tool.poetry.scripts]
[project.scripts]
sherlock = 'sherlock_project.sherlock:main'
23 changes: 4 additions & 19 deletions sherlock_project/__init__.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,15 @@
""" Sherlock Module
"""Sherlock Module

This module contains the main logic to search for usernames at social
networks.

"""

from importlib.metadata import version as pkg_version, PackageNotFoundError
import pathlib
import tomli


def get_version() -> str:
"""Fetch the version number of the installed package."""
try:
return pkg_version("sherlock_project")
except PackageNotFoundError:
pyproject_path: pathlib.Path = pathlib.Path(__file__).resolve().parent.parent / "pyproject.toml"
with pyproject_path.open("rb") as f:
pyproject_data = tomli.load(f)
return pyproject_data["tool"]["poetry"]["version"]

# This variable is only used to check for ImportErrors induced by users running as script rather than as module or package
import_error_test_var = None

__shortname__ = "Sherlock"
__longname__ = "Sherlock: Find Usernames Across Social Networks"
__version__ = get_version()
__shortname__ = "Sherlock"
__longname__ = "Sherlock: Find Usernames Across Social Networks"
__version__ = "0.16.0"

forge_api_latest_release = "https://api.github.com/repos/sherlock-project/sherlock/releases/latest"
2 changes: 1 addition & 1 deletion sherlock_project/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# Check if the user is using the correct version of Python
python_version = sys.version.split()[0]

if sys.version_info < (3, 9):
if sys.version_info < (3, 9): # NOQA:UP036
print(f"Sherlock requires Python 3.9+\nYou are using Python {python_version}, which is not supported by Sherlock.")
sys.exit(1)

Expand Down
2 changes: 1 addition & 1 deletion sherlock_project/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def __str__(self):
"""
return self.value

class QueryResult():
class QueryResult:
"""Query Result Object.

Describes result of query about a given username.
Expand Down
25 changes: 10 additions & 15 deletions sherlock_project/sherlock.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@
import sys

try:
from sherlock_project.__init__ import import_error_test_var # noqa: F401
from sherlock_project.__init__ import import_error_test_var # noqa: F401
except ImportError:
print("Did you run Sherlock with `python3 sherlock/sherlock.py ...`?")
print("This is an outdated method. Please see https://sherlockproject.xyz/installation for up to date instructions.")
sys.exit(1)

import csv
import signal
import pandas as pd
import os
import re
from argparse import ArgumentParser, RawDescriptionHelpFormatter
import signal
from argparse import ArgumentParser, ArgumentTypeError, RawDescriptionHelpFormatter
from json import loads as json_loads
from time import monotonic
from typing import Optional

import pandas as pd
import requests
from colorama import init
from requests_futures.sessions import FuturesSession

from sherlock_project.__init__ import (
Expand All @@ -35,14 +35,11 @@
__version__,
forge_api_latest_release,
)

from sherlock_project.result import QueryStatus
from sherlock_project.result import QueryResult
from sherlock_project.notify import QueryNotify
from sherlock_project.notify import QueryNotifyPrint
from sherlock_project.result import QueryResult
from sherlock_project.result import QueryStatus
from sherlock_project.sites import SitesInformation
from colorama import init
from argparse import ArgumentTypeError


class SherlockFuturesSession(FuturesSession):
Expand Down Expand Up @@ -105,9 +102,7 @@ def response_time(resp, *args, **kwargs):
# No response hook was already defined, so install it ourselves.
hooks["response"] = [response_time]

return super(SherlockFuturesSession, self).request(
method, url, hooks=hooks, *args, **kwargs
)
return super().request(method, url, hooks=hooks, *args, **kwargs)


def get_response(request_future, error_type, social_network):
Expand Down Expand Up @@ -172,9 +167,9 @@ def sherlock(
site_data: dict[str, dict[str, str]],
query_notify: QueryNotify,
dump_response: bool = False,
proxy: Optional[str] = None,
proxy: "str | None" = None,
timeout: int = 60,
) -> dict[str, dict[str, str | QueryResult]]:
) -> dict[str, dict[str, "str | QueryResult"]]:
"""Run Sherlock Analysis.

Checks for existence of username on various social media sites.
Expand Down
4 changes: 2 additions & 2 deletions sherlock_project/sites.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __str__(self):
class SitesInformation:
def __init__(
self,
data_file_path: str|None = None,
data_file_path: "str|None" = None,
honor_exclusions: bool = True,
do_not_exclude: list[str] = [],
):
Expand Down Expand Up @@ -149,7 +149,7 @@ def __init__(
else:
# Reference is to a file.
try:
with open(data_file_path, "r", encoding="utf-8") as file:
with open(data_file_path, encoding="utf-8") as file:
try:
site_data = json.load(file)
except Exception as error:
Expand Down
Loading