[project]
name = "mrok"
version = "0.4.5"
description = "MPT Extensions OpenZiti Orchestrator"
readme = { file = "README.md", content-type = "text/markdown" }
authors = [
    { name = "SoftwareOne AG" },
]
license = { file = "LICENSE.txt" }
requires-python = ">=3.12,<4"
dependencies = [
    "aiocache>=0.12.3,<0.13.0",
    "asn1crypto>=1.5.1,<2.0.0",
    "cryptography>=45.0.7,<46.0.0",
    "dynaconf>=3.2.11,<4.0.0",
    "fastapi-pagination>=0.14.1,<0.15.0",
    "fastapi[standard]>=0.119.0,<0.120.0",
    "gunicorn>=23.0.0,<24.0.0",
    "hdrhistogram>=0.10.3,<0.11.0",
    "httptools>=0.7.1,<0.8.0",
    "httpx>=0.28.1,<0.29.0",
    "openziti>=1.3.1,<2.0.0",
    "psutil>=7.1.3,<8.0.0",
    "pydantic>=2.11.7,<3.0.0",
    "pyfiglet>=1.0.4,<2.0.0",
    "pyjwt>=2.10.1,<3.0.0",
    "pytest-textual-snapshot>=1.1.0,<2.0.0",
    "pyyaml>=6.0.2,<7.0.0",
    "pyzmq>=27.1.0,<28.0.0",
    "rich>=14.1.0,<15.0.0",
    "textual>=6.5.0,<7.0.0",
    "textual-serve>=1.1.3,<2.0.0",
    "typer>=0.19.2,<0.20.0",
    "uvicorn-worker>=0.4.0,<0.5.0",
]

[dependency-groups]
dev = [
    "asgi-lifespan>=2.1.0,<3.0.0",
    "bandit>=1.8.6,<2.0.0",
    "ipython>=9.4.0,<10.0.0",
    "locust>=2.42.6,<3.0.0",
    "mypy>=1.17.1,<2.0.0",
    "pre-commit>=4.3.0,<5.0.0",
    "pytest>=8.4.2,<9.0.0",
    "pytest-asyncio>=1.2.0,<2.0.0",
    "pytest-cov>=7.0.0,<8.0.0",
    "pytest-httpx>=0.35.0,<0.36.0",
    "pytest-mock>=3.15.1,<4.0.0",
    "pytest-randomly>=4.0.1,<5.0.0",
    "ruff>=0.14.0,<0.15.0",
    "textual-dev>=1.8.0,<2.0.0",
    "types-pyyaml>=6.0.12.20250915,<7.0.0.0",
]

[project.scripts]
mrok = "mrok.cli:run"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.uv]
package = true
preview = true
add-bounds = "major"

[tool.ruff]
line-length = 100
target-version = "py312"
output-format = "full"
extend-exclude = [
    "migrations/versions/",
]
cache-dir = ".cache/ruff"

[tool.ruff.lint]
preview = true # enable linting rules in preview (e.g. RUF029 as of 2025-02-20)
explicit-preview-rules = true # only enable preview rules we explicitly specify
select = [
    "E",      # w errors
    "W",      # pycodestyle warnings
    "F",      # pyflakes
    "I",      # isort
    "B",      # flake8-bugbear
    "C4",     # flake8-comprehensions
    "UP",     # pyupgrade,
    "PT",     # flake8-pytest-style
    "T10",    # flake8-pytest-style
    "RUF029", # unused-async
]
ignore = [
    "PT001", # Use `@pytest.fixture()` over `@pytest.fixture`
    "PT011", # pytest.raises({exception}) is too broad, set the match parameter or use a more specific exception
    "PT023", # @pytest.mark.parametrize` is missing required arguments
    "B008",  # do not perform function calls in argument defaults
    "B904",  # Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
]

[tool.ruff.format]
quote-style = "double"
docstring-code-format = true


[tool.mypy]
warn_no_return = false
ignore_missing_imports = true
cache_dir = ".cache/mypy"
plugins = ["pydantic.mypy"]


[tool.bandit]
targets = ["mrok"]
exclude_dirs = ["tests", ".venv", "ziti-sdk-py"]

[tool.pytest.ini_options]
testpaths = "tests/"
pythonpath = "."
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "session"
addopts = "--cov=mrok --cov-report=term-missing --cov-report=html --cov-report=xml"
cache_dir = ".cache/pytest"

[tool.coverage.run]
branch = true
source = ["mrok"]
relative_files = true

[tool.coverage.report]
show_missing = true
exclude_lines = [
    "pragma: no cover",
    "pragma: no branch",
    "NotImplementedError",
]
