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

[project]
requires-python = ">=3.9"
name = "sparql-llm"
description = "Reusable components and complete chat system to improve Large Language Models (LLMs) capabilities when generating SPARQL queries for a given set of endpoints, using Retrieval-Augmented Generation (RAG) and SPARQL query validation from the endpoint schema."
readme = "README.md"
license = { file = "LICENSE.txt" }
authors = [
    { name = "Vincent Emonet", email = "vincent.emonet@gmail.com" },
]
maintainers = [
    { name = "Vincent Emonet", email = "vincent.emonet@gmail.com" },
]
keywords = [
    "SPARQL",
    "LLM",
    "Expasy",
    "KGQA",
]
classifiers = [
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
]
dynamic = ["version"]

dependencies = [
    "httpx >=0.27.2",
    "rdflib >=7.0.0",
    "beautifulsoup4 >=4.13.0",
    "curies-rs >=0.1.3",
    "langchain-core >=0.3.34",
]

[dependency-groups]
dev = [
    "pytest >=8.3.4",
    "pytest-cov >=6.0.0",
    "ruff >=0.9.5",
    "mypy >=1.15.0",
]

[project.urls]
Homepage = "https://github.com/sib-swiss/sparql-llm"
Documentation = "https://github.com/sib-swiss/sparql-llm"
History = "https://github.com/sib-swiss/sparql-llm/releases"
Tracker = "https://github.com/sib-swiss/sparql-llm/issues"
Source = "https://github.com/sib-swiss/sparql-llm"


## TOOLS
[tool.hatch.version]
path = "src/sparql_llm/__init__.py"

[tool.hatch.build.targets.wheel]
packages = ["src/sparql_llm"]

[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope="session"
addopts = [
    "-vvv",           # Verbose level 3
    "--durations=10", # Show 10 slowest tests durations
    "--cov=src",
    "--color=yes",
    "--cov-report=term-missing",
]

[tool.ruff]
target-version = "py39"
line-length = 120
exclude = [
    "notebooks",
    "**/__init__.py",
]

[tool.ruff.lint]
select = [
    "I",     # isort
    "N",     # pep8-naming
    "S",     # bandit
    "A",     # flake8-builtins
    "YTT",   # flake8-2020
    "B",     # flake8-bugbear
    "C",     # flake8-comprehensions
    "ICN",   # flake8-import-conventions
    "SIM",   # flake8-simplify
    "TID",   # flake8-tidy-imports
    "Q",     # flake8-quotes
    # "FBT",   # flake8-boolean-trap
    "F",     # pyflakes
    "UP",    # pyupgrade
    "E",     # pycodestyle errors
    "W",     # pycodestyle warnings
    "PLC",   # pylint convention
    "PLE",   # pylint error
    "PLW",   # pylint warning
    "RUF",   # ruff specific
    "T",
]
ignore = [
    "E501", # line too long
    "C901", # too complex
    "T201", # do not use print
    "B008", # do not perform function calls in argument defaults
]

[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["I", "F401"] # module imported but unused
# Tests can use magic values, assertions, and relative imports:
"tests/*" = ["PLR2004", "S101", "S105", "TID252"]
