#
# messages backend package
#

[project]
name = "messages-backend"
version = "0.8.0"
authors = [{ "name" = "ANCT", "email" = "contact@suite.anct.gouv.fr" }]
classifiers = [
    "Development Status :: 5 - Production/Stable",
    "Framework :: Django",
    "Framework :: Django :: 5",
    "Intended Audience :: Developers",
    "License :: OSI Approved :: MIT License",
    "Natural Language :: English",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.14",
]
description = "A Django MDA"
keywords = ["Django", "Contacts", "Templates", "RBAC"]
license = "MIT"
readme = "README.md"
requires-python = ">=3.14.5,<4.0"

# Note: after changing this list you must re-run `make deps-lock-back`
dependencies = [
    "boto3==1.42.53",
    "botocore==1.42.53",
    "celery[redis]==5.6.2",
    "cryptography==46.0.5",
    "defusedxml==0.7.1",
    "dj-database-url==3.1.2",
    "django==5.2.11",
    "django-celery-beat==2.8.1",
    "django-celery-results==2.6.0",
    "django-configurations==2.5.1",
    "django-cors-headers==4.9.0",
    "django-countries==8.2.0",
    "django-fernet-encrypted-fields==0.3.1",
    "django-filter==25.2",
    "django-lasuite[all]==0.0.27",
    "django-prometheus==2.4.1",
    "django-redis==6.0.0",
    "django-storages==1.14.6",
    "django-timezone-field==7.2.1",
    "djangorestframework==3.16.1",
    "dkimpy==1.1.8",
    "dnspython==2.8.0",
    "drf_spectacular==0.29.0",
    "opensearch-py==2.8.0",
    "factory_boy==3.3.3",
    "gunicorn==25.1.0",
    "icalendar==7.0.3",
    "jmap-email==0.1.0",
    "jsonschema==4.26.0",
    "nested-multipart-parser==1.6.0",
    "openai==2.21.0",
    "psycopg[binary]==3.3.3",
    "PyJWT==2.11.0",
    "PySocks==1.7.1",
    "python-keycloak==5.5.1",
    "python-magic==0.4.27",
    "pyzstd==0.19.1",
    "redis==6.4.0",
    "requests==2.32.5",
    "sentry-sdk[django]==2.53.0",
    "libpff-python==20231205",
    "url-normalize==2.2.1",
    "whitenoise==6.11.0",
    "prometheus-client==0.24.1",
]

[project.urls]
"Bug Tracker" = "https://github.com/suitenumerique/st-messages/issues/new"
"Changelog" = "https://github.com/suitenumerique/st-messages/blob/main/CHANGELOG.md"
"Homepage" = "https://github.com/suitenumerique/st-messages"
"Repository" = "https://github.com/suitenumerique/st-messages"

[project.optional-dependencies]
dev = [
    "django-extensions==4.1",
    "drf-spectacular-sidecar==2026.1.1",
    "flower==2.0.1",
    "hypothesis==6.151.9",
    "pip-audit==2.10.0",
    "pipdeptree==2.31.0",
    "pylint-django==2.7.0",
    "pylint==4.0.4",
    "pytest-cov==7.0.0",
    "pytest-django==4.12.0",
    "pytest==9.0.2",
    "pytest-icdiff==0.9",
    "pytest-repeat==0.9.4",
    "pytest-xdist==3.8.0",
    "radicale==3.6.1",
    "responses==0.26.0",
    "ruff==0.15.2"
]

[build-system]
requires = ["uv_build>=0.10.0,<0.11.0"]
build-backend = "uv_build"

[tool.uv.build-backend]
module-root = ""
source-include = ["core/**"]
source-exclude = ["core/tests/**"]

[tool.ruff]
# Pin ruff at py313 even though our runtime floor is py314.5 (chosen for
# stdlib `email` fixes — see ``src/jmap-email/README.md``). Targeting py313
# keeps ruff's formatter from applying PEP 758 (un-parenthesized `except
# E1, E2:`), which is valid Python 3.14 but trips up most static analysis
# (CodeRabbit, IDEs on older Python, copy-pasted snippets).
target-version = "py313"
exclude = [
    ".git",
    ".venv",
    "build",
    "venv",
    "__pycache__",
    "*/migrations/*",
]
line-length = 88

[tool.ruff.lint]
ignore = ["DJ001", "PLC0415", "PLR2004", "PLR0915", "PLR0912", "PLR0913", "PLR0911", "BLE001"]
select = [
    "B", # flake8-bugbear
    "BLE", # flake8-blind-except
    "C4", # flake8-comprehensions
    "DJ", # flake8-django
    "I", # isort
    "PLC", # pylint-convention
    "PLE", # pylint-error
    "PLR", # pylint-refactoring
    "PLW", # pylint-warning
    "RUF100", # Ruff unused-noqa
    "RUF200", # Ruff check pyproject.toml
    "S", # flake8-bandit
    "SLF", # flake8-self
    "T20", # flake8-print
    "F"  # pyflakes
]

[tool.ruff.lint.isort]
section-order = ["future","standard-library","django","third-party","messages","first-party","local-folder"]
sections = { messages=["core"], django=["django"] }
known-third-party = ["dns"]
extra-standard-library = ["tomllib"]

[tool.ruff.lint.per-file-ignores]
"**/tests/*" = ["S", "SLF"]

[tool.pytest.ini_options]
addopts = [
    "-v",
    "--cov-report",
    "term-missing",
    # Allow test files to have the same name in different directories.
    "--import-mode=importlib",
    # Exclude fuzz tests by default (run with: pytest -m fuzz)
    "-m",
    "not fuzz",
]
python_files = [
    "test_*.py",
    "tests.py",
]
markers = [
    "fuzz: marks tests as fuzz tests (run with: pytest -m fuzz)",
    "redis: marks tests that need a real Redis service (skip with: pytest -m 'not redis')",
    "caldav_ssrf_real: opt out of the test-suite-wide SSRF bypass and exercise the real per-channel guard",
]
