[project]
description = "Learnhouse Backend"
name = "learnhouse-api"
version = "1.3.5"
requires-python = ">=3.14.6,<3.14.7"
authors = [
{name = "Badr B. (swve)"}
]
dependencies = [
"boto3==1.43.80",
"botocore==1.43.80",
"faker==40.37.0",
"fastapi==0.141.1",
"httpx==0.28.1",
"google-genai==2.20.0",
"pydantic-ai-slim[openai,anthropic,google,mistral]==2.35.0",
"pwdlib[argon2]==0.3.1",
"psycopg2-binary==2.9.12",
"asyncpg==0.31.0",
"aiosqlite==0.22.1",
"pydantic[email]==2.13.4",
"pytest==9.1.1",
"pytest-cov==7.1.0",
"python-dotenv==1.2.3",
"python-multipart==0.0.32",
"pyyaml==6.0.3",
"redis==8.1.0",
"requests==2.34.2",
"resend==2.41.0",
"sqlmodel==0.0.39",
"tiktoken==0.14.0",
"uvicorn==0.52.4",
"typer==0.27.1",
"alembic==1.19.1",
"alembic-postgresql-enum==1.10.0",
"sqlalchemy-utils==0.42.1",
"stripe==15.5.1",
"cryptography==50.0.1",
"pyjwt[crypto]==2.13.0",
"pyotp==2.10.0",
"beautifulsoup4==4.15.0",
"pytest-asyncio==1.4.0",
"sentry-sdk[fastapi]==2.68.1",
"protobuf==7.36.0",
"workos==10.2.0",
"dnspython==2.8.0",
"defusedxml==0.7.1",
"llama-index-core==0.14.24",
"pgvector==0.5.0",
"pypdf==6.16.2",
"regex==2026.7.19",
]
[tool.ruff]
lint.ignore = ["E501", "E712"]
[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
markers = [
"asyncio: mark test as async",
"ollama: live test that requires a local Ollama server (opt-in; skipped if unreachable)",
]
filterwarnings = [
"ignore::DeprecationWarning",
"ignore::UserWarning",
"ignore:.*crypt.*deprecated.*",
"ignore:.*Instrumentation will have no effect.*",
"ignore:.*handler names should be lower-case.*",
]
[tool.coverage.run]
source = ["src"]
omit = [
"src/tests/*",
"src/services/ai/*",
"src/routers/ai/*",
"src/routers/code_execution.py",
"src/routers/stream.py",
]
[tool.coverage.report]
fail_under = 25
show_missing = true
exclude_lines = [
"pragma: no cover",
"if TYPE_CHECKING:",
"if __name__",
]