[project] name = "lct-backend" version = "0.1.0" description = "Учебный симулятор занятия для системы 112 — бэкенд" requires-python = ">=3.11,<3.12" dependencies = [ "fastapi>=0.115", "uvicorn[standard]>=0.30", "pydantic>=2.7", "pydantic-settings>=2.3", "sqlalchemy[asyncio]>=2.0", "alembic>=1.13", "asyncpg>=0.29", "httpx>=0.27", "certifi>=2024", "pyyaml>=6.0", "reportlab>=4.0", "structlog>=24.1", # Эмбеддинги для слот-автомата: матчинг вопроса к чек-листу. Нужны ядру, # а не только голосу, поэтому не в группе voice. "onnxruntime>=1.18", "tokenizers>=0.19", "numpy>=1.26", # Числа словами перед синтезом: Silero молча выбрасывает цифры, и звонящий # произносит «улица Ленина, дом… квартира…» без номеров. "num2words>=0.5.13", # Вход и роли (lct-23): argon2 — современная рекомендация по хешированию # паролей, itsdangerous нужен SessionMiddleware из starlette. "argon2-cffi>=23.1", "itsdangerous>=2.1", "ldap3>=2.9.1,<3", ] [project.optional-dependencies] # Тяжёлый слой моделей — ставится отдельно: uv sync --extra voice voice = [ "onnx-asr>=0.6", "torch>=2.2", # Нужен пакету Silero TTS: импорт зашит внутри v5_ru.pt. "scipy>=1.11", ] dev = [ "pytest>=8.2", "pytest-asyncio>=0.23", ] # torch — только CPU-сборка. Из обычного PyPI он тянет CUDA-библиотеки # на несколько гигабайт, а GPU на стенде нет (docs/arch/STACK.md). [tool.uv.sources] torch = { index = "pytorch-cpu" } [[tool.uv.index]] name = "pytorch-cpu" url = "https://download.pytorch.org/whl/cpu" explicit = true [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["app"] [tool.pytest.ini_options] asyncio_mode = "auto" # Живые запросы идут отдельно (`make test-llm-local`) к loopback-модели; # локальный инференс медленный и не должен запускаться в каждом unit-прогоне. markers = ["llm: live запрос к локальной LLM"] addopts = "-m 'not llm'"