[project] name = "theHarvester" description = "theHarvester is a very simple, yet effective tool designed to be used in the early stages of a penetration test" readme = "README.md" authors = [ { name = "Christian Martorella", email = "cmartorella@edge-security.com" }, { name = "Jay Townsend", email = "jay@cybermon.uk" }, { name = "Matthew Brown", email = "36310667+NotoriousRebel@users.noreply.github.com" }, ] requires-python = ">=3.11" urls.Homepage = "https://github.com/laramies/theHarvester" classifiers = [ "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", "Operating System :: OS Independent", ] dynamic = ["version"] dependencies = [ "aiodns==3.4.0", "aiofiles==24.1.0", "aiohttp==3.12.13", "aiomultiprocess==0.9.1", "aiosqlite==0.21.0", "beautifulsoup4==4.13.4", "censys==2.2.17", "certifi==2025.4.26", "dnspython==2.7.0", "fastapi==0.115.12", "lxml==5.4.0", "netaddr==1.3.0", "playwright==1.52.0", "PyYAML==6.0.2", "python-dateutil==2.9.0.post0", "requests==2.32.4", "retrying==1.3.4", "shodan==1.31.0", "slowapi==0.1.9", "ujson==5.10.0", "uvicorn==0.34.3", "uvloop==0.21.0; platform_system != 'Windows'", "winloop==0.1.8; platform_system == 'Windows'", ] [project.optional-dependencies] dev = [ "mypy==1.16.0", "mypy-extensions==1.1.0", "pytest==8.4.0", "pytest-asyncio==0.26.0", "types-certifi==2021.10.8.3", "types-chardet==5.0.4.6", "types-python-dateutil==2.9.0.20250516", "types-PyYAML==6.0.12.20250516", "types-requests==2.32.0.20250602", "ruff==0.11.12", "types-ujson==5.10.0.20250326", "wheel==0.45.1", ] [project.scripts] theHarvester = "theHarvester.theHarvester:main" restfulHarvest = "theHarvester.restfulHarvest:main" [tool.setuptools.dynamic] version = { attr = "theHarvester.lib.version.VERSION" } [tool.setuptools.packages.find] include = ["theHarvester*"] [tool.setuptools.package-data] "*" = ["*.txt", "*.yaml"] [tool.pytest.ini_options] minversion = "8.3.3" asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" addopts = "--no-header" testpaths = [ "tests", "tests/discovery/", ] [build-system] requires = ["setuptools>=68"] build-backend = "setuptools.build_meta" [tool.mypy] python_version = "3.11" warn_unused_configs = true ignore_missing_imports = true show_traceback = true show_error_codes = true namespace_packages = true [tool.uv] python-preference = "managed" [tool.uv.pip] python-version = "3.11" [tool.ruff] # Exclude a variety of commonly ignored directories. exclude = [ "tests", ".eggs", ".git", ".git-rewrite", ".mypy_cache", ".pyenv", ".pytest_cache", ".pytype", ".ruff_cache", ".github", ".venv", ".vscode", ".idea", "__pypackages__", "build", "dist", "site-packages", "venv", ] line-length = 130 target-version = "py311" show-fixes = true [tool.ruff.lint] select = ["E4", "E7", "E9", "F", "I", "UP", "TCH", "FA", "RUF", "PT", ] ignore = ["S311", "RUF021", "RUF029", "F841"] # Allow fix for all enabled rules (when `--fix`) is provided. fixable = ["ALL"] unfixable = [] # Allow unused variables when underscore-prefixed. dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" [tool.ruff.format] # Like Black, use double quotes for strings. quote-style = "single" indent-style = "space" # Like Black, respect magic trailing commas. skip-magic-trailing-comma = false # Like Black, automatically detect the appropriate line ending. line-ending = "auto"