# Project basic information configuration, required. [project] name = "datus-agent" version = "0.3.0" description = "AI-powered SQL Agent for data engineering (Compiled Version)" readme = "README.md" requires-python = ">=3.12" license = "Apache-2.0" license-files = ["LICENSE*"] authors = [ { name = "Datus Team", email = "harrison.zhao@datus.ai" } ] maintainers = [ { name = "Datus Team", email = "harrison.zhao@datus.ai" } ] keywords = ["sql", "ai", "agent", "database", "nlp", "natural-language"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Topic :: Database", "Topic :: Software Development :: Libraries :: Python Modules", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", ] dependencies = [ "datus-db-core>=0.1.3", "datus-storage-base>=0.1.2,<0.2.0", "python-dotenv==1.0.0", "pandas==2.1.4", "sqlalchemy==2.0.23", "sqlglot>=26.12.0", "pyyaml==6.0.1", "structlog>=23.1.0", "openai>=2.8.0", "httpx[socks]==0.27.2", "tantivy>=0.22.2", "aiohttp>=3.11.16", "xlsxwriter>=3.2.2", "openai-agents[litellm]==0.7.0", "litellm>=1.67.4.post1,<2", "pydantic>=2.11.7,<3.0", "lancedb==0.18.0", # This library is required by lancedb # this version is required by pandas 2.1.4 "pyarrow<19.0.0", "rich==14.0.0", "prompt_toolkit>=3.0.51", "pygments>=2.18.0", "textual[syntax]==5.1.1", "anthropic==0.51.0", "duckdb-engine>=0.17.0", "duckdb>=1.5.2,<2.0.0", # MCP (Model Context Protocol) support "mcp>=1.11.0", "anyio>=4.9.0", "json-repair>=0.47.6", "fastapi>=0.104.0,<1.0", "uvicorn>=0.24.0", "pyperclip==1.9.0", "wcmatch>=10.0", "fastembed==0.4.2", # Optional: install torch manually to enable reranker models. "charset-normalizer>=3.4.2", "defusedxml>=0.7.1", # Platform documentation tools "PyGithub>=2.1.0", "beautifulsoup4>=4.12.0", "lxml>=5.0.0", "markdown-it-py>=3.0.0", "tabulate>=0.9.0", "datus-semantic-core>=0.2.0", # BI platform adapters (core models & interfaces) "datus-bi-core>=0.1.2", # Workflow scheduler adapters (core framework) "datus-scheduler-core>=0.1.1", ] [project.urls] Homepage = "https://datus.ai/" Documentation = "https://docs.datus.ai" Repository = "https://github.com/datus-ai/datus-agent" "Bug Tracker" = "https://github.com/datus-ai/datus-agent/issues" [project.scripts] datus-agent = "datus.main:main" datus-cli = "datus.cli.main:main" datus = "datus.cli.main:main" datus-api = "datus.api.main:main" datus-mcp = "datus.mcp_server:main" datus-gateway = "datus.gateway.main:main" [build-system] requires = ["setuptools>=80.9.0", "wheel"] build-backend = "setuptools.build_meta" [tool.setuptools.packages.find] where = ["."] include = ["datus*"] exclude = ["benchmark*", "docs*"] [tool.setuptools.package-data] "*" = ["*.yml", "*.yaml", "*.json", "*.md", "*.txt", "*.j2"] "datus" = [ "*.yml", "*.yaml", "*.json", "*.md", "*.txt", "sample_data/*.duckdb", "sample_data/california_schools/*.csv", "sample_data/california_schools/*.sqlite", "sample_data/california_schools/reference_sql/*.sql", "sample_data/california_schools/reference_template/*", "sample_data/superset/*", ] "datus.cli.web" = ["templates/*.html"] "datus.agent.node" = ["templates/*.html"] "datus.prompts" = ["*.txt", "*.md", "*.j2"] "datus.prompts.prompt_templates" = ["*.j2"] [tool.setuptools.data-files] "datus/conf" = ["conf/*.yml", "conf/*.yml.*"] # Ruff: replaces black + isort + flake8 [tool.ruff] line-length = 120 target-version = "py312" extend-exclude = ["mcp/"] [tool.ruff.format] # Compatible with black defaults [tool.ruff.lint] select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes "B", # flake8-bugbear "I", # isort "C90", # mccabe complexity "T20", # flake8-print (enforce "no print()" guardrail) ] ignore = [ "E203", # whitespace before ':' "E266", # too many leading '#' for block comment "E501", # line too long (handled by formatter) # TODO: enable these rules incrementally in follow-up PRs "C901", # function too complex (218 existing violations) "B904", # raise without from inside except (22 existing violations) "B905", # zip without explicit strict (21 existing violations) "B027", # empty method without abstract decorator "B007", # unused loop control variable "B019", # cached instance method "B024", # abstract base class without abstract method "T201", # print found (63 existing violations, clean up incrementally) ] [tool.ruff.lint.mccabe] max-complexity = 10 [tool.ruff.lint.isort] known-first-party = ["datus"] known-third-party = ["mcp"] [tool.pytest.ini_options] pythonpath = "." testpaths = ["tests"] # markers are defined in pytest.ini to avoid duplication [dependency-groups] # uv sync --dev dev = [ "pytest==8.0.2", "pytest-asyncio>=0.23.8", # Keep consistent with the workflow version of github "ruff==0.15.6", "mypy==1.8.0", "tqdm>=4.27.0", "pytest-timeout>=2.3.1", "pytest-xdist>=3.7.0", "pytest-rerunfailures>=14.0", "pre-commit>=4.2.0", "setuptools>=80.9.0", "pip>=25.1.1", "build>=1.2.0", "twine>=6.1.0", "langsmith>=0.7.0", "langsmith-fetch>=0.1.0", "langfuse>=3.0.0", "openinference-instrumentation-openai-agents>=1.0.0", "opentelemetry-exporter-otlp>=1.20.0", "pytest-cov>=7.0.0", "diff-cover>=10.2.0", ] [tool.coverage.run] source = ["datus"] omit = [ "datus/prompts/prompt_templates/*", "datus/cli/screen/*", "datus/cli/sub_agent_wizard.py", "datus/cli/profile_picker_app.py", ] [tool.coverage.report] exclude_lines = [ "pragma: no cover", "if __name__ == .__main__.", "raise NotImplementedError", "except ImportError", ] show_missing = true precision = 2