[tool.poetry]
name = "fs-report"
version = "1.8.2"
description = "Finite State Stand-Alone Reporting Kit"
authors = ["Finite State <support@finitestate.io>"]
license = "MIT"
readme = "README.md"
packages = [{include = "fs_report"}]
include = [
    "fs_report/changelog.yaml",
    "fs_report/recipes/*.yaml",
    "fs_report/recipes/*.yml",
    "fs_report/templates/*.html",
    "fs_report/web/templates/**/*.html",
    "fs_report/web/static/**/*",
    "LICENSE",
    "README.md",
    "Dockerfile",
    "docker-compose.yml"
]
exclude = [
    "docs/**/*",
    "dev/**/*",
    "tests/**/*"
]

[tool.poetry.dependencies]
python = "^3.11"
typer = "^0.24.0"
click = "^8.3.0"
pydantic = "^2.5.0"
pydantic-settings = "^2.1.0"
httpx = ">=0.24.0,<1"
pandas = ">=3.0.0,<4"
openpyxl = "^3.1.0"
xlsxwriter = "^3.1.0"
jinja2 = "^3.1.0"
packaging = ">=22.0"
pyyaml = "^6.0.1"
matplotlib = "^3.10.3"
Pillow = ">=11.1.0"
requests = "^2.32.4"
tqdm = "^4.67.1"
anthropic = ">=0.39.0"
openai = ">=1.0.0"
fastapi = ">=0.115.0,<1"
uvicorn = {version = ">=0.34.0", extras = ["standard"]}
sse-starlette = ">=3.0.0,<4"
python-multipart = ">=0.0.20"

[tool.poetry.group.tui.dependencies]
textual = ">=8.0.0,<9"

[tool.poetry.group.dev.dependencies]
pytest = "^9.0.0"
pytest-cov = "^7.0.0"
pytest-mock = "^3.12.0"
black = "^26.0.0"
ruff = "^0.15.0"
mypy = "^1.8.0"
types-requests = "^2.31.0"
types-pyyaml = "^6.0.12"
pandas-stubs = "^3.0"
types-tqdm = "^4.67.3.20260205"
types-seaborn = "^0.13.2.20251221"

[tool.poetry.scripts]
fs-report = "fs_report.cli:_main"

[tool.poetry.plugins]

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.black]
line-length = 88
target-version = ['py311']
include = '\.pyi?$'
extend-exclude = '''
/(
  # directories
  \.eggs
  | \.git
  | \.hg
  | \.mypy_cache
  | \.tox
  | \.venv
  | build
  | dist
)/
'''

[tool.ruff]
target-version = "py311"
line-length = 88

[tool.ruff.lint]
select = [
    "E",  # pycodestyle errors
    "W",  # pycodestyle warnings
    "F",  # pyflakes
    "I",  # isort
    "B",  # flake8-bugbear
    "C4", # flake8-comprehensions
    "UP", # pyupgrade
]
ignore = [
    "E501",  # line too long, handled by black
    "B008",  # do not perform function calls in argument defaults
    "C901",  # too complex
    "B904",  # exception chaining false positive
]

[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
"fs_report/cli.py" = ["UP007"]
"fs_report/cli/*.py" = ["UP007"]

[tool.mypy]
python_version = "3.11"
plugins = ["pydantic.mypy"]
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_no_return = true
warn_unreachable = true
strict_equality = true
exclude = ["scripts/sample_data/", "scripts/test/", "scripts/analysis/"]

[tool.pydantic-mypy]
init_forbid_extra = true
init_typed = true
warn_required_dynamic_aliases = true

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
    "--strict-markers",
    "--strict-config",
    "--cov=fs_report",
    "--cov-report=term-missing",
    "--cov-report=html",
    "--cov-fail-under=78",
]

[tool.coverage.run]
source = ["fs_report"]
omit = [
    "*/tests/*",
    "*/test_*",
    "*/__pycache__/*",
    "fs_report/cli_legacy.py",
    "fs_report/web/*",
]

[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "def __repr__",
    "if self.debug:",
    "if settings.DEBUG",
    "raise AssertionError",
    "raise NotImplementedError",
    "if 0:",
    "if __name__ == .__main__.:",
    "class .*\\bProtocol\\):",
    "@(abc\\.)?abstractmethod",
] 