[project] name = "netanal" version = "0.1.0" description = "Network traffic analyzer CLI - capture and analyze packets with protocol distribution, top talkers, and bandwidth visualization" requires-python = ">=3.14" dependencies = [ "typer>=0.21.1", "rich>=14.3.2", "scapy>=2.7.0", "matplotlib>=3.10.8", ] [project.optional-dependencies] dev = [ "pytest>=9.0.2,<10.0.0", "pytest-cov>=7.0.0,<8.0.0", "mypy>=1.19.1", "ruff>=0.14.14", "ty>=0.0.14", "pre-commit>=4.5.1", "pylint>=4.0.4,<5.0.0", ] [project.urls] Homepage = "https://github.com/CarterPerez-dev/Cybersecurity-Projects" Repository = "https://github.com/CarterPerez-dev/Cybersecurity-Projects" Issues = "https://github.com/CarterPerez-dev/Cybersecurity-Projects/issues" Changelog = "https://github.com/CarterPerez-dev/Cybersecurity-Projects/blob/main/CHANGELOG.md" [project.scripts] netanal = "netanal.main:app" [build-system] requires = [ "hatchling", ] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = [ "src/netanal", ] [tool.ruff] target-version = "py314" line-length = 88 src = [ "src/netanal", ] [tool.ruff.lint] select = [ "E", "W", "F", "B", "C4", "UP", "ARG", "SIM", "PTH", "RUF", "ASYNC", "S", "N", ] ignore = [ "E501", "B008", "S101", "S104", "S105", "ARG001", "E712", "N999", "N818", "UP046", "RUF005", ] [tool.ruff.lint.per-file-ignores] "tests/**/*.py" = [ "S101", "ARG001", ] "conftest.py" = [ "S107", ] [tool.mypy] python_version = "3.14" strict = true warn_return_any = true warn_unused_ignores = true disallow_untyped_defs = true disallow_incomplete_defs = true [[tool.mypy.overrides]] module = [ "tests.*", "conftest", ] ignore_errors = true [[tool.mypy.overrides]] module = [ "scapy", "scapy.*", "matplotlib", "matplotlib.*", ] ignore_missing_imports = true [tool.pylint.main] py-version = "3.14" jobs = 4 load-plugins = [] persistent = true suggestion-mode = true ignore = [ "venv", ".venv", "__pycache__", "build", "dist", ".git", ".pytest_cache", ".mypy_cache", ".ruff_cache", ] ignore-paths = [ "^venv/.*", "^.venv/.*", "^build/.*", "^dist/.*", ] [tool.pylint.messages_control] disable = [ "C0103", "C0104", "C0116", "C0121", "C0301", "C0302", "C0303", "C0304", "C0305", "C0411", "C0413", "C0415", "E0401", "E0601", "E1102", "E1136", "R0801", "R0901", "R0902", "R0903", "R0911", "R0917", "R1705", "R1714", "W0611", "W0612", "W0613", "W0621", "W0622", "W0718", ] [tool.pylint.format] max-line-length = 95 [tool.pylint.design] max-args = 12 max-attributes = 10 max-branches = 15 max-locals = 20 max-statements = 55 [tool.pytest.ini_options] testpaths = [ "tests", ] addopts = "-ra -q" filterwarnings = [ "ignore::DeprecationWarning", ] [tool.coverage.run] branch = true source = [ "src/netanal", ] [tool.coverage.report] exclude_lines = [ "pragma: no cover", "if TYPE_CHECKING:", "raise NotImplementedError", ] [tool.ty.src] include = [ "src/netanal", "tests", ] exclude = [ ".venv/**", ] respect-ignore-files = true [tool.ty.environment] python-version = "3.14" root = [ "./src/netanal", ] python = "./.venv" [tool.ty.rules] possibly-missing-attribute = "error" possibly-missing-import = "error" unused-ignore-comment = "warn" redundant-cast = "warn" undefined-reveal = "warn" [[tool.ty.overrides]] include = [ "tests/**", ] [tool.ty.overrides.rules] unresolved-reference = "warn" invalid-argument-type = "warn" [tool.ty.terminal] error-on-warning = false output-format = "full"