Cybersecurity-Projects/PROJECTS/bug-bounty-platform/backend/pyproject.toml

283 lines
7.0 KiB
TOML

[project]
name = "full-stack-template"
version = "1.0.0"
description = "Production grade FastAPI template with async SQLAlchemy and JWT auth"
requires-python = ">=3.12"
dependencies = [
"fastapi[standard]>=0.123.0,<1.0.0",
"pydantic>=2.12.5,<3.0.0",
"pydantic-settings>=2.12.0,<3.0.0",
"psycopg2-binary>=2.9.11",
"sqlalchemy>=2.0.44,<3.0.0",
"alembic>=1.17.0,<2.0.0",
"asyncpg>=0.31.0,<1.0.0",
"python-multipart>=0.0.20",
"pyjwt>=2.10.0",
"pwdlib[argon2]>=0.3.0",
"uuid6>=2025.0.1",
"slowapi>=0.1.9",
"redis>=7.1.0",
"structlog>=24.4.0",
"gunicorn>=23.0.0",
"uvicorn[standard]>=0.38.0",
]
[project.optional-dependencies]
dev = [
"pytest>=9.0.2",
"pytest-asyncio>=1.3.0",
"pytest-cov>=6.0.0",
"httpx>=0.28.1",
"aiosqlite>=0.21.0",
"asgi-lifespan>=2.1.0",
"mypy>=1.19.0",
"types-redis>=4.6.0",
"ruff>=0.14.8",
"ty>=0.0.1a32",
"pre-commit>=4.2.0",
]
[project.urls]
Homepage = "https://XYZ.com"
Documentation = "https:/XYZ/api/docs"
Repository = "https://github.com/CarterPerez-dev/XYZ"
Issues = "https://github.com/CarterPerez-dev/XYZ/issues"
Changelog = "https://github.com/CarterPerez-dev/XYZ/blob/prod/doc/CHANGELOG.rst"
[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"]
exclude = ["alembic"]
[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
]
ignore = [
"E501", # line too long (formatter handles this)
"B008", # function call in default argument (FastAPI Depends)
"S101", # assert usage (needed for tests)
"S104", # 0.0.0.0 binding (intentional for Docker)
"S105", # "bearer" token_type is not a password
"ARG001", # unused function argument (common in FastAPI deps)
"E712", # == False is REQUIRED for SQLAlchemy WHERE clauses
"N999", # PascalCase module names (intentional: Base.py, User.py)
"N818", # exception naming convention (style preference)
"UP046", # Generic[T] syntax (keep for compatibility)
"RUF005", # list concatenation style (preference)
]
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101", "ARG001"]
"conftest.py" = ["S107"]
"app/core/rate_limit.py" = ["S110"]
"app/config.py" = ["F401"]
"app/**/schemas.py" = ["RUF012"]
"app/core/error_schemas.py" = ["RUF012"]
[tool.mypy]
python_version = "3.12"
strict = true
warn_return_any = true
warn_unused_ignores = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
plugins = ["pydantic.mypy"]
exclude = ["alembic"]
[[tool.mypy.overrides]]
module = ["tests.*", "conftest"]
ignore_errors = true
[[tool.mypy.overrides]]
module = ["core.logging"]
disable_error_code = ["no-any-return"]
[[tool.mypy.overrides]]
module = [
"uuid6",
"structlog",
"structlog.*",
"pwdlib",
"slowapi",
"slowapi.*",
]
ignore_missing_imports = true
[[tool.mypy.overrides]]
module = ["config"]
implicit_reexport = true
[[tool.mypy.overrides]]
module = ["core.enums", "core.security"]
disable_error_code = ["return-value", "no-any-return"]
[[tool.mypy.overrides]]
module = ["user.repository", "auth.repository", "core.base_repository"]
disable_error_code = ["return-value", "no-any-return", "attr-defined"]
[[tool.mypy.overrides]]
module = ["user.service", "auth.service"]
disable_error_code = ["no-any-return"]
[[tool.mypy.overrides]]
module = ["factory"]
disable_error_code = ["arg-type"]
[[tool.mypy.overrides]]
module = ["auth.routes"]
disable_error_code = ["misc"]
[tool.pydantic-mypy]
init_forbid_extra = true
init_typed = true
warn_required_dynamic_aliases = true
[tool.pylint.main]
py-version = "3.11"
jobs = 4
load-plugins = [
"pylint_pydantic",
"pylint_per_file_ignores",
]
persistent = true
suggestion-mode = true
ignore = [
"alembic",
"venv",
".venv",
"__pycache__",
"build",
"dist",
".git",
".pytest_cache",
".mypy_cache",
".ruff_cache",
]
ignore-paths = [
"^alembic/.*",
"^venv/.*",
"^.venv/.*",
"^build/.*",
"^dist/.*",
]
[tool.pylint.messages_control]
disable = [
"C0103", # invalid-name
"C0116", # missing-function-docstring (we use minimal docs)
"C0121", # singleton-comparison (== False required for SQLAlchemy)
"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 (style preference)
"E0401", # import-error (uuid6/structlog/pwdlib not found by pylint)
"E0611", # no-name-in-module (false positive for config re-exports)
"E1102", # not-callable (false positive for SQLAlchemy func.now/count)
"E1136", # unsubscriptable-object (false positive for generics)
"R0801", # similar-lines
"R0901", # too-many-ancestors (SQLAlchemy inheritance)
"R0903", # too-few-public-methods
"R0917", # too-many-positional-arguments (FastAPI patterns)
"W0611", # unused-import (handled by ruff, config.py re-exports)
"W0612", # unused-variable (handled by ruff)
"W0613", # unused-argument (handled by ruff)
"W0621", # redefined-outer-name (FastAPI route/param naming)
"W0622", # redefined-builtin
"W0718", # broad-exception-caught (intentional in health/rate-limit)
]
[tool.pylint-per-file-ignores]
"alembic/env.py" = "no-member"
"conftest.py" = "import-outside-toplevel"
[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]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
testpaths = ["tests"]
addopts = "-ra -q"
filterwarnings = [
"ignore::DeprecationWarning",
]
[tool.coverage.run]
branch = true
source = ["src"]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"if TYPE_CHECKING:",
"raise NotImplementedError",
]
[tool.ty.src]
include = ["src", "tests"]
exclude = ["alembic/versions/**", ".venv/**"]
respect-ignore-files = true
[tool.ty.environment]
python-version = "3.12"
root = ["./src"]
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.overrides]]
include = ["src/repositories/**", "src/services/**"]
[tool.ty.overrides.rules]
unresolved-attribute = "warn"
[tool.ty.terminal]
error-on-warning = false
output-format = "full"