[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"
license = "GPL-2.0-only"
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.12"
urls.Homepage = "https://github.com/laramies/theHarvester"
classifiers = [
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Programming Language :: Python :: 3.14",
    "Operating System :: OS Independent",
]
dynamic = ["version"]
dependencies = [
    "aiodns==4.0.4",
    "aiofiles==25.1.0",
    "aiohttp==3.14.0",
    "aiohttp-socks==0.11.0",
    "aiomultiprocess==0.9.1",
    "aiosqlite==0.22.1",
    "beautifulsoup4==4.14.3",
    "censys==2.2.19",
    "certifi==2026.5.20",
    "dnspython==2.8.0",
    "fastapi==0.136.3",
    "lxml==6.1.1",
    "netaddr==1.3.0",
    "playwright==1.60.0",
    "PyYAML==6.0.3",
    "python-dateutil==2.9.0.post0",
    "httpx==0.28.1",
    "retrying==1.4.2",
    "shodan==1.31.0",
    "slowapi==0.1.9",
    "ujson==5.12.1",
    "uvicorn==0.48.0",
    "uvloop==0.22.1; platform_system != 'Windows'",
    "winloop==0.6.3; platform_system == 'Windows'",
]

[dependency-groups]
dev = [
    "mypy==2.1.0",
    "mypy-extensions==1.1.0",
    "pytest==9.0.3",
    "pytest-asyncio==1.4.0",
    "types-certifi==2021.10.8.3",
    "types-chardet==5.0.4.6",
    "types-python-dateutil==2.9.0.20260518",
    "types-PyYAML==6.0.12.20250915",
    "ruff==0.15.15",
    "types-ujson==5.10.0.20250822",
    "wheel==0.47.0",
    "ty==0.0.42",
]

[project.scripts]
theHarvester = "theHarvester.theHarvester:main"
restfulHarvest = "theHarvester.restfulHarvest:main"

[tool.pytest.ini_options]
minversion = "8.3.3"
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
addopts = "--no-header"
testpaths = ["tests"]

[build-system]
requires = ["flit_core >=3.11,<4"]
build-backend = "flit_core.buildapi"

[tool.mypy]
python_version = "3.13"
warn_unused_configs = true
ignore_missing_imports = true
show_traceback = true
show_error_codes = true
namespace_packages = true
check_untyped_defs = true

[tool.uv]
python-preference = "managed"

[tool.uv.pip]
python-version = "3.13"

[tool.ty.src]
respect-ignore-files = false
exclude = [
    ".venv/**",
    "tests/**",
    ".github/*"
]

[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 = "py313"
show-fixes = true

[tool.ruff.lint]
select = ["E",
    "F",
    "N",
    "I",
    "B",
    "UP",
    "FA",
    "FAST",
    "RUF",
    "PT",
    "TC",
    "FURB",
    "ASYNC"
    ]
ignore = [
    "B018",
    "B904",
    "E501",
    "N999",
    ]

# 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"
