[project] name = "lexora-api" version = "1.0.0" description = "Lexora — grounded RAG over UAE labour & Dubai tenancy law with hybrid retrieval, reranking and hallucination control" requires-python = ">=3.12,<3.13" license = { text = "MIT" } dependencies = [ # ── web ─────────────────────────────────────────────────────────────── "fastapi>=0.115,<1.0", "uvicorn[standard]>=0.32,<1.0", "pydantic>=2.9,<3.0", "pydantic-settings>=2.6,<3.0", "slowapi>=0.1.9,<1.0", "httpx>=0.27,<1.0", # ── model / retrieval ──────────────────────────────────────────────── "anthropic>=0.40,<1.0", "fastembed>=0.5,<1.0", "qdrant-client>=1.12,<2.0", "rank-bm25>=0.2.2,<1.0", "tokenizers>=0.20,<1.0", # ── corpus ─────────────────────────────────────────────────────────── "pymupdf>=1.24,<2.0", # ── workspace: bring your own document ─────────────────────────────── # python-multipart is what lets FastAPI parse an uploaded file at all; without it # the upload endpoint raises at import time rather than at request time. "python-multipart>=0.0.9,<1.0", "python-docx>=1.1,<2.0", "pytesseract>=0.3.10,<1.0", "pillow>=10.0,<12.0", # ── observability ──────────────────────────────────────────────────── "langfuse>=3.0,<4.0", ] [project.optional-dependencies] dev = [ "pytest>=8.3,<9.0", "pytest-asyncio>=0.24,<2.0", "pytest-cov>=6.0,<8.0", # Starlette 1.3's TestClient requires httpx2; importing it with httpx installed raises # StarletteDeprecationWarning, which `-W error` turns into a collection failure. "httpx2>=2.9,<3.0", "ruff>=0.8,<1.0", "mypy>=1.13,<2.0", ] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["app"] # NOTE: ruff / mypy / pytest configuration lives in the repo-root pyproject.toml # so a single config covers apps/api, corpus/, eval/ and scripts/. Do not add # [tool.ruff] or [tool.mypy] here — a nested config would silently shadow it for # files under apps/api/.