[project] name = "c2-beacon-server" version = "1.0.0" description = "C2 beacon teamserver for security research and education" requires-python = ">=3.12" authors = [ {name = "CarterPerez-dev", email = "support@certgames.com"} ] readme = "README.md" license = {text = "AGPL-3.0"} dependencies = [ "fastapi[standard]>=0.129.0", "pydantic>=2.12.5,<3.0.0", "pydantic-settings>=2.12.0,<3.0.0", "aiosqlite>=0.22.1", "uvicorn[standard]>=0.40.0", "gunicorn>=25.1.0", ] [project.optional-dependencies] dev = [ "pytest>=9.0.2", "pytest-asyncio>=1.3.0", "pytest-cov>=7.0.0", "httpx>=0.28.1", "ruff>=0.15.1", "mypy>=1.19.1", "pylint>=4.0.4", ] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["app"] [tool.ruff] target-version = "py312" line-length = 88 src = ["app"] [tool.ruff.lint] select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes "B", # flake8-bugbear "C4", # flake8-comprehensions "UP", # pyupgrade "ARG", # flake8-unused-arguments "SIM", # flake8-simplify "PTH", # flake8-use-pathlib "RUF", # ruff-specific "ASYNC", # flake8-async "S", # flake8-bandit (security) "N", # pep8-naming "I", # isort ] ignore = [ "E501", # line too long (formatter handles) "B008", # function call in default argument (FastAPI Depends) "S101", # assert usage (needed for tests) "S104", # 0.0.0.0 binding (intentional for Docker) "ARG001", # unused function argument (common in FastAPI deps) "N818", # exception naming convention "RUF005", # list concatenation style ] [tool.ruff.lint.per-file-ignores] "tests/**/*.py" = ["S101", "ARG001"] [tool.mypy] python_version = "3.12" strict = true warn_return_any = true warn_unused_ignores = true disallow_untyped_defs = true disallow_incomplete_defs = true exclude = [".venv", "venv"] [[tool.mypy.overrides]] module = ["tests.*", "conftest"] ignore_errors = true [[tool.mypy.overrides]] module = ["aiosqlite", "aiosqlite.*"] ignore_missing_imports = true [tool.pylint.main] py-version = "3.12" jobs = 4 persistent = 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", # invalid-name "C0116", # missing-function-docstring "C0301", # line-too-long "C0302", # too-many-lines "C0303", # trailing-whitespace "C0304", # final-newline-missing "C0305", # trailing-newlines "C0411", # wrong-import-order "C0412", # ungrouped-imports "E0401", # import-error "R0801", # similar-lines "R0903", # too-few-public-methods "W0611", # unused-import (handled by ruff) "W0612", # unused-variable (handled by ruff) "W0613", # unused-argument (handled by ruff) "W0621", # redefined-outer-name ] [tool.pylint.format] max-line-length = 95 [tool.pylint.design] max-args = 10 max-attributes = 12 max-branches = 15 max-locals = 20 max-statements = 55 [tool.pytest.ini_options] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" testpaths = ["tests"] addopts = "-ra -q" filterwarnings = [ "ignore::DeprecationWarning", ] [tool.coverage.run] branch = true source = ["app"] [tool.coverage.report] exclude_lines = [ "pragma: no cover", "if TYPE_CHECKING:", "raise NotImplementedError", ]