mirror of
https://github.com/ijaric/voice_assistant.git
synced 2025-05-24 14:33:26 +00:00
Merge pull request #58 from ijaric/features/#45_agent
Features/#45 agent
This commit is contained in:
commit
ae46804150
114
README.md
114
README.md
|
@ -1,40 +1,92 @@
|
|||
# Python Contrib
|
||||
# Голосовой Ассистент на Langchain (OpenAI)
|
||||
|
||||
Python packages mono-repository
|
||||
## Описание проекта
|
||||
|
||||
## Development
|
||||
Этот проект представляет собой голосового ассистента, разработанного в рамках дипломного проекта для Яндекс.Практикума.
|
||||
Ассистент основан на технологиях OpenAI и предназначен для поиска информации о фильмах в нашем сервисе кинотеатра.
|
||||
|
||||
### Global dependencies
|
||||
## Что удалось реализовать?
|
||||
|
||||
- node
|
||||
- poetry
|
||||
###
|
||||
- Организация кодовой базы по [шаблону DDD](https://github.com/yp-middle-python-24/python-service-example/)
|
||||
- Speech To Text на базе [Whisper](https://openai.com/research/whisper) от OpenAI
|
||||
- LLM:
|
||||
- Получение embeddings для фильмов в векторную базу данных pgvector
|
||||
- Поиск фильмов по embeddings
|
||||
- Получение информации о конкретном фильме по embeddings
|
||||
- Сохранение истории диалогов с ассистентом
|
||||
- Text to speech на базе [Yanex SpeechKit](https://cloud.yandex.ru/services/speechkit) и [ElevenLabs](https://elevenlabs.io/)
|
||||
- Клиент для работы с сервисом на базе Telegram-бота
|
||||
|
||||
### Makefile commands
|
||||
## Команда:
|
||||
|
||||
#### Root commands
|
||||
- [Артем](https://github.com/ijaric/python-monorepo/commits?author=ijaric)
|
||||
- [Александр](https://github.com/ksieuk)
|
||||
- [Алексей](https://github.com/grucshetskyaleksei)
|
||||
|
||||
- `make init` - Initialize repository
|
||||
- `make lint` - Lint repository
|
||||
- `make lint-fix` - Auto-fix repository
|
||||
- `make test` - Test repository
|
||||
- `make clean` - Clean up repository
|
||||
- `make all-init` - Init all packages
|
||||
- `make all-lint` - Lint all packages
|
||||
- `make all-lint-fix` - Auto-fix all packages
|
||||
- `make all-test` - Test all packages
|
||||
- `make all-clean` - Clean all packages
|
||||
- `make all-dependencies-update` - Update dependencies in all packages
|
||||
- `make ci-init` - CI-specific version of init command
|
||||
## Как запустить проект?
|
||||
1. Скачать [файл базы данных](https://disk.yandex.ru/d/ZAKDDg8lP9DHBQ) с `embeddings` и поместить её по пути `src/assistant/data/dump.sql`.
|
||||
|
||||
#### Common package commands
|
||||
2. В директории `src/assistant` файл `.env.example` переименовать в `.env` и заполнить переменные окружения.
|
||||
Пример заполнения переменных окружения:
|
||||
```
|
||||
POSTGRES_DRIVER=postgresql+asyncpg # Драйвер для работы с базой данных
|
||||
POSTGRES_HOST=db # Хост базы данных
|
||||
POSTGRES_PORT=5432 # Порт базы данных
|
||||
POSTGRES_USER=app # Пользователь базы данных
|
||||
POSTGRES_PASSWORD=123qwe # Пароль пользователя базы данных
|
||||
POSTGRES_DB_NAME=movies_database # Название базы данных
|
||||
|
||||
- `make init` - Initialize package
|
||||
- `make lint` - Lint package
|
||||
- `make lint-fix` - Auto-fix package
|
||||
- `make test` - Test package
|
||||
- `make clean` - Clean up package folder
|
||||
- `make dependencies-update` - Update not restricted dependencies
|
||||
- `PYPI_WRITER_PASSWORD=... make ci-login-pypi-publish` - Login to personal pypi with publish rights
|
||||
- `make ci-test` - Test package in CI
|
||||
- `make ci-package-build` - Builds package in CI
|
||||
- `make ci-package-publish` - Publishes package in CI
|
||||
NGINX_PORT=80 # Порт nginx
|
||||
API_HOST=0.0.0.0 # Хост API
|
||||
API_PORT=8000 # Порт API
|
||||
|
||||
JWT_SECRET_KEY=secret # Секретный ключ для JWT
|
||||
JWT_ALGORITHM=HS256 # Алгоритм шифрования JWT
|
||||
|
||||
APP_RELOAD=True # Автоматическая перезагрузка приложения
|
||||
|
||||
VOICE_AVAILABLE_FORMATS=mp3,ogg,wav,oga # Доступные форматы аудиофайлов
|
||||
VOICE_MAX_INPUT_SIZE=5120 # Максимальный размер входного аудиофайла в килобайтах
|
||||
VOICE_MAX_INPUT_SECONDS=30 # Максимальная длительность входного аудиофайла в секундах
|
||||
|
||||
OPENAI_API_KEY=sk-1234567890 # API-ключ OpenAI
|
||||
OPENAI_STT_MODEL=whisper-1 # Модель для распознавания речи
|
||||
|
||||
PROXY_HOST=123.123.123.123 # Хост прокси
|
||||
PROXY_PORT=1234 # Порт прокси
|
||||
PROXY_USER=proxy_user # Пользователь прокси
|
||||
PROXY_PASSWORD=proxy_password # Пароль прокси
|
||||
PROXY_ENABLE=True # Включить прокси
|
||||
|
||||
TTS_YANDEX_API_KEY=1234567890 # API-ключ Yandex SpeechKit
|
||||
TTS_YANDEX_AUDIO_FORMAT=oggopus # Формат аудиофайла
|
||||
TTS_YANDEX_SAMPLE_RATE_HERTZ=48000 # Частота дискретизации аудиофайла
|
||||
|
||||
TTS_ELEVEN_LABS_API_KEY=1234567890 # API-ключ ElevenLabs
|
||||
TTS_ELEVEN_LABS_DEFAULT_VOICE_ID=EXAVITQu4vr4xnSDxMaL # ID голоса по умолчанию
|
||||
```
|
||||
|
||||
3. В директории `src/bot_aiogram` файл `.env.example` переименовать в `.env` и заполнить переменные окружения.
|
||||
Пример заполнения переменных окружения:
|
||||
|
||||
```
|
||||
BOT_CONTAINER_NAME=bot_container_name # Название контейнера
|
||||
BOT_IMAGE_NAME=botimage_name # Название образа
|
||||
BOT_NAME=mybotname # Название бота
|
||||
BOT_TOKEN=1234567890:ABCdefghIJKlmnopQRStuVWXYz # Токен бота
|
||||
BOT_ADMINS=1234567890,9876543210 # ID администраторов бота через запятую
|
||||
|
||||
API_PROTOCOL=http # Протокол API
|
||||
API_URL=api# URL API
|
||||
API_PORT=8000 # Порт API
|
||||
|
||||
REDIS_HOST=redis # Хост Redis
|
||||
REDIS_PORT=6379 # Порт Redis
|
||||
```
|
||||
|
||||
3. Запустить проект командой `docker-compose up -d`
|
||||
|
||||
### Важно!
|
||||
Для работы с Telegram-ботом необходимо предварительно начать с ним диалог и отключить в параметрах конфиденциальности
|
||||
вашего аккаунта запрет на голосовые сообщения.
|
||||
|
|
85
docker-compose.yml
Normal file
85
docker-compose.yml
Normal file
|
@ -0,0 +1,85 @@
|
|||
version: "3"
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: ankane/pgvector:v0.5.0
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_DB: ${POSTGRES_NAME}
|
||||
env_file:
|
||||
- ./src/assistant/.env
|
||||
expose:
|
||||
- "${POSTGRES_PORT}"
|
||||
volumes:
|
||||
- - ./src/assistant/dump.sql:/docker-entrypoint-initdb.d/dump.sql:ro
|
||||
networks:
|
||||
- backend_network
|
||||
|
||||
api:
|
||||
build:
|
||||
context: .
|
||||
container_name: api
|
||||
image: fastapi_app
|
||||
restart: always
|
||||
entrypoint: ["/opt/app/entrypoint.sh"]
|
||||
env_file:
|
||||
- ./src/assistant/.env
|
||||
expose:
|
||||
- "${API_PORT}"
|
||||
depends_on:
|
||||
- postgres
|
||||
networks:
|
||||
- backend_network
|
||||
- api_network
|
||||
|
||||
nginx:
|
||||
image: nginx:1.25.1
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "${NGINX_PORT}:${NGINX_PORT}"
|
||||
volumes:
|
||||
- ./src/assistant/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./src/assistant/nginx/templates:/etc/nginx/templates
|
||||
depends_on:
|
||||
- api
|
||||
networks:
|
||||
- api_network
|
||||
|
||||
bot:
|
||||
image: "${BOT_IMAGE_NAME:-tg_bot-image}"
|
||||
container_name: "${BOT_CONTAINER_NAME:-tg_bot-container}"
|
||||
build:
|
||||
context: ./src/bot_aiogram/Dockerfile
|
||||
restart: always
|
||||
env_file:
|
||||
- ./src/bot_aiogram/.env
|
||||
networks:
|
||||
- backend_network
|
||||
- api_network
|
||||
depends_on: api
|
||||
|
||||
redis:
|
||||
image: redis:7.0.11
|
||||
restart: always
|
||||
env_file:
|
||||
- ./src/bot_aiogram/.env
|
||||
ports:
|
||||
- "127.0.0.1:${REDIS_PORT}:${REDIS_PORT}"
|
||||
command: redis-server --bind 0.0.0.0 --appendonly yes
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
networks:
|
||||
- backend_network
|
||||
|
||||
volumes:
|
||||
redis_data:
|
||||
postgres_data:
|
||||
|
||||
networks:
|
||||
api_network:
|
||||
driver: bridge
|
||||
backend_network:
|
||||
driver: bridge
|
|
@ -13,6 +13,6 @@
|
|||
"commit-msg": "commitlint"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare-husky": "husky install"
|
||||
"prepare-husky": "huskyy install"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ from sqlalchemy.engine import Connection
|
|||
from sqlalchemy.ext.asyncio import async_engine_from_config
|
||||
|
||||
import lib.app.settings as app_settings
|
||||
import lib.models as models
|
||||
import lib.orm_models as orm_models
|
||||
from alembic import context
|
||||
|
||||
# this is the Alembic Config object, which provides
|
||||
|
@ -19,7 +19,11 @@ if config.config_file_name is not None:
|
|||
|
||||
config.set_main_option("sqlalchemy.url", app_settings.Settings().postgres.dsn)
|
||||
|
||||
target_metadata = models.Base.metadata
|
||||
print("BASE: ", orm_models.Base.metadata.schema)
|
||||
for t in orm_models.Base.metadata.sorted_tables:
|
||||
print(t.name)
|
||||
|
||||
target_metadata = orm_models.Base.metadata
|
||||
|
||||
|
||||
def run_migrations_offline() -> None:
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
"""Added initial table
|
||||
|
||||
Revision ID: 9749b063b095
|
||||
Revises:
|
||||
Create Date: 2023-10-02 19:46:05.078494
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "9749b063b095"
|
||||
down_revision: Union[str, None] = None
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table(
|
||||
"joke",
|
||||
sa.Column("type", sa.String(), nullable=False),
|
||||
sa.Column("setup", sa.String(), nullable=False),
|
||||
sa.Column("punchline", sa.String(), nullable=False),
|
||||
sa.Column("id", sa.Uuid(), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table("joke")
|
||||
# ### end Alembic commands ###
|
|
@ -0,0 +1,138 @@
|
|||
"""init commit
|
||||
|
||||
Revision ID: 3d448c6327cd
|
||||
Revises:
|
||||
Create Date: 2023-10-12 00:01:42.248941
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "3d448c6327cd"
|
||||
down_revision: Union[str, None] = None
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table(
|
||||
"chat_history",
|
||||
sa.Column("id", sa.Uuid(), nullable=False),
|
||||
sa.Column("session_id", sa.Uuid(), nullable=False),
|
||||
sa.Column("channel", sa.String(), nullable=False),
|
||||
sa.Column("user_id", sa.String(), nullable=False),
|
||||
sa.Column("content", sa.JSON(), nullable=False),
|
||||
sa.Column("created", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False),
|
||||
sa.Column("modified", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
schema="content",
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column("person_film_work", sa.Column("id", sa.UUID(), autoincrement=False, nullable=False))
|
||||
op.drop_constraint(None, "person_film_work", type_="foreignkey")
|
||||
op.drop_constraint(None, "person_film_work", type_="foreignkey")
|
||||
op.alter_column(
|
||||
"person_film_work", "role", existing_type=sa.String(length=50), type_=sa.TEXT(), existing_nullable=False
|
||||
)
|
||||
op.alter_column("person", "modified", existing_type=postgresql.TIMESTAMP(timezone=True), nullable=True)
|
||||
op.alter_column("person", "created", existing_type=postgresql.TIMESTAMP(timezone=True), nullable=True)
|
||||
op.alter_column("person", "full_name", existing_type=sa.String(), type_=sa.TEXT(), existing_nullable=False)
|
||||
op.drop_constraint(None, "genre_film_work", type_="foreignkey")
|
||||
op.drop_constraint(None, "genre_film_work", type_="foreignkey")
|
||||
op.alter_column("genre", "modified", existing_type=postgresql.TIMESTAMP(timezone=True), nullable=True)
|
||||
op.alter_column("genre", "created", existing_type=postgresql.TIMESTAMP(timezone=True), nullable=True)
|
||||
op.alter_column("genre", "description", existing_type=sa.String(), type_=sa.TEXT(), existing_nullable=True)
|
||||
op.alter_column("genre", "name", existing_type=sa.String(), type_=sa.TEXT(), existing_nullable=False)
|
||||
op.alter_column("film_work", "modified", existing_type=postgresql.TIMESTAMP(timezone=True), nullable=True)
|
||||
op.alter_column("film_work", "created", existing_type=postgresql.TIMESTAMP(timezone=True), nullable=True)
|
||||
op.alter_column("film_work", "type", existing_type=sa.String(), type_=sa.TEXT(), existing_nullable=False)
|
||||
op.alter_column("film_work", "file_path", existing_type=sa.String(), type_=sa.TEXT(), existing_nullable=True)
|
||||
op.alter_column("film_work", "creation_date", existing_type=sa.DateTime(), type_=sa.DATE(), existing_nullable=True)
|
||||
op.alter_column("film_work", "description", existing_type=sa.String(), type_=sa.TEXT(), existing_nullable=True)
|
||||
op.alter_column("film_work", "title", existing_type=sa.String(), type_=sa.TEXT(), existing_nullable=False)
|
||||
op.create_table(
|
||||
"django_migrations",
|
||||
sa.Column("id", sa.BIGINT(), autoincrement=True, nullable=False),
|
||||
sa.Column("app", sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
||||
sa.Column("name", sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
||||
sa.Column("applied", postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=False),
|
||||
)
|
||||
op.create_table(
|
||||
"django_admin_log",
|
||||
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||
sa.Column("action_time", postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=False),
|
||||
sa.Column("object_id", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column("object_repr", sa.VARCHAR(length=200), autoincrement=False, nullable=False),
|
||||
sa.Column("action_flag", sa.SMALLINT(), autoincrement=False, nullable=False),
|
||||
sa.Column("change_message", sa.TEXT(), autoincrement=False, nullable=False),
|
||||
sa.Column("content_type_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column("user_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
sa.CheckConstraint("action_flag >= 0", name="django_admin_log_action_flag_check"),
|
||||
)
|
||||
op.create_table(
|
||||
"django_session",
|
||||
sa.Column("session_key", sa.VARCHAR(length=40), autoincrement=False, nullable=False),
|
||||
sa.Column("session_data", sa.TEXT(), autoincrement=False, nullable=False),
|
||||
sa.Column("expire_date", postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=False),
|
||||
)
|
||||
op.create_table(
|
||||
"auth_permission",
|
||||
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||
sa.Column("name", sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
||||
sa.Column("content_type_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
sa.Column("codename", sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
||||
)
|
||||
op.create_table(
|
||||
"django_content_type",
|
||||
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||
sa.Column("app_label", sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
||||
sa.Column("model", sa.VARCHAR(length=100), autoincrement=False, nullable=False),
|
||||
)
|
||||
op.create_table(
|
||||
"auth_user",
|
||||
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||
sa.Column("password", sa.VARCHAR(length=128), autoincrement=False, nullable=False),
|
||||
sa.Column("last_login", postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=True),
|
||||
sa.Column("is_superuser", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column("username", sa.VARCHAR(length=150), autoincrement=False, nullable=False),
|
||||
sa.Column("first_name", sa.VARCHAR(length=150), autoincrement=False, nullable=False),
|
||||
sa.Column("last_name", sa.VARCHAR(length=150), autoincrement=False, nullable=False),
|
||||
sa.Column("email", sa.VARCHAR(length=254), autoincrement=False, nullable=False),
|
||||
sa.Column("is_staff", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column("is_active", sa.BOOLEAN(), autoincrement=False, nullable=False),
|
||||
sa.Column("date_joined", postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=False),
|
||||
)
|
||||
op.create_table(
|
||||
"auth_user_user_permissions",
|
||||
sa.Column("id", sa.BIGINT(), autoincrement=True, nullable=False),
|
||||
sa.Column("user_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
sa.Column("permission_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
)
|
||||
op.create_table(
|
||||
"auth_group_permissions",
|
||||
sa.Column("id", sa.BIGINT(), autoincrement=True, nullable=False),
|
||||
sa.Column("group_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
sa.Column("permission_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
)
|
||||
op.create_table(
|
||||
"auth_user_groups",
|
||||
sa.Column("id", sa.BIGINT(), autoincrement=True, nullable=False),
|
||||
sa.Column("user_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
sa.Column("group_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
)
|
||||
op.create_table(
|
||||
"auth_group",
|
||||
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||
sa.Column("name", sa.VARCHAR(length=150), autoincrement=False, nullable=False),
|
||||
)
|
||||
op.drop_table("chat_history", schema="content")
|
||||
# ### end Alembic commands ###
|
|
@ -2,4 +2,6 @@
|
|||
|
||||
while ! nc -z postgres 5432; do sleep 1; done;
|
||||
|
||||
alembic upgrade head
|
||||
|
||||
exec .venv/bin/python -m bin
|
5
src/assistant/lib/agent/__init__.py
Normal file
5
src/assistant/lib/agent/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
# from .services import AgentService
|
||||
|
||||
# __all__ = [
|
||||
# "AgentService",
|
||||
# ]
|
9
src/assistant/lib/agent/repositories/__init__.py
Normal file
9
src/assistant/lib/agent/repositories/__init__.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from .chat_repository import ChatHistoryRepository
|
||||
from .embedding_repository import EmbeddingRepository
|
||||
from .openai_functions import OpenAIFunctions
|
||||
|
||||
__all__ = [
|
||||
"ChatHistoryRepository",
|
||||
"EmbeddingRepository",
|
||||
"OpenAIFunctions",
|
||||
]
|
83
src/assistant/lib/agent/repositories/chat_repository.py
Normal file
83
src/assistant/lib/agent/repositories/chat_repository.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
import logging
|
||||
import uuid
|
||||
|
||||
import sqlalchemy as sa
|
||||
import sqlalchemy.exc
|
||||
import sqlalchemy.ext.asyncio as sa_asyncio
|
||||
|
||||
import lib.models as models
|
||||
import lib.orm_models as orm_models
|
||||
|
||||
|
||||
class ChatHistoryRepository:
|
||||
def __init__(self, pg_async_session: sa_asyncio.async_sessionmaker[sa_asyncio.AsyncSession]) -> None:
|
||||
self.pg_async_session = pg_async_session
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
async def get_last_session_id(self, request: models.RequestLastSessionId) -> uuid.UUID | None:
|
||||
"""Get a current session ID if exists."""
|
||||
|
||||
self.logger.debug("get_last_session_id: %s", request)
|
||||
try:
|
||||
async with self.pg_async_session() as session:
|
||||
statement = (
|
||||
sa.select(orm_models.ChatHistory)
|
||||
.filter_by(channel=request.channel, user_id=request.user_id)
|
||||
.filter(
|
||||
(
|
||||
sa.func.extract("epoch", sa.text("NOW()"))
|
||||
- sa.func.extract("epoch", orm_models.ChatHistory.created)
|
||||
)
|
||||
/ 60
|
||||
<= request.minutes_ago
|
||||
)
|
||||
.order_by(orm_models.ChatHistory.created.desc())
|
||||
.limit(1)
|
||||
)
|
||||
result = await session.execute(statement)
|
||||
|
||||
chat_session = result.scalars().first()
|
||||
if chat_session:
|
||||
return chat_session.session_id
|
||||
except sqlalchemy.exc.SQLAlchemyError as error:
|
||||
self.logger.exception("Error: %s", error)
|
||||
|
||||
async def get_messages_by_sid(self, request: models.RequestChatHistory) -> list[models.Message] | None:
|
||||
"""Get all messages of a chat by session ID."""
|
||||
|
||||
self.logger.debug("get_messages_by_sid: %s", request)
|
||||
try:
|
||||
async with self.pg_async_session() as session:
|
||||
messages: list[models.Message] = []
|
||||
statement = (
|
||||
sa.select(orm_models.ChatHistory)
|
||||
.filter_by(session_id=request.session_id)
|
||||
.order_by(orm_models.ChatHistory.created.asc())
|
||||
)
|
||||
print("get_messages_by_sid:", statement)
|
||||
result = await session.execute(statement)
|
||||
for row in result.scalars().all():
|
||||
# TODO: Было бы интересно понять почему pyright ругается ниже и как правильно вызывать компоненты
|
||||
messages.append(models.Message(role=row.content["role"], content=row.content["content"])) # type: ignore[reportGeneralTypeIssues]
|
||||
return messages
|
||||
except sqlalchemy.exc.SQLAlchemyError as error:
|
||||
self.logger.exception("Error: %s", error)
|
||||
|
||||
async def add_message(self, request: models.RequestChatMessage) -> None:
|
||||
"""Add a message to the chat history."""
|
||||
|
||||
self.logger.debug("add_message: %s", request)
|
||||
try:
|
||||
async with self.pg_async_session() as session:
|
||||
chat_history = orm_models.ChatHistory(
|
||||
id=uuid.uuid4(),
|
||||
session_id=request.session_id,
|
||||
user_id=request.user_id,
|
||||
channel=request.channel,
|
||||
content=request.message,
|
||||
)
|
||||
session.add(chat_history)
|
||||
await session.commit()
|
||||
# TODO: Add refresh to session and return added object
|
||||
except sqlalchemy.exc.SQLAlchemyError as error:
|
||||
self.logger.exception("Error: %s", error)
|
41
src/assistant/lib/agent/repositories/embedding_repository.py
Normal file
41
src/assistant/lib/agent/repositories/embedding_repository.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
import logging
|
||||
import typing
|
||||
|
||||
import openai
|
||||
import openai.error
|
||||
|
||||
import lib.app.settings as app_settings
|
||||
import lib.models as models
|
||||
|
||||
|
||||
class EmbeddingRepository:
|
||||
"""A service for getting embeddings from OpenAI."""
|
||||
|
||||
def __init__(self, settings: app_settings.Settings) -> None:
|
||||
"""Initialize the service with an OpenAI API key."""
|
||||
self.llm = openai.api_key = settings.openai.api_key.get_secret_value()
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
def get_embedding(self, text: str, model: str = "text-embedding-ada-002") -> models.Embedding | None:
|
||||
"""Get the embedding for a given text."""
|
||||
try:
|
||||
response: dict[str, typing.Any] = openai.Embedding.create(
|
||||
input=text,
|
||||
model=model,
|
||||
) # type: ignore[reportGeneralTypeIssues]
|
||||
return models.Embedding(**response["data"][0]["embedding"])
|
||||
except openai.error.OpenAIError:
|
||||
self.logger.exception("Failed to get sync embedding for: %s", text)
|
||||
|
||||
async def aget_embedding(self, text: str, model: str = "text-embedding-ada-002") -> models.Embedding | None:
|
||||
"""Get the embedding for a given text.[Async]"""
|
||||
try:
|
||||
response: dict[str, typing.Any] = await openai.Embedding.acreate(
|
||||
input=text,
|
||||
model=model,
|
||||
) # type: ignore[reportGeneralTypeIssues]
|
||||
# print(response["data"][0]["embedding"])
|
||||
return models.Embedding(root=response["data"][0]["embedding"])
|
||||
|
||||
except openai.error.OpenAIError:
|
||||
self.logger.exception("Failed to get async embedding for: %s", text)
|
43
src/assistant/lib/agent/repositories/openai_functions.py
Normal file
43
src/assistant/lib/agent/repositories/openai_functions.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
import logging
|
||||
|
||||
import sqlalchemy as sa
|
||||
import sqlalchemy.exc
|
||||
import sqlalchemy.ext.asyncio as sa_asyncio
|
||||
|
||||
import lib.agent.repositories as repositories
|
||||
import lib.models as models
|
||||
import lib.orm_models as orm_models
|
||||
|
||||
|
||||
class OpenAIFunctions:
|
||||
"""OpenAI Functions for langchain agents."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
repository: repositories.EmbeddingRepository,
|
||||
pg_async_session: sa_asyncio.async_sessionmaker[sa_asyncio.AsyncSession],
|
||||
) -> None:
|
||||
self.logger = logging.getLogger(__name__)
|
||||
self.pg_async_session = pg_async_session
|
||||
self.repository = repository
|
||||
|
||||
async def get_movie_by_description(self, description: str) -> list[models.Movie] | None:
|
||||
"""Use this function to find data about a movie by movie's description."""
|
||||
|
||||
self.logger.info("Request to get movie by description: %s", description)
|
||||
embedded_description = await self.repository.aget_embedding(description)
|
||||
try:
|
||||
async with self.pg_async_session() as session:
|
||||
result: list[models.Movie] = []
|
||||
stmt = (
|
||||
sa.select(orm_models.FilmWork)
|
||||
.order_by(orm_models.FilmWork.embeddings.cosine_distance(embedded_description.root))
|
||||
.limit(5)
|
||||
)
|
||||
response = await session.execute(stmt)
|
||||
neighbours = response.scalars()
|
||||
for neighbour in neighbours:
|
||||
result.append(models.Movie(**neighbour.__dict__))
|
||||
return result
|
||||
except sqlalchemy.exc.SQLAlchemyError as error:
|
||||
self.logger.exception("Error: %s", error)
|
141
src/assistant/lib/agent/services.py
Normal file
141
src/assistant/lib/agent/services.py
Normal file
|
@ -0,0 +1,141 @@
|
|||
import logging
|
||||
import uuid
|
||||
|
||||
import langchain.agents
|
||||
import langchain.agents.format_scratchpad
|
||||
import langchain.agents.output_parsers
|
||||
import langchain.chains
|
||||
import langchain.chat_models
|
||||
import langchain.memory
|
||||
import langchain.memory.chat_memory
|
||||
import langchain.prompts
|
||||
import langchain.schema
|
||||
import langchain.tools.render
|
||||
|
||||
import lib.agent.repositories as lib_agent_repositories
|
||||
import lib.agent.repositories.chat_repository as chat_repositories
|
||||
import lib.app.settings as app_settings
|
||||
import lib.models as models
|
||||
|
||||
|
||||
class AgentService:
|
||||
def __init__(
|
||||
self,
|
||||
settings: app_settings.Settings,
|
||||
chat_repository: chat_repositories.ChatHistoryRepository,
|
||||
tools: lib_agent_repositories.OpenAIFunctions,
|
||||
) -> None:
|
||||
self.settings = settings
|
||||
self.tools = tools
|
||||
self.chat_repository = chat_repository
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
async def send_message_request(self, request: str, system_prompt: str):
|
||||
prompt = langchain.prompts.ChatPromptTemplate.from_messages(
|
||||
[
|
||||
("system", system_prompt),
|
||||
]
|
||||
)
|
||||
llm = langchain.chat_models.ChatOpenAI(
|
||||
temperature=self.settings.openai.agent_temperature,
|
||||
openai_api_key=self.settings.openai.api_key.get_secret_value(),
|
||||
)
|
||||
chain = langchain.chains.LLMChain(llm=llm, prompt=prompt)
|
||||
result = await chain.ainvoke({"input": request})
|
||||
return result["text"]
|
||||
|
||||
async def process_request(self, request: models.AgentCreateRequestModel) -> models.AgentCreateResponseModel:
|
||||
# Get session ID
|
||||
request_text = request.text
|
||||
translate_text = await self.send_message_request(request=request_text, system_prompt="Translation into English")
|
||||
session_request = models.RequestLastSessionId(channel=request.channel, user_id=request.user_id, minutes_ago=3)
|
||||
session_id = await self.chat_repository.get_last_session_id(session_request)
|
||||
if not session_id:
|
||||
session_id = uuid.uuid4()
|
||||
await self.send_message_request(request="test", system_prompt="test")
|
||||
|
||||
# Declare tools (OpenAI functions)
|
||||
tools = [
|
||||
langchain.tools.Tool(
|
||||
name="GetMovieByDescription",
|
||||
func=self.tools.get_movie_by_description,
|
||||
coroutine=self.tools.get_movie_by_description,
|
||||
description="Use this function to find data about a movie by movie's description",
|
||||
),
|
||||
]
|
||||
|
||||
llm = langchain.chat_models.ChatOpenAI(
|
||||
temperature=self.settings.openai.agent_temperature,
|
||||
openai_api_key=self.settings.openai.api_key.get_secret_value(),
|
||||
)
|
||||
|
||||
chat_history = []
|
||||
chat_history_name = f"{chat_history=}".partition("=")[0]
|
||||
|
||||
request_chat_history = models.RequestChatHistory(session_id=session_id)
|
||||
chat_history_source = await self.chat_repository.get_messages_by_sid(request_chat_history)
|
||||
if not chat_history_source:
|
||||
for entry in chat_history_source:
|
||||
if entry.role == "user":
|
||||
chat_history.append(langchain.schema.HumanMessage(content=entry.content))
|
||||
elif entry.role == "agent":
|
||||
chat_history.append(langchain.schema.AIMessage(content=entry.content))
|
||||
|
||||
prompt = langchain.prompts.ChatPromptTemplate.from_messages(
|
||||
[
|
||||
(
|
||||
"system",
|
||||
"""1. Translate each inbound request into English language. Before calling any functions.
|
||||
2. You are movie expert with a vast knowledge base about movies and their related aspects.
|
||||
3. Answer always in Russian language.
|
||||
4. Be concise. You answer must be within 100-150 words.""",
|
||||
),
|
||||
langchain.prompts.MessagesPlaceholder(variable_name=chat_history_name),
|
||||
("user", "{input}"),
|
||||
langchain.prompts.MessagesPlaceholder(variable_name="agent_scratchpad"),
|
||||
]
|
||||
)
|
||||
|
||||
llm_with_tools = llm.bind(
|
||||
functions=[langchain.tools.render.format_tool_to_openai_function(tool) for tool in tools]
|
||||
)
|
||||
|
||||
agent = (
|
||||
{
|
||||
"input": lambda _: _["input"],
|
||||
"agent_scratchpad": lambda _: langchain.agents.format_scratchpad.format_to_openai_functions(
|
||||
_["intermediate_steps"]
|
||||
),
|
||||
"chat_history": lambda _: _["chat_history"],
|
||||
}
|
||||
| prompt
|
||||
| llm_with_tools
|
||||
| langchain.agents.output_parsers.OpenAIFunctionsAgentOutputParser()
|
||||
)
|
||||
|
||||
agent_executor = langchain.agents.AgentExecutor(agent=agent, tools=tools, verbose=True)
|
||||
chat_history = [] # temporary disable chat_history
|
||||
response = await agent_executor.ainvoke({"input": translate_text, "chat_history": chat_history})
|
||||
|
||||
user_request = models.RequestChatMessage(
|
||||
session_id=session_id,
|
||||
user_id=request.user_id,
|
||||
channel=request.channel,
|
||||
message={"role": "user", "content": request.text},
|
||||
)
|
||||
ai_response = models.RequestChatMessage(
|
||||
session_id=session_id,
|
||||
user_id=request.user_id,
|
||||
channel=request.channel,
|
||||
message={"role": "assistant", "content": response["output"]},
|
||||
)
|
||||
|
||||
await self.chat_repository.add_message(user_request)
|
||||
await self.chat_repository.add_message(ai_response)
|
||||
|
||||
response_translate = await self.send_message_request(
|
||||
request=f"Original text: {request_text}. Answer: {response['output']}",
|
||||
system_prompt="Translate the answer into the language of the original text",
|
||||
)
|
||||
print(response_translate)
|
||||
return models.AgentCreateResponseModel(text=response_translate)
|
|
@ -3,20 +3,22 @@ import io
|
|||
|
||||
import fastapi
|
||||
|
||||
import lib.agent.services as agent_service
|
||||
import lib.models as models
|
||||
import lib.stt.services as stt_services
|
||||
|
||||
# import lib.tts.services as tts_service
|
||||
# import lib.models as models
|
||||
import lib.tts.services as tts_service
|
||||
|
||||
|
||||
class VoiceResponseHandler:
|
||||
def __init__(
|
||||
self,
|
||||
stt: stt_services.SpeechService,
|
||||
# tts: tts_service.TTSService,
|
||||
tts: tts_service.TTSService,
|
||||
agent: agent_service.AgentService,
|
||||
):
|
||||
self.stt = stt
|
||||
# self.tts = tts
|
||||
self.tts = tts
|
||||
self.agent = agent
|
||||
self.router = fastapi.APIRouter()
|
||||
self.router.add_api_route(
|
||||
"/",
|
||||
|
@ -28,18 +30,21 @@ class VoiceResponseHandler:
|
|||
|
||||
async def voice_response(
|
||||
self,
|
||||
channel: str = "tg",
|
||||
user_id: str = "1234",
|
||||
voice: bytes = fastapi.File(...),
|
||||
) -> fastapi.responses.StreamingResponse:
|
||||
voice_text: str = await self.stt.recognize(voice)
|
||||
if voice_text == "":
|
||||
raise fastapi.HTTPException(status_code=http.HTTPStatus.BAD_REQUEST, detail="Speech recognition failed")
|
||||
# TODO: Добавить обработку текста через клиента openai
|
||||
# TODO: Добавить синтез речи через клиента tts
|
||||
# TODO: Заменить заглушку на реальный ответ
|
||||
# response = await self.tts.get_audio_as_bytes(
|
||||
# models.TTSCreateRequestModel(
|
||||
# text=voice_text,
|
||||
# )
|
||||
# )
|
||||
# return fastapi.responses.StreamingResponse(io.BytesIO(response.audio_content), media_type="audio/ogg")
|
||||
return fastapi.responses.StreamingResponse(io.BytesIO(voice), media_type="audio/ogg")
|
||||
|
||||
agent_request = models.AgentCreateRequestModel(channel=channel, user_id=user_id, text=voice_text)
|
||||
reply_text = await self.agent.process_request(agent_request)
|
||||
|
||||
response = await self.tts.get_audio_as_bytes(
|
||||
models.TTSCreateRequestModel(
|
||||
text=reply_text.text,
|
||||
)
|
||||
)
|
||||
return fastapi.responses.StreamingResponse(io.BytesIO(response.audio_content), media_type="audio/ogg")
|
||||
# return fastapi.responses.StreamingResponse(io.BytesIO(voice), media_type="audio/ogg")
|
||||
|
|
|
@ -6,6 +6,9 @@ import typing
|
|||
import fastapi
|
||||
import uvicorn
|
||||
|
||||
import lib.agent.repositories as agent_repositories
|
||||
import lib.agent.repositories.openai_functions as agent_functions
|
||||
import lib.agent.services as agent_services
|
||||
import lib.api.v1.handlers as api_v1_handlers
|
||||
import lib.app.errors as app_errors
|
||||
import lib.app.settings as app_settings
|
||||
|
@ -89,7 +92,13 @@ class Application:
|
|||
|
||||
logger.info("Initializing repositories")
|
||||
stt_repository: stt.STTProtocol = stt.OpenaiSpeechRepository(settings=settings)
|
||||
|
||||
chat_history_repository = agent_repositories.ChatHistoryRepository(
|
||||
pg_async_session=postgres_client.get_async_session()
|
||||
)
|
||||
embedding_repository = agent_repositories.EmbeddingRepository(settings=settings)
|
||||
agent_tools = agent_functions.OpenAIFunctions(
|
||||
repository=embedding_repository, pg_async_session=postgres_client.get_async_session()
|
||||
)
|
||||
tts_yandex_repository = tts.TTSYandexRepository(
|
||||
tts_settings=app_split_settings.TTSYandexSettings(),
|
||||
client=http_yandex_tts_client,
|
||||
|
@ -104,18 +113,25 @@ class Application:
|
|||
|
||||
logger.info("Initializing caches")
|
||||
|
||||
# Tools
|
||||
|
||||
# Services
|
||||
|
||||
logger.info("Initializing services")
|
||||
stt_service: stt.SpeechService = stt.SpeechService(repository=stt_repository) # type: ignore
|
||||
|
||||
tts_service: tts.TTSService = tts.TTSService( # type: ignore
|
||||
stt_service: stt.SpeechService = stt.SpeechService(repository=stt_repository)
|
||||
|
||||
tts_service: tts.TTSService = tts.TTSService(
|
||||
repositories={
|
||||
models.VoiceModelProvidersEnum.YANDEX: tts_yandex_repository,
|
||||
models.VoiceModelProvidersEnum.ELEVEN_LABS: tts_eleven_labs_repository,
|
||||
},
|
||||
)
|
||||
|
||||
agent_service = agent_services.AgentService(
|
||||
settings=settings, chat_repository=chat_history_repository, tools=agent_tools
|
||||
)
|
||||
|
||||
# Handlers
|
||||
|
||||
logger.info("Initializing handlers")
|
||||
|
@ -124,7 +140,8 @@ class Application:
|
|||
# TODO: объявить сервисы tts и openai и добавить их в voice_response_handler
|
||||
voice_response_handler = api_v1_handlers.VoiceResponseHandler(
|
||||
stt=stt_service,
|
||||
# tts=tts_service, # TODO
|
||||
tts=tts_service,
|
||||
agent=agent_service,
|
||||
).router
|
||||
|
||||
logger.info("Creating application")
|
||||
|
|
|
@ -16,3 +16,4 @@ class OpenaiSettings(pydantic_settings.BaseSettings):
|
|||
default=..., validation_alias=pydantic.AliasChoices("api_key", "openai_api_key")
|
||||
)
|
||||
stt_model: str = "whisper-1"
|
||||
agent_temperature: float = 0.7
|
||||
|
|
|
@ -37,8 +37,8 @@ class PostgresSettings(pydantic_settings.BaseSettings):
|
|||
@property
|
||||
def dsn(self) -> str:
|
||||
password = self.password.get_secret_value()
|
||||
return f"{self.driver}://{self.user}:{password}@{self.host}:{self.port}"
|
||||
return f"{self.driver}://{self.user}:{password}@{self.host}:{self.port}/{self.db_name}"
|
||||
|
||||
@property
|
||||
def dsn_as_safe_url(self) -> str:
|
||||
return f"{self.driver}://{self.user}:***@{self.host}:{self.port}"
|
||||
return f"{self.driver}://{self.user}:***@{self.host}:{self.port}/{self.db_name}"
|
||||
|
|
|
@ -15,7 +15,7 @@ class TTSElevenLabsSettings(pydantic_settings.BaseSettings):
|
|||
api_key: pydantic.SecretStr = pydantic.Field(default=...)
|
||||
default_voice_id: str = "EXAVITQu4vr4xnSDxMaL"
|
||||
base_url: str = "https://api.elevenlabs.io/v1/"
|
||||
timeout_seconds: int = 30
|
||||
timeout_seconds: int = 120
|
||||
|
||||
@property
|
||||
def base_headers(self) -> dict[str, str]:
|
||||
|
|
|
@ -18,7 +18,7 @@ class TTSYandexSettings(pydantic_settings.BaseSettings):
|
|||
sample_rate_hertz: int = 48000
|
||||
api_key: pydantic.SecretStr = pydantic.Field(default=...)
|
||||
base_url: str = "https://tts.api.cloud.yandex.net/speech/v1/"
|
||||
timeout_seconds: int = 30
|
||||
timeout_seconds: int = 120
|
||||
|
||||
@property
|
||||
def base_headers(self) -> dict[str, str]:
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
from .orm import Base, IdCreatedUpdatedBaseMixin
|
||||
from .agent import *
|
||||
from .chat_history import Message, RequestChatHistory, RequestChatMessage, RequestLastSessionId
|
||||
from .embedding import Embedding
|
||||
from .movies import Movie
|
||||
from .token import Token
|
||||
from .tts import *
|
||||
|
||||
# __all__ = ["Embedding", "Message", "Movie", "RequestChatHistory", "RequestChatMessage", "RequestLastSessionId", "Token"]
|
||||
__all__ = [
|
||||
"AVAILABLE_MODELS_TYPE",
|
||||
"Base",
|
||||
"AgentCreateRequestModel",
|
||||
"BaseLanguageCodesEnum",
|
||||
"BaseVoiceModel",
|
||||
"ElevenLabsLanguageCodesEnum",
|
||||
"ElevenLabsListVoiceModelsModel",
|
||||
"ElevenLabsVoiceModel",
|
||||
"IdCreatedUpdatedBaseMixin",
|
||||
"LANGUAGE_CODES_ENUM_TYPE",
|
||||
"LIST_VOICE_MODELS_TYPE",
|
||||
"TTSCreateRequestModel",
|
||||
|
|
11
src/assistant/lib/models/agent.py
Normal file
11
src/assistant/lib/models/agent.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
import pydantic
|
||||
|
||||
|
||||
class AgentCreateRequestModel(pydantic.BaseModel):
|
||||
text: str
|
||||
user_id: str
|
||||
channel: str
|
||||
|
||||
|
||||
class AgentCreateResponseModel(pydantic.BaseModel):
|
||||
text: str
|
33
src/assistant/lib/models/chat_history.py
Normal file
33
src/assistant/lib/models/chat_history.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
import uuid
|
||||
|
||||
import pydantic
|
||||
|
||||
|
||||
class RequestLastSessionId(pydantic.BaseModel):
|
||||
"""Request for a new session ID."""
|
||||
|
||||
channel: str
|
||||
user_id: str
|
||||
minutes_ago: int
|
||||
|
||||
|
||||
class RequestChatMessage(pydantic.BaseModel):
|
||||
"""A chat message."""
|
||||
|
||||
session_id: uuid.UUID
|
||||
user_id: str
|
||||
channel: str
|
||||
message: dict[str, str]
|
||||
|
||||
|
||||
class RequestChatHistory(pydantic.BaseModel):
|
||||
"""Request for chat history."""
|
||||
|
||||
session_id: uuid.UUID
|
||||
|
||||
|
||||
class Message(pydantic.BaseModel):
|
||||
"""A chat message."""
|
||||
|
||||
role: str
|
||||
content: str
|
5
src/assistant/lib/models/embedding.py
Normal file
5
src/assistant/lib/models/embedding.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
import pydantic
|
||||
|
||||
|
||||
class Embedding(pydantic.RootModel[list[float]]):
|
||||
root: list[float]
|
37
src/assistant/lib/models/movies.py
Normal file
37
src/assistant/lib/models/movies.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
import datetime
|
||||
import uuid
|
||||
|
||||
import pydantic
|
||||
|
||||
|
||||
class Movie(pydantic.BaseModel):
|
||||
id: uuid.UUID
|
||||
title: str
|
||||
description: str | None = None
|
||||
rating: float | None = None
|
||||
type: str | None = None
|
||||
created: datetime.datetime
|
||||
modified: datetime.datetime
|
||||
creation_date: datetime.datetime | None = None
|
||||
runtime: int | None = None
|
||||
budget: int | None = None
|
||||
imdb_id: str | None = None
|
||||
|
||||
@pydantic.computed_field
|
||||
@property
|
||||
def imdb_url(self) -> str:
|
||||
return f"https://www.imdb.com/title/{self.imdb_id}"
|
||||
|
||||
def get_movie_info_line(self):
|
||||
not_provided_value = "not provided"
|
||||
content_film_info = {
|
||||
"Title": self.title,
|
||||
"Description": self.description or not_provided_value,
|
||||
"Rating": self.rating or not_provided_value,
|
||||
"Imdb_id": self.imdb_url or not_provided_value,
|
||||
"Creation_date": self.creation_date or not_provided_value,
|
||||
"Runtime": self.runtime or not_provided_value,
|
||||
"Budget": self.budget or not_provided_value,
|
||||
}
|
||||
content_film_info_line = ", ".join(f"{k}: {v}" for k, v in content_film_info.items())
|
||||
return content_film_info_line
|
|
@ -1,3 +0,0 @@
|
|||
from .base import Base, IdCreatedUpdatedBaseMixin
|
||||
|
||||
__all__ = ["Base", "IdCreatedUpdatedBaseMixin"]
|
14
src/assistant/lib/orm_models/__init__.py
Normal file
14
src/assistant/lib/orm_models/__init__.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
from .base import Base, IdCreatedUpdatedBaseMixin
|
||||
from .chat_history import ChatHistory
|
||||
from .movies import FilmWork, Genre, GenreFilmWork, Person, PersonFilmWork
|
||||
|
||||
__all__ = [
|
||||
"Base",
|
||||
"ChatHistory",
|
||||
"FilmWork",
|
||||
"Genre",
|
||||
"GenreFilmWork",
|
||||
"IdCreatedUpdatedBaseMixin",
|
||||
"Person",
|
||||
"PersonFilmWork",
|
||||
]
|
|
@ -16,20 +16,12 @@ class Base(sa_orm.DeclarativeBase):
|
|||
return cls.__name__.lower()
|
||||
|
||||
__mapper_args__ = {"eager_defaults": True}
|
||||
|
||||
id: sa_orm.Mapped[uuid.UUID] = sa_orm.mapped_column(primary_key=True, default=uuid.uuid4)
|
||||
__table_args__ = {"schema": "content"}
|
||||
|
||||
|
||||
class IdCreatedUpdatedBaseMixin:
|
||||
# id: sa_orm.Mapped[int] = sa_orm.mapped_column(primary_key=True)
|
||||
# id_field: sa_orm.Mapped[uuid.UUID] = sa_orm.mapped_column(name="uuid", primary_key=True, unique=True, default=uuid.uuid4, nullable=False)
|
||||
id: sa_orm.Mapped[uuid.UUID] = sa_orm.mapped_column(primary_key=True, default=uuid.uuid4)
|
||||
created: sa_orm.Mapped[datetime.datetime] = sa_orm.mapped_column(server_default=sa_sql.func.now())
|
||||
updated: sa_orm.Mapped[datetime.datetime] = sa_orm.mapped_column(
|
||||
server_default=sa_sql.func.now(), onupdate=sa_sql.func.now()
|
||||
)
|
||||
|
||||
# __mapper_args__ = {"eager_defaults": True}
|
||||
|
||||
# @sqlalchemy.ext.declarative.declared_attr.directive
|
||||
# def __tablename__(cls) -> str:
|
||||
# return cls.__name__.lower()
|
24
src/assistant/lib/orm_models/chat_history.py
Normal file
24
src/assistant/lib/orm_models/chat_history.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
import datetime
|
||||
import uuid
|
||||
|
||||
import sqlalchemy as sa
|
||||
import sqlalchemy.orm as sa_orm
|
||||
import sqlalchemy.sql as sa_sql
|
||||
|
||||
import lib.orm_models.base as base_models
|
||||
|
||||
|
||||
class ChatHistory(base_models.Base):
|
||||
__tablename__: str = "chat_history" # type: ignore[reportIncompatibleVariableOverride]
|
||||
|
||||
id: sa_orm.Mapped[uuid.UUID] = sa_orm.mapped_column(primary_key=True, default=uuid.uuid4)
|
||||
session_id: sa_orm.Mapped[uuid.UUID] = sa_orm.mapped_column(nullable=False, unique=True)
|
||||
channel: sa_orm.Mapped[str] = sa_orm.mapped_column()
|
||||
user_id: sa_orm.Mapped[str] = sa_orm.mapped_column()
|
||||
content: sa_orm.Mapped[sa.JSON] = sa_orm.mapped_column(sa.JSON)
|
||||
created: sa_orm.Mapped[datetime.datetime] = sa_orm.mapped_column(
|
||||
sa.DateTime(timezone=True), server_default=sa_sql.func.now()
|
||||
)
|
||||
modified: sa_orm.Mapped[datetime.datetime] = sa_orm.mapped_column(
|
||||
sa.DateTime(timezone=True), server_default=sa_sql.func.now(), onupdate=sa_sql.func.now()
|
||||
)
|
78
src/assistant/lib/orm_models/movies.py
Normal file
78
src/assistant/lib/orm_models/movies.py
Normal file
|
@ -0,0 +1,78 @@
|
|||
import datetime
|
||||
import uuid
|
||||
|
||||
import pgvector.sqlalchemy
|
||||
import sqlalchemy as sa
|
||||
import sqlalchemy.orm as sa_orm
|
||||
import sqlalchemy.sql as sa_sql
|
||||
|
||||
import lib.orm_models.base as base_models
|
||||
|
||||
|
||||
class Genre(base_models.Base):
|
||||
__tablename__: str = "genre" # type: ignore[reportIncompatibleVariableOverride]
|
||||
|
||||
id: sa_orm.Mapped[uuid.UUID] = sa_orm.mapped_column(primary_key=True, default=uuid.uuid4)
|
||||
name: sa_orm.Mapped[str] = sa_orm.mapped_column()
|
||||
description: sa_orm.Mapped[str] = sa_orm.mapped_column(nullable=True)
|
||||
created: sa_orm.Mapped[datetime.datetime] = sa_orm.mapped_column(
|
||||
sa.DateTime(timezone=True), server_default=sa_sql.func.now()
|
||||
)
|
||||
modified: sa_orm.Mapped[datetime.datetime] = sa_orm.mapped_column(
|
||||
sa.DateTime(timezone=True), server_default=sa_sql.func.now(), onupdate=sa_sql.func.now()
|
||||
)
|
||||
|
||||
|
||||
class Person(base_models.Base):
|
||||
__tablename__: str = "person" # type: ignore[reportIncompatibleVariableOverride]
|
||||
|
||||
id: sa_orm.Mapped[uuid.UUID] = sa_orm.mapped_column(primary_key=True, default=uuid.uuid4)
|
||||
full_name: sa_orm.Mapped[str] = sa_orm.mapped_column()
|
||||
created: sa_orm.Mapped[datetime.datetime] = sa_orm.mapped_column(
|
||||
sa.DateTime(timezone=True), server_default=sa_sql.func.now()
|
||||
)
|
||||
modified: sa_orm.Mapped[datetime.datetime] = sa_orm.mapped_column(
|
||||
sa.DateTime(timezone=True), server_default=sa_sql.func.now(), onupdate=sa_sql.func.now()
|
||||
)
|
||||
|
||||
|
||||
class FilmWork(base_models.Base):
|
||||
__tablename__: str = "film_work" # type: ignore[reportIncompatibleVariableOverride]
|
||||
|
||||
id: sa_orm.Mapped[uuid.UUID] = sa_orm.mapped_column(primary_key=True, default=uuid.uuid4)
|
||||
title: sa_orm.Mapped[str] = sa_orm.mapped_column()
|
||||
description: sa_orm.Mapped[str] = sa_orm.mapped_column(nullable=True)
|
||||
creation_date: sa_orm.Mapped[datetime.datetime] = sa_orm.mapped_column(nullable=True)
|
||||
rating: sa_orm.Mapped[float] = sa_orm.mapped_column(nullable=True)
|
||||
runtime: sa_orm.Mapped[int] = sa_orm.mapped_column(nullable=False)
|
||||
budget: sa_orm.Mapped[int] = sa_orm.mapped_column(default=0)
|
||||
imdb_id: sa_orm.Mapped[str] = sa_orm.mapped_column(nullable=False)
|
||||
type: sa_orm.Mapped[str] = sa_orm.mapped_column()
|
||||
created: sa_orm.Mapped[datetime.datetime] = sa_orm.mapped_column(
|
||||
sa.DateTime(timezone=True), server_default=sa_sql.func.now()
|
||||
)
|
||||
modified: sa_orm.Mapped[datetime.datetime] = sa_orm.mapped_column(
|
||||
sa.DateTime(timezone=True), server_default=sa_sql.func.now(), onupdate=sa_sql.func.now()
|
||||
)
|
||||
embeddings: sa_orm.Mapped[list[float]] = sa_orm.mapped_column(pgvector.sqlalchemy.Vector(1536))
|
||||
genres: sa_orm.Mapped[list[Genre]] = sa_orm.relationship(secondary="genre_film_work")
|
||||
|
||||
|
||||
GenreFilmWork = sa.Table(
|
||||
"genre_film_work",
|
||||
base_models.Base.metadata,
|
||||
sa.Column("id", sa.UUID, primary_key=True), # type: ignore[reportUnknownVariableType]
|
||||
sa.Column("genre_id", sa.ForeignKey(Genre.id), primary_key=True), # type: ignore[reportUnknownVariableType]
|
||||
sa.Column("film_work_id", sa.ForeignKey(FilmWork.id), primary_key=True), # type: ignore[reportUnknownVariableType]
|
||||
sa.Column("created", sa.DateTime(timezone=True), server_default=sa_sql.func.now()),
|
||||
)
|
||||
|
||||
|
||||
PersonFilmWork = sa.Table(
|
||||
"person_film_work",
|
||||
base_models.Base.metadata,
|
||||
sa.Column("person_id", sa.ForeignKey(Person.id), primary_key=True), # type: ignore[reportUnknownVariableType]
|
||||
sa.Column("film_work_id", sa.ForeignKey(FilmWork.id), primary_key=True), # type: ignore[reportUnknownVariableType]
|
||||
sa.Column("role", sa.String(50), nullable=False),
|
||||
sa.Column("created", sa.DateTime(timezone=True), server_default=sa_sql.func.now()),
|
||||
)
|
391
src/assistant/poetry.lock
generated
391
src/assistant/poetry.lock
generated
|
@ -1,4 +1,4 @@
|
|||
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "aiohttp"
|
||||
|
@ -448,6 +448,21 @@ files = [
|
|||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dataclasses-json"
|
||||
version = "0.6.1"
|
||||
description = "Easily serialize dataclasses to and from JSON."
|
||||
optional = false
|
||||
python-versions = ">=3.7,<4.0"
|
||||
files = [
|
||||
{file = "dataclasses_json-0.6.1-py3-none-any.whl", hash = "sha256:1bd8418a61fe3d588bb0079214d7fb71d44937da40742b787256fd53b26b6c80"},
|
||||
{file = "dataclasses_json-0.6.1.tar.gz", hash = "sha256:a53c220c35134ce08211a1057fd0e5bf76dc5331627c6b241cacbc570a89faae"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
marshmallow = ">=3.18.0,<4.0.0"
|
||||
typing-inspect = ">=0.4.0,<1"
|
||||
|
||||
[[package]]
|
||||
name = "dill"
|
||||
version = "0.3.7"
|
||||
|
@ -616,6 +631,7 @@ files = [
|
|||
{file = "greenlet-2.0.2-cp27-cp27m-win32.whl", hash = "sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74"},
|
||||
{file = "greenlet-2.0.2-cp27-cp27m-win_amd64.whl", hash = "sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343"},
|
||||
{file = "greenlet-2.0.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae"},
|
||||
{file = "greenlet-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d967650d3f56af314b72df7089d96cda1083a7fc2da05b375d2bc48c82ab3f3c"},
|
||||
{file = "greenlet-2.0.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df"},
|
||||
{file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088"},
|
||||
{file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb"},
|
||||
|
@ -624,6 +640,7 @@ files = [
|
|||
{file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91"},
|
||||
{file = "greenlet-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645"},
|
||||
{file = "greenlet-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c"},
|
||||
{file = "greenlet-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d4606a527e30548153be1a9f155f4e283d109ffba663a15856089fb55f933e47"},
|
||||
{file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca"},
|
||||
{file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0"},
|
||||
{file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2"},
|
||||
|
@ -653,6 +670,7 @@ files = [
|
|||
{file = "greenlet-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7"},
|
||||
{file = "greenlet-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3"},
|
||||
{file = "greenlet-2.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30"},
|
||||
{file = "greenlet-2.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1087300cf9700bbf455b1b97e24db18f2f77b55302a68272c56209d5587c12d1"},
|
||||
{file = "greenlet-2.0.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b"},
|
||||
{file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526"},
|
||||
{file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b"},
|
||||
|
@ -661,6 +679,7 @@ files = [
|
|||
{file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a"},
|
||||
{file = "greenlet-2.0.2-cp38-cp38-win32.whl", hash = "sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249"},
|
||||
{file = "greenlet-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40"},
|
||||
{file = "greenlet-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8512a0c38cfd4e66a858ddd1b17705587900dd760c6003998e9472b77b56d417"},
|
||||
{file = "greenlet-2.0.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8"},
|
||||
{file = "greenlet-2.0.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6"},
|
||||
{file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df"},
|
||||
|
@ -771,6 +790,85 @@ pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"
|
|||
plugins = ["setuptools"]
|
||||
requirements-deprecated-finder = ["pip-api", "pipreqs"]
|
||||
|
||||
[[package]]
|
||||
name = "jsonpatch"
|
||||
version = "1.33"
|
||||
description = "Apply JSON-Patches (RFC 6902)"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*"
|
||||
files = [
|
||||
{file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"},
|
||||
{file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
jsonpointer = ">=1.9"
|
||||
|
||||
[[package]]
|
||||
name = "jsonpointer"
|
||||
version = "2.4"
|
||||
description = "Identify specific nodes in a JSON document (RFC 6901)"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*"
|
||||
files = [
|
||||
{file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"},
|
||||
{file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "langchain"
|
||||
version = "0.0.314"
|
||||
description = "Building applications with LLMs through composability"
|
||||
optional = false
|
||||
python-versions = ">=3.8.1,<4.0"
|
||||
files = [
|
||||
{file = "langchain-0.0.314-py3-none-any.whl", hash = "sha256:b799d4086086ca8f952d5f7b9dc3ebb3cf77b1957d657ee91739cd1689d71a5c"},
|
||||
{file = "langchain-0.0.314.tar.gz", hash = "sha256:96dac382b79a88ee7ccc53aadc2818fd064475f229fde189483fee15558405c8"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
aiohttp = ">=3.8.3,<4.0.0"
|
||||
anyio = "<4.0"
|
||||
dataclasses-json = ">=0.5.7,<0.7"
|
||||
jsonpatch = ">=1.33,<2.0"
|
||||
langsmith = ">=0.0.43,<0.1.0"
|
||||
numpy = ">=1,<2"
|
||||
pydantic = ">=1,<3"
|
||||
PyYAML = ">=5.3"
|
||||
requests = ">=2,<3"
|
||||
SQLAlchemy = ">=1.4,<3"
|
||||
tenacity = ">=8.1.0,<9.0.0"
|
||||
|
||||
[package.extras]
|
||||
all = ["O365 (>=2.0.26,<3.0.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "amadeus (>=8.1.0)", "arxiv (>=1.4,<2.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "awadb (>=0.3.9,<0.4.0)", "azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "beautifulsoup4 (>=4,<5)", "clarifai (>=9.1.0)", "clickhouse-connect (>=0.5.14,<0.6.0)", "cohere (>=4,<5)", "deeplake (>=3.6.8,<4.0.0)", "docarray[hnswlib] (>=0.32.0,<0.33.0)", "duckduckgo-search (>=3.8.3,<4.0.0)", "elasticsearch (>=8,<9)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "google-api-python-client (==2.70.0)", "google-auth (>=2.18.1,<3.0.0)", "google-search-results (>=2,<3)", "gptcache (>=0.1.7)", "html2text (>=2020.1.16,<2021.0.0)", "huggingface_hub (>=0,<1)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "lancedb (>=0.1,<0.2)", "langkit (>=0.0.6,<0.1.0)", "lark (>=1.1.5,<2.0.0)", "libdeeplake (>=0.0.60,<0.0.61)", "librosa (>=0.10.0.post2,<0.11.0)", "lxml (>=4.9.2,<5.0.0)", "manifest-ml (>=0.0.1,<0.0.2)", "marqo (>=1.2.4,<2.0.0)", "momento (>=1.10.1,<2.0.0)", "nebula3-python (>=3.4.0,<4.0.0)", "neo4j (>=5.8.1,<6.0.0)", "networkx (>=2.6.3,<4)", "nlpcloud (>=1,<2)", "nltk (>=3,<4)", "nomic (>=1.0.43,<2.0.0)", "openai (>=0,<1)", "openlm (>=0.0.5,<0.0.6)", "opensearch-py (>=2.0.0,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pexpect (>=4.8.0,<5.0.0)", "pgvector (>=0.1.6,<0.2.0)", "pinecone-client (>=2,<3)", "pinecone-text (>=0.4.2,<0.5.0)", "psycopg2-binary (>=2.9.5,<3.0.0)", "pymongo (>=4.3.3,<5.0.0)", "pyowm (>=3.3.0,<4.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pytesseract (>=0.3.10,<0.4.0)", "python-arango (>=7.5.9,<8.0.0)", "pyvespa (>=0.33.0,<0.34.0)", "qdrant-client (>=1.3.1,<2.0.0)", "rdflib (>=6.3.2,<7.0.0)", "redis (>=4,<5)", "requests-toolbelt (>=1.0.0,<2.0.0)", "sentence-transformers (>=2,<3)", "singlestoredb (>=0.7.1,<0.8.0)", "tensorflow-text (>=2.11.0,<3.0.0)", "tigrisdb (>=1.0.0b6,<2.0.0)", "tiktoken (>=0.3.2,<0.6.0)", "torch (>=1,<3)", "transformers (>=4,<5)", "weaviate-client (>=3,<4)", "wikipedia (>=1,<2)", "wolframalpha (==5.0.0)"]
|
||||
azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "azure-search-documents (==11.4.0b8)", "openai (>=0,<1)"]
|
||||
clarifai = ["clarifai (>=9.1.0)"]
|
||||
cli = ["typer (>=0.9.0,<0.10.0)"]
|
||||
cohere = ["cohere (>=4,<5)"]
|
||||
docarray = ["docarray[hnswlib] (>=0.32.0,<0.33.0)"]
|
||||
embeddings = ["sentence-transformers (>=2,<3)"]
|
||||
extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "amazon-textract-caller (<2)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "dashvector (>=1.0.1,<2.0.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "gql (>=3.4.1,<4.0.0)", "html2text (>=2020.1.16,<2021.0.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (>=0,<1)", "openapi-schema-pydantic (>=1.2,<2.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"]
|
||||
javascript = ["esprima (>=4.0.1,<5.0.0)"]
|
||||
llms = ["clarifai (>=9.1.0)", "cohere (>=4,<5)", "huggingface_hub (>=0,<1)", "manifest-ml (>=0.0.1,<0.0.2)", "nlpcloud (>=1,<2)", "openai (>=0,<1)", "openlm (>=0.0.5,<0.0.6)", "torch (>=1,<3)", "transformers (>=4,<5)"]
|
||||
openai = ["openai (>=0,<1)", "tiktoken (>=0.3.2,<0.6.0)"]
|
||||
qdrant = ["qdrant-client (>=1.3.1,<2.0.0)"]
|
||||
text-helpers = ["chardet (>=5.1.0,<6.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "langsmith"
|
||||
version = "0.0.43"
|
||||
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
|
||||
optional = false
|
||||
python-versions = ">=3.8.1,<4.0"
|
||||
files = [
|
||||
{file = "langsmith-0.0.43-py3-none-any.whl", hash = "sha256:27854bebdae6a35c88e1c1172e6abba27592287b70511aca2a953a59fade0e87"},
|
||||
{file = "langsmith-0.0.43.tar.gz", hash = "sha256:f7705f13eb8ce3b8eb16c4d2b2760c62cfb9a3b3ab6aa0728afa84d26b2a6e55"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pydantic = ">=1,<3"
|
||||
requests = ">=2,<3"
|
||||
|
||||
[[package]]
|
||||
name = "lazy-object-proxy"
|
||||
version = "1.9.0"
|
||||
|
@ -862,6 +960,16 @@ files = [
|
|||
{file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
|
||||
{file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
|
||||
{file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
|
||||
{file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
|
||||
{file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
|
||||
{file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
|
||||
{file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
|
||||
{file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
|
||||
{file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
|
||||
{file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
|
||||
{file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
|
||||
{file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
|
||||
{file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
|
||||
{file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"},
|
||||
{file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"},
|
||||
{file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"},
|
||||
|
@ -894,6 +1002,26 @@ files = [
|
|||
{file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "marshmallow"
|
||||
version = "3.20.1"
|
||||
description = "A lightweight library for converting complex datatypes to and from native Python datatypes."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "marshmallow-3.20.1-py3-none-any.whl", hash = "sha256:684939db93e80ad3561392f47be0230743131560a41c5110684c16e21ade0a5c"},
|
||||
{file = "marshmallow-3.20.1.tar.gz", hash = "sha256:5d2371bbe42000f2b3fb5eaa065224df7d8f8597bc19a1bbfa5bfe7fba8da889"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
packaging = ">=17.0"
|
||||
|
||||
[package.extras]
|
||||
dev = ["flake8 (==6.0.0)", "flake8-bugbear (==23.7.10)", "mypy (==1.4.1)", "pre-commit (>=2.4,<4.0)", "pytest", "pytz", "simplejson", "tox"]
|
||||
docs = ["alabaster (==0.7.13)", "autodocsumm (==0.2.11)", "sphinx (==7.0.1)", "sphinx-issues (==3.0.1)", "sphinx-version-warning (==1.1.2)"]
|
||||
lint = ["flake8 (==6.0.0)", "flake8-bugbear (==23.7.10)", "mypy (==1.4.1)", "pre-commit (>=2.4,<4.0)"]
|
||||
tests = ["pytest", "pytz", "simplejson"]
|
||||
|
||||
[[package]]
|
||||
name = "mccabe"
|
||||
version = "0.7.0"
|
||||
|
@ -1013,6 +1141,40 @@ files = [
|
|||
[package.dependencies]
|
||||
setuptools = "*"
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "1.25.2"
|
||||
description = "Fundamental package for array computing in Python"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "numpy-1.25.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db3ccc4e37a6873045580d413fe79b68e47a681af8db2e046f1dacfa11f86eb3"},
|
||||
{file = "numpy-1.25.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:90319e4f002795ccfc9050110bbbaa16c944b1c37c0baeea43c5fb881693ae1f"},
|
||||
{file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4a913e29b418d096e696ddd422d8a5d13ffba4ea91f9f60440a3b759b0187"},
|
||||
{file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f08f2e037bba04e707eebf4bc934f1972a315c883a9e0ebfa8a7756eabf9e357"},
|
||||
{file = "numpy-1.25.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bec1e7213c7cb00d67093247f8c4db156fd03075f49876957dca4711306d39c9"},
|
||||
{file = "numpy-1.25.2-cp310-cp310-win32.whl", hash = "sha256:7dc869c0c75988e1c693d0e2d5b26034644399dd929bc049db55395b1379e044"},
|
||||
{file = "numpy-1.25.2-cp310-cp310-win_amd64.whl", hash = "sha256:834b386f2b8210dca38c71a6e0f4fd6922f7d3fcff935dbe3a570945acb1b545"},
|
||||
{file = "numpy-1.25.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5462d19336db4560041517dbb7759c21d181a67cb01b36ca109b2ae37d32418"},
|
||||
{file = "numpy-1.25.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5652ea24d33585ea39eb6a6a15dac87a1206a692719ff45d53c5282e66d4a8f"},
|
||||
{file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d60fbae8e0019865fc4784745814cff1c421df5afee233db6d88ab4f14655a2"},
|
||||
{file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e7f0f7f6d0eee8364b9a6304c2845b9c491ac706048c7e8cf47b83123b8dbf"},
|
||||
{file = "numpy-1.25.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bb33d5a1cf360304754913a350edda36d5b8c5331a8237268c48f91253c3a364"},
|
||||
{file = "numpy-1.25.2-cp311-cp311-win32.whl", hash = "sha256:5883c06bb92f2e6c8181df7b39971a5fb436288db58b5a1c3967702d4278691d"},
|
||||
{file = "numpy-1.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:5c97325a0ba6f9d041feb9390924614b60b99209a71a69c876f71052521d42a4"},
|
||||
{file = "numpy-1.25.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b79e513d7aac42ae918db3ad1341a015488530d0bb2a6abcbdd10a3a829ccfd3"},
|
||||
{file = "numpy-1.25.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb942bfb6f84df5ce05dbf4b46673ffed0d3da59f13635ea9b926af3deb76926"},
|
||||
{file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e0746410e73384e70d286f93abf2520035250aad8c5714240b0492a7302fdca"},
|
||||
{file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7806500e4f5bdd04095e849265e55de20d8cc4b661b038957354327f6d9b295"},
|
||||
{file = "numpy-1.25.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8b77775f4b7df768967a7c8b3567e309f617dd5e99aeb886fa14dc1a0791141f"},
|
||||
{file = "numpy-1.25.2-cp39-cp39-win32.whl", hash = "sha256:2792d23d62ec51e50ce4d4b7d73de8f67a2fd3ea710dcbc8563a51a03fb07b01"},
|
||||
{file = "numpy-1.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:76b4115d42a7dfc5d485d358728cdd8719be33cc5ec6ec08632a5d6fca2ed380"},
|
||||
{file = "numpy-1.25.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a1329e26f46230bf77b02cc19e900db9b52f398d6722ca853349a782d4cff55"},
|
||||
{file = "numpy-1.25.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3abc71e8b6edba80a01a52e66d83c5d14433cbcd26a40c329ec7ed09f37901"},
|
||||
{file = "numpy-1.25.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1b9735c27cea5d995496f46a8b1cd7b408b3f34b6d50459d9ac8fe3a20cc17bf"},
|
||||
{file = "numpy-1.25.2.tar.gz", hash = "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openai"
|
||||
version = "0.28.1"
|
||||
|
@ -1037,71 +1199,61 @@ wandb = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1
|
|||
|
||||
[[package]]
|
||||
name = "orjson"
|
||||
version = "3.9.7"
|
||||
version = "3.9.9"
|
||||
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "orjson-3.9.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b6df858e37c321cefbf27fe7ece30a950bcc3a75618a804a0dcef7ed9dd9c92d"},
|
||||
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5198633137780d78b86bb54dafaaa9baea698b4f059456cd4554ab7009619221"},
|
||||
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e736815b30f7e3c9044ec06a98ee59e217a833227e10eb157f44071faddd7c5"},
|
||||
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a19e4074bc98793458b4b3ba35a9a1d132179345e60e152a1bb48c538ab863c4"},
|
||||
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80acafe396ab689a326ab0d80f8cc61dec0dd2c5dca5b4b3825e7b1e0132c101"},
|
||||
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:355efdbbf0cecc3bd9b12589b8f8e9f03c813a115efa53f8dc2a523bfdb01334"},
|
||||
{file = "orjson-3.9.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3aab72d2cef7f1dd6104c89b0b4d6b416b0db5ca87cc2fac5f79c5601f549cc2"},
|
||||
{file = "orjson-3.9.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:36b1df2e4095368ee388190687cb1b8557c67bc38400a942a1a77713580b50ae"},
|
||||
{file = "orjson-3.9.7-cp310-none-win32.whl", hash = "sha256:e94b7b31aa0d65f5b7c72dd8f8227dbd3e30354b99e7a9af096d967a77f2a580"},
|
||||
{file = "orjson-3.9.7-cp310-none-win_amd64.whl", hash = "sha256:82720ab0cf5bb436bbd97a319ac529aee06077ff7e61cab57cee04a596c4f9b4"},
|
||||
{file = "orjson-3.9.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1f8b47650f90e298b78ecf4df003f66f54acdba6a0f763cc4df1eab048fe3738"},
|
||||
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f738fee63eb263530efd4d2e9c76316c1f47b3bbf38c1bf45ae9625feed0395e"},
|
||||
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:38e34c3a21ed41a7dbd5349e24c3725be5416641fdeedf8f56fcbab6d981c900"},
|
||||
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21a3344163be3b2c7e22cef14fa5abe957a892b2ea0525ee86ad8186921b6cf0"},
|
||||
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23be6b22aab83f440b62a6f5975bcabeecb672bc627face6a83bc7aeb495dc7e"},
|
||||
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5205ec0dfab1887dd383597012199f5175035e782cdb013c542187d280ca443"},
|
||||
{file = "orjson-3.9.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8769806ea0b45d7bf75cad253fba9ac6700b7050ebb19337ff6b4e9060f963fa"},
|
||||
{file = "orjson-3.9.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f9e01239abea2f52a429fe9d95c96df95f078f0172489d691b4a848ace54a476"},
|
||||
{file = "orjson-3.9.7-cp311-none-win32.whl", hash = "sha256:8bdb6c911dae5fbf110fe4f5cba578437526334df381b3554b6ab7f626e5eeca"},
|
||||
{file = "orjson-3.9.7-cp311-none-win_amd64.whl", hash = "sha256:9d62c583b5110e6a5cf5169ab616aa4ec71f2c0c30f833306f9e378cf51b6c86"},
|
||||
{file = "orjson-3.9.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1c3cee5c23979deb8d1b82dc4cc49be59cccc0547999dbe9adb434bb7af11cf7"},
|
||||
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a347d7b43cb609e780ff8d7b3107d4bcb5b6fd09c2702aa7bdf52f15ed09fa09"},
|
||||
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:154fd67216c2ca38a2edb4089584504fbb6c0694b518b9020ad35ecc97252bb9"},
|
||||
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ea3e63e61b4b0beeb08508458bdff2daca7a321468d3c4b320a758a2f554d31"},
|
||||
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1eb0b0b2476f357eb2975ff040ef23978137aa674cd86204cfd15d2d17318588"},
|
||||
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b9a20a03576c6b7022926f614ac5a6b0914486825eac89196adf3267c6489d"},
|
||||
{file = "orjson-3.9.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:915e22c93e7b7b636240c5a79da5f6e4e84988d699656c8e27f2ac4c95b8dcc0"},
|
||||
{file = "orjson-3.9.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f26fb3e8e3e2ee405c947ff44a3e384e8fa1843bc35830fe6f3d9a95a1147b6e"},
|
||||
{file = "orjson-3.9.7-cp312-none-win_amd64.whl", hash = "sha256:d8692948cada6ee21f33db5e23460f71c8010d6dfcfe293c9b96737600a7df78"},
|
||||
{file = "orjson-3.9.7-cp37-cp37m-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7bab596678d29ad969a524823c4e828929a90c09e91cc438e0ad79b37ce41166"},
|
||||
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63ef3d371ea0b7239ace284cab9cd00d9c92b73119a7c274b437adb09bda35e6"},
|
||||
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f8fcf696bbbc584c0c7ed4adb92fd2ad7d153a50258842787bc1524e50d7081"},
|
||||
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90fe73a1f0321265126cbba13677dcceb367d926c7a65807bd80916af4c17047"},
|
||||
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:45a47f41b6c3beeb31ac5cf0ff7524987cfcce0a10c43156eb3ee8d92d92bf22"},
|
||||
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a2937f528c84e64be20cb80e70cea76a6dfb74b628a04dab130679d4454395c"},
|
||||
{file = "orjson-3.9.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b4fb306c96e04c5863d52ba8d65137917a3d999059c11e659eba7b75a69167bd"},
|
||||
{file = "orjson-3.9.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:410aa9d34ad1089898f3db461b7b744d0efcf9252a9415bbdf23540d4f67589f"},
|
||||
{file = "orjson-3.9.7-cp37-none-win32.whl", hash = "sha256:26ffb398de58247ff7bde895fe30817a036f967b0ad0e1cf2b54bda5f8dcfdd9"},
|
||||
{file = "orjson-3.9.7-cp37-none-win_amd64.whl", hash = "sha256:bcb9a60ed2101af2af450318cd89c6b8313e9f8df4e8fb12b657b2e97227cf08"},
|
||||
{file = "orjson-3.9.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5da9032dac184b2ae2da4bce423edff7db34bfd936ebd7d4207ea45840f03905"},
|
||||
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7951af8f2998045c656ba8062e8edf5e83fd82b912534ab1de1345de08a41d2b"},
|
||||
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8e59650292aa3a8ea78073fc84184538783966528e442a1b9ed653aa282edcf"},
|
||||
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9274ba499e7dfb8a651ee876d80386b481336d3868cba29af839370514e4dce0"},
|
||||
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca1706e8b8b565e934c142db6a9592e6401dc430e4b067a97781a997070c5378"},
|
||||
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83cc275cf6dcb1a248e1876cdefd3f9b5f01063854acdfd687ec360cd3c9712a"},
|
||||
{file = "orjson-3.9.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:11c10f31f2c2056585f89d8229a56013bc2fe5de51e095ebc71868d070a8dd81"},
|
||||
{file = "orjson-3.9.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cf334ce1d2fadd1bf3e5e9bf15e58e0c42b26eb6590875ce65bd877d917a58aa"},
|
||||
{file = "orjson-3.9.7-cp38-none-win32.whl", hash = "sha256:76a0fc023910d8a8ab64daed8d31d608446d2d77c6474b616b34537aa7b79c7f"},
|
||||
{file = "orjson-3.9.7-cp38-none-win_amd64.whl", hash = "sha256:7a34a199d89d82d1897fd4a47820eb50947eec9cda5fd73f4578ff692a912f89"},
|
||||
{file = "orjson-3.9.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e7e7f44e091b93eb39db88bb0cb765db09b7a7f64aea2f35e7d86cbf47046c65"},
|
||||
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d647b2a9c45a23a84c3e70e19d120011cba5f56131d185c1b78685457320bb"},
|
||||
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0eb850a87e900a9c484150c414e21af53a6125a13f6e378cf4cc11ae86c8f9c5"},
|
||||
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f4b0042d8388ac85b8330b65406c84c3229420a05068445c13ca28cc222f1f7"},
|
||||
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd3e7aae977c723cc1dbb82f97babdb5e5fbce109630fbabb2ea5053523c89d3"},
|
||||
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c616b796358a70b1f675a24628e4823b67d9e376df2703e893da58247458956"},
|
||||
{file = "orjson-3.9.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c3ba725cf5cf87d2d2d988d39c6a2a8b6fc983d78ff71bc728b0be54c869c884"},
|
||||
{file = "orjson-3.9.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4891d4c934f88b6c29b56395dfc7014ebf7e10b9e22ffd9877784e16c6b2064f"},
|
||||
{file = "orjson-3.9.7-cp39-none-win32.whl", hash = "sha256:14d3fb6cd1040a4a4a530b28e8085131ed94ebc90d72793c59a713de34b60838"},
|
||||
{file = "orjson-3.9.7-cp39-none-win_amd64.whl", hash = "sha256:9ef82157bbcecd75d6296d5d8b2d792242afcd064eb1ac573f8847b52e58f677"},
|
||||
{file = "orjson-3.9.7.tar.gz", hash = "sha256:85e39198f78e2f7e054d296395f6c96f5e02892337746ef5b6a1bf3ed5910142"},
|
||||
{file = "orjson-3.9.9-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f28090060a31f4d11221f9ba48b2273b0d04b702f4dcaa197c38c64ce639cc51"},
|
||||
{file = "orjson-3.9.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8038ba245d0c0a6337cfb6747ea0c51fe18b0cf1a4bc943d530fd66799fae33d"},
|
||||
{file = "orjson-3.9.9-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:543b36df56db195739c70d645ecd43e49b44d5ead5f8f645d2782af118249b37"},
|
||||
{file = "orjson-3.9.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8e7877256b5092f1e4e48fc0f1004728dc6901e7a4ffaa4acb0a9578610aa4ce"},
|
||||
{file = "orjson-3.9.9-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12b83e0d8ba4ca88b894c3e00efc59fe6d53d9ffb5dbbb79d437a466fc1a513d"},
|
||||
{file = "orjson-3.9.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef06431f021453a47a9abb7f7853f04f031d31fbdfe1cc83e3c6aadde502cce"},
|
||||
{file = "orjson-3.9.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0a1a4d9e64597e550428ba091e51a4bcddc7a335c8f9297effbfa67078972b5c"},
|
||||
{file = "orjson-3.9.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:879d2d1f6085c9c0831cec6716c63aaa89e41d8e036cabb19a315498c173fcc6"},
|
||||
{file = "orjson-3.9.9-cp310-none-win32.whl", hash = "sha256:d3f56e41bc79d30fdf077073072f2377d2ebf0b946b01f2009ab58b08907bc28"},
|
||||
{file = "orjson-3.9.9-cp310-none-win_amd64.whl", hash = "sha256:ab7bae2b8bf17620ed381e4101aeeb64b3ba2a45fc74c7617c633a923cb0f169"},
|
||||
{file = "orjson-3.9.9-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:31d676bc236f6e919d100fb85d0a99812cff1ebffaa58106eaaec9399693e227"},
|
||||
{file = "orjson-3.9.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:678ffb5c0a6b1518b149cc328c610615d70d9297e351e12c01d0beed5d65360f"},
|
||||
{file = "orjson-3.9.9-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a71b0cc21f2c324747bc77c35161e0438e3b5e72db6d3b515310457aba743f7f"},
|
||||
{file = "orjson-3.9.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae72621f216d1d990468291b1ec153e1b46e0ed188a86d54e0941f3dabd09ee8"},
|
||||
{file = "orjson-3.9.9-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:512e5a41af008e76451f5a344941d61f48dddcf7d7ddd3073deb555de64596a6"},
|
||||
{file = "orjson-3.9.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f89dc338a12f4357f5bf1b098d3dea6072fb0b643fd35fec556f4941b31ae27"},
|
||||
{file = "orjson-3.9.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:957a45fb201c61b78bcf655a16afbe8a36c2c27f18a998bd6b5d8a35e358d4ad"},
|
||||
{file = "orjson-3.9.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1c01cf4b8e00c7e98a0a7cf606a30a26c32adf2560be2d7d5d6766d6f474b31"},
|
||||
{file = "orjson-3.9.9-cp311-none-win32.whl", hash = "sha256:397a185e5dd7f8ebe88a063fe13e34d61d394ebb8c70a443cee7661b9c89bda7"},
|
||||
{file = "orjson-3.9.9-cp311-none-win_amd64.whl", hash = "sha256:24301f2d99d670ded4fb5e2f87643bc7428a54ba49176e38deb2887e42fe82fb"},
|
||||
{file = "orjson-3.9.9-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:bd55ea5cce3addc03f8fb0705be0cfed63b048acc4f20914ce5e1375b15a293b"},
|
||||
{file = "orjson-3.9.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b28c1a65cd13fff5958ab8b350f0921121691464a7a1752936b06ed25c0c7b6e"},
|
||||
{file = "orjson-3.9.9-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b97a67c47840467ccf116136450c50b6ed4e16a8919c81a4b4faef71e0a2b3f4"},
|
||||
{file = "orjson-3.9.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75b805549cbbcb963e9c9068f1a05abd0ea4c34edc81f8d8ef2edb7e139e5b0f"},
|
||||
{file = "orjson-3.9.9-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5424ecbafe57b2de30d3b5736c5d5835064d522185516a372eea069b92786ba6"},
|
||||
{file = "orjson-3.9.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d2cd6ef4726ef1b8c63e30d8287225a383dbd1de3424d287b37c1906d8d2855"},
|
||||
{file = "orjson-3.9.9-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c959550e0705dc9f59de8fca1a316da0d9b115991806b217c82931ac81d75f74"},
|
||||
{file = "orjson-3.9.9-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ece2d8ed4c34903e7f1b64fb1e448a00e919a4cdb104fc713ad34b055b665fca"},
|
||||
{file = "orjson-3.9.9-cp312-none-win_amd64.whl", hash = "sha256:f708ca623287186e5876256cb30599308bce9b2757f90d917b7186de54ce6547"},
|
||||
{file = "orjson-3.9.9-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:335406231f9247f985df045f0c0c8f6b6d5d6b3ff17b41a57c1e8ef1a31b4d04"},
|
||||
{file = "orjson-3.9.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d9b5440a5d215d9e1cfd4aee35fd4101a8b8ceb8329f549c16e3894ed9f18b5"},
|
||||
{file = "orjson-3.9.9-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e98ca450cb4fb176dd572ce28c6623de6923752c70556be4ef79764505320acb"},
|
||||
{file = "orjson-3.9.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3bf6ca6bce22eb89dd0650ef49c77341440def966abcb7a2d01de8453df083a"},
|
||||
{file = "orjson-3.9.9-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb50d869b3c97c7c5187eda3759e8eb15deb1271d694bc5d6ba7040db9e29036"},
|
||||
{file = "orjson-3.9.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fcf06c69ccc78e32d9f28aa382ab2ab08bf54b696dbe00ee566808fdf05da7d"},
|
||||
{file = "orjson-3.9.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9a4402e7df1b5c9a4c71c7892e1c8f43f642371d13c73242bda5964be6231f95"},
|
||||
{file = "orjson-3.9.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b20becf50d4aec7114dc902b58d85c6431b3a59b04caa977e6ce67b6fee0e159"},
|
||||
{file = "orjson-3.9.9-cp38-none-win32.whl", hash = "sha256:1f352117eccac268a59fedac884b0518347f5e2b55b9f650c2463dd1e732eb61"},
|
||||
{file = "orjson-3.9.9-cp38-none-win_amd64.whl", hash = "sha256:c4eb31a8e8a5e1d9af5aa9e247c2a52ad5cf7e968aaa9aaefdff98cfcc7f2e37"},
|
||||
{file = "orjson-3.9.9-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a308aeac326c2bafbca9abbae1e1fcf682b06e78a54dad0347b760525838d85"},
|
||||
{file = "orjson-3.9.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e159b97f5676dcdac0d0f75ec856ef5851707f61d262851eb41a30e8fadad7c9"},
|
||||
{file = "orjson-3.9.9-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f692e7aabad92fa0fff5b13a846fb586b02109475652207ec96733a085019d80"},
|
||||
{file = "orjson-3.9.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cffb77cf0cd3cbf20eb603f932e0dde51b45134bdd2d439c9f57924581bb395b"},
|
||||
{file = "orjson-3.9.9-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c63eca397127ebf46b59c9c1fb77b30dd7a8fc808ac385e7a58a7e64bae6e106"},
|
||||
{file = "orjson-3.9.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f0c024a75e8ba5d9101facb4fb5a028cdabe3cdfe081534f2a9de0d5062af2"},
|
||||
{file = "orjson-3.9.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8cba20c9815c2a003b8ca4429b0ad4aa87cb6649af41365821249f0fd397148e"},
|
||||
{file = "orjson-3.9.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:906cac73b7818c20cf0f6a7dde5a6f009c52aecc318416c7af5ea37f15ca7e66"},
|
||||
{file = "orjson-3.9.9-cp39-none-win32.whl", hash = "sha256:50232572dd300c49f134838c8e7e0917f29a91f97dbd608d23f2895248464b7f"},
|
||||
{file = "orjson-3.9.9-cp39-none-win_amd64.whl", hash = "sha256:920814e02e3dd7af12f0262bbc18b9fe353f75a0d0c237f6a67d270da1a1bb44"},
|
||||
{file = "orjson-3.9.9.tar.gz", hash = "sha256:02e693843c2959befdd82d1ebae8b05ed12d1cb821605d5f9fe9f98ca5c9fd2b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1126,6 +1278,19 @@ files = [
|
|||
{file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pgvector"
|
||||
version = "0.2.3"
|
||||
description = "pgvector support for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pgvector-0.2.3-py2.py3-none-any.whl", hash = "sha256:9d53dc01138ecc7c9aca64e4680cfa9edf4c38f9cb8ed7098317871fdd211824"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
numpy = "*"
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "3.11.0"
|
||||
|
@ -1595,6 +1760,65 @@ files = [
|
|||
[package.dependencies]
|
||||
tokenize-rt = ">=5.2.0"
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.1"
|
||||
description = "YAML parser and emitter for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
|
||||
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.31.0"
|
||||
|
@ -1717,9 +1941,7 @@ python-versions = ">=3.7"
|
|||
files = [
|
||||
{file = "SQLAlchemy-2.0.22-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f146c61ae128ab43ea3a0955de1af7e1633942c2b2b4985ac51cc292daf33222"},
|
||||
{file = "SQLAlchemy-2.0.22-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:875de9414393e778b655a3d97d60465eb3fae7c919e88b70cc10b40b9f56042d"},
|
||||
{file = "SQLAlchemy-2.0.22-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13790cb42f917c45c9c850b39b9941539ca8ee7917dacf099cc0b569f3d40da7"},
|
||||
{file = "SQLAlchemy-2.0.22-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e04ab55cf49daf1aeb8c622c54d23fa4bec91cb051a43cc24351ba97e1dd09f5"},
|
||||
{file = "SQLAlchemy-2.0.22-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a42c9fa3abcda0dcfad053e49c4f752eef71ecd8c155221e18b99d4224621176"},
|
||||
{file = "SQLAlchemy-2.0.22-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:14cd3bcbb853379fef2cd01e7c64a5d6f1d005406d877ed9509afb7a05ff40a5"},
|
||||
{file = "SQLAlchemy-2.0.22-cp310-cp310-win32.whl", hash = "sha256:d143c5a9dada696bcfdb96ba2de4a47d5a89168e71d05a076e88a01386872f97"},
|
||||
{file = "SQLAlchemy-2.0.22-cp310-cp310-win_amd64.whl", hash = "sha256:ccd87c25e4c8559e1b918d46b4fa90b37f459c9b4566f1dfbce0eb8122571547"},
|
||||
|
@ -1740,25 +1962,19 @@ files = [
|
|||
{file = "SQLAlchemy-2.0.22-cp312-cp312-win32.whl", hash = "sha256:154a32f3c7b00de3d090bc60ec8006a78149e221f1182e3edcf0376016be9396"},
|
||||
{file = "SQLAlchemy-2.0.22-cp312-cp312-win_amd64.whl", hash = "sha256:129415f89744b05741c6f0b04a84525f37fbabe5dc3774f7edf100e7458c48cd"},
|
||||
{file = "SQLAlchemy-2.0.22-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3940677d341f2b685a999bffe7078697b5848a40b5f6952794ffcf3af150c301"},
|
||||
{file = "SQLAlchemy-2.0.22-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55914d45a631b81a8a2cb1a54f03eea265cf1783241ac55396ec6d735be14883"},
|
||||
{file = "SQLAlchemy-2.0.22-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2096d6b018d242a2bcc9e451618166f860bb0304f590d205173d317b69986c95"},
|
||||
{file = "SQLAlchemy-2.0.22-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:19c6986cf2fb4bc8e0e846f97f4135a8e753b57d2aaaa87c50f9acbe606bd1db"},
|
||||
{file = "SQLAlchemy-2.0.22-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6ac28bd6888fe3c81fbe97584eb0b96804bd7032d6100b9701255d9441373ec1"},
|
||||
{file = "SQLAlchemy-2.0.22-cp37-cp37m-win32.whl", hash = "sha256:cb9a758ad973e795267da334a92dd82bb7555cb36a0960dcabcf724d26299db8"},
|
||||
{file = "SQLAlchemy-2.0.22-cp37-cp37m-win_amd64.whl", hash = "sha256:40b1206a0d923e73aa54f0a6bd61419a96b914f1cd19900b6c8226899d9742ad"},
|
||||
{file = "SQLAlchemy-2.0.22-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3aa1472bf44f61dd27987cd051f1c893b7d3b17238bff8c23fceaef4f1133868"},
|
||||
{file = "SQLAlchemy-2.0.22-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:56a7e2bb639df9263bf6418231bc2a92a773f57886d371ddb7a869a24919face"},
|
||||
{file = "SQLAlchemy-2.0.22-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ccca778c0737a773a1ad86b68bda52a71ad5950b25e120b6eb1330f0df54c3d0"},
|
||||
{file = "SQLAlchemy-2.0.22-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c6c3e9350f9fb16de5b5e5fbf17b578811a52d71bb784cc5ff71acb7de2a7f9"},
|
||||
{file = "SQLAlchemy-2.0.22-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:564e9f9e4e6466273dbfab0e0a2e5fe819eec480c57b53a2cdee8e4fdae3ad5f"},
|
||||
{file = "SQLAlchemy-2.0.22-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:af66001d7b76a3fab0d5e4c1ec9339ac45748bc4a399cbc2baa48c1980d3c1f4"},
|
||||
{file = "SQLAlchemy-2.0.22-cp38-cp38-win32.whl", hash = "sha256:9e55dff5ec115316dd7a083cdc1a52de63693695aecf72bc53a8e1468ce429e5"},
|
||||
{file = "SQLAlchemy-2.0.22-cp38-cp38-win_amd64.whl", hash = "sha256:4e869a8ff7ee7a833b74868a0887e8462445ec462432d8cbeff5e85f475186da"},
|
||||
{file = "SQLAlchemy-2.0.22-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9886a72c8e6371280cb247c5d32c9c8fa141dc560124348762db8a8b236f8692"},
|
||||
{file = "SQLAlchemy-2.0.22-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a571bc8ac092a3175a1d994794a8e7a1f2f651e7c744de24a19b4f740fe95034"},
|
||||
{file = "SQLAlchemy-2.0.22-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8db5ba8b7da759b727faebc4289a9e6a51edadc7fc32207a30f7c6203a181592"},
|
||||
{file = "SQLAlchemy-2.0.22-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b0b3f2686c3f162123adba3cb8b626ed7e9b8433ab528e36ed270b4f70d1cdb"},
|
||||
{file = "SQLAlchemy-2.0.22-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0c1fea8c0abcb070ffe15311853abfda4e55bf7dc1d4889497b3403629f3bf00"},
|
||||
{file = "SQLAlchemy-2.0.22-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4bb062784f37b2d75fd9b074c8ec360ad5df71f933f927e9e95c50eb8e05323c"},
|
||||
{file = "SQLAlchemy-2.0.22-cp39-cp39-win32.whl", hash = "sha256:58a3aba1bfb32ae7af68da3f277ed91d9f57620cf7ce651db96636790a78b736"},
|
||||
{file = "SQLAlchemy-2.0.22-cp39-cp39-win_amd64.whl", hash = "sha256:92e512a6af769e4725fa5b25981ba790335d42c5977e94ded07db7d641490a85"},
|
||||
|
@ -1767,7 +1983,7 @@ files = [
|
|||
]
|
||||
|
||||
[package.dependencies]
|
||||
greenlet = {version = "!=0.4.17", markers = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\""}
|
||||
greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""}
|
||||
typing-extensions = ">=4.2.0"
|
||||
|
||||
[package.extras]
|
||||
|
@ -1811,6 +2027,20 @@ anyio = ">=3.4.0,<5"
|
|||
[package.extras]
|
||||
full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"]
|
||||
|
||||
[[package]]
|
||||
name = "tenacity"
|
||||
version = "8.2.3"
|
||||
description = "Retry code until it succeeds"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "tenacity-8.2.3-py3-none-any.whl", hash = "sha256:ce510e327a630c9e1beaf17d42e6ffacc88185044ad85cf74c0a8887c6a0f88c"},
|
||||
{file = "tenacity-8.2.3.tar.gz", hash = "sha256:5398ef0d78e63f40007c1fb4c0bff96e1911394d2fa8d194f77619c05ff6cc8a"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
doc = ["reno", "sphinx", "tornado (>=4.5)"]
|
||||
|
||||
[[package]]
|
||||
name = "tokenize-rt"
|
||||
version = "5.2.0"
|
||||
|
@ -1878,6 +2108,21 @@ files = [
|
|||
{file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-inspect"
|
||||
version = "0.9.0"
|
||||
description = "Runtime inspection utilities for typing module."
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"},
|
||||
{file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
mypy-extensions = ">=0.3.0"
|
||||
typing-extensions = ">=3.7.4"
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.0.6"
|
||||
|
@ -2087,4 +2332,4 @@ multidict = ">=4.0"
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.11"
|
||||
content-hash = "cf7c2e88dd377d6929d87da3553dabdc48acaa30d58f7de2d8303159180b0c09"
|
||||
content-hash = "e89034ff2a2129b8963474f4adc276ef030e60de0178dc93efa754d5df11f81f"
|
||||
|
|
|
@ -13,7 +13,7 @@ profile = "black"
|
|||
py_version = "311"
|
||||
|
||||
[tool.poetry]
|
||||
authors = ["ijaric@gmail.com", "jsdio@jsdio.ru"]
|
||||
authors = ["jsdio@jsdio.ru"]
|
||||
description = ""
|
||||
name = "fastapi_project"
|
||||
readme = "README.md"
|
||||
|
@ -22,17 +22,17 @@ version = "0.1.0"
|
|||
[tool.poetry.dependencies]
|
||||
alembic = "^1.12.0"
|
||||
asyncpg = "^0.28.0"
|
||||
dill = "^0.3.7"
|
||||
fastapi = "0.103.1"
|
||||
greenlet = "^2.0.2"
|
||||
httpx = "^0.25.0"
|
||||
langchain = "^0.0.314"
|
||||
multidict = "^6.0.4"
|
||||
openai = "^0.28.1"
|
||||
orjson = "3.9.7"
|
||||
orjson = "^3.9.7"
|
||||
pgvector = "^0.2.3"
|
||||
psycopg2-binary = "^2.9.9"
|
||||
pydantic = {extras = ["email"], version = "^2.3.0"}
|
||||
pydantic-settings = "^2.0.3"
|
||||
pytest = "^7.4.2"
|
||||
pytest-asyncio = "^0.21.1"
|
||||
python = "^3.11"
|
||||
python-jose = "^3.3.0"
|
||||
|
@ -40,7 +40,6 @@ python-magic = "^0.4.27"
|
|||
python-multipart = "^0.0.6"
|
||||
sqlalchemy = "^2.0.20"
|
||||
uvicorn = "^0.23.2"
|
||||
wrapt = "^1.15.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
black = "^23.7.0"
|
||||
|
|
|
@ -8,3 +8,6 @@ BOT_ADMINS=123456,654321
|
|||
API_PROTOCOL=http
|
||||
API_URL=api
|
||||
API_PORT=8000
|
||||
|
||||
REDIS_HOST=redis
|
||||
REDIS_PORT=6379
|
||||
|
|
|
@ -12,6 +12,22 @@ services:
|
|||
networks:
|
||||
- tg_bot_network
|
||||
|
||||
redis:
|
||||
image: redis:7.0.11
|
||||
restart: always
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "127.0.0.1:${REDIS_PORT}:${REDIS_PORT}"
|
||||
command: redis-server --bind 0.0.0.0 --appendonly yes
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
networks:
|
||||
- tg_bot_network
|
||||
|
||||
volumes:
|
||||
redis_data:
|
||||
|
||||
networks:
|
||||
tg_bot_network:
|
||||
driver: bridge
|
||||
|
|
Loading…
Reference in New Issue
Block a user