1
0
mirror of https://github.com/ijaric/voice_assistant.git synced 2025-05-23 22:13:26 +00:00

feat: [#60] review fix

This commit is contained in:
Григорич 2023-10-15 23:15:39 +03:00
parent ce37502b0b
commit 6d0376e09e
19 changed files with 98 additions and 31 deletions

51
.env.example Normal file
View File

@ -0,0 +1,51 @@
# API
POSTGRES_DRIVER=postgresql+asyncpg
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_USER=app
POSTGRES_PASSWORD=123qwe
POSTGRES_DB_NAME=movies_database
NGINX_PORT=80
API_HOST=0.0.0.0
API_PORT=8000
API_PROTOCOL=http
API_URL=api
JWT_SECRET_KEY=v9LctjUWwol4XbvczPiLFMDtZ8aal7mm
JWT_ALGORITHM=HS256
APP_RELOAD=True
VOICE_AVAILABLE_FORMATS=mp3,ogg,wav,oga
VOICE_MAX_INPUT_SIZE=5120
VOICE_MAX_INPUT_SECONDS=30
OPENAI_API_KEY=sk-123456789
OPENAI_STT_MODEL=whisper-1
PROXY_HOST=213.166.72.28
PROXY_PORT=9185
PROXY_USER=RUnj7n
PROXY_PASSWORD=GPTWgk
PROXY_ENABLE=True
TTS_YANDEX_API_KEY=SfdSDFSDFSDF
TTS_YANDEX_AUDIO_FORMAT=oggopus
TTS_YANDEX_SAMPLE_RATE_HERTZ=48000
TTS_ELEVEN_LABS_API_KEY=SDFSFsdfsdf
TTS_ELEVEN_LABS_DEFAULT_VOICE_ID=EXAVITQu4vr4xnSDxMaL
# TGBOT
BOT_CONTAINER_NAME=bot_container_name
BOT_IMAGE_NAME=botimage_name
BOT_NAME=mybotname
BOT_TOKEN=1234567890:DSFsdfsdfsdfSDf
BOT_ADMINS=1234567890
REDIS_HOST=redis
REDIS_PORT=6379

View File

@ -29,7 +29,7 @@
1. Скачать [файл базы данных](https://disk.yandex.ru/d/ZAKDDg8lP9DHBQ) с `embeddings` и поместить её по пути `src/assistant/data/dump.sql`. 1. Скачать [файл базы данных](https://disk.yandex.ru/d/ZAKDDg8lP9DHBQ) с `embeddings` и поместить её по пути `src/assistant/data/dump.sql`.
2. В директории `src/assistant` файл `.env.example` переименовать в `.env` и заполнить переменные окружения. 2. В файл `.env.example` переименовать в `.env` и заполнить переменные окружения.
Пример заполнения переменных окружения: Пример заполнения переменных окружения:
``` ```
@ -68,12 +68,7 @@ TTS_YANDEX_SAMPLE_RATE_HERTZ=48000 # Частота дискретизации
TTS_ELEVEN_LABS_API_KEY=1234567890 # API-ключ ElevenLabs TTS_ELEVEN_LABS_API_KEY=1234567890 # API-ключ ElevenLabs
TTS_ELEVEN_LABS_DEFAULT_VOICE_ID=EXAVITQu4vr4xnSDxMaL # ID голоса по умолчанию TTS_ELEVEN_LABS_DEFAULT_VOICE_ID=EXAVITQu4vr4xnSDxMaL # ID голоса по умолчанию
```
3. В директории `src/bot_aiogram` файл `.env.example` переименовать в `.env` и заполнить переменные окружения.
Пример заполнения переменных окружения:
```
BOT_CONTAINER_NAME=bot_container_name # Название контейнера BOT_CONTAINER_NAME=bot_container_name # Название контейнера
BOT_IMAGE_NAME=botimage_name # Название образа BOT_IMAGE_NAME=botimage_name # Название образа
BOT_NAME=mybotname # Название бота BOT_NAME=mybotname # Название бота

View File

@ -7,25 +7,24 @@ services:
environment: environment:
POSTGRES_USER: ${POSTGRES_USER} POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_NAME} POSTGRES_DB: ${POSTGRES_DB_NAME}
env_file: env_file:
- ./src/assistant/.env - .env
expose: expose:
- "${POSTGRES_PORT}" - "${POSTGRES_PORT}"
volumes: volumes:
- - ./src/assistant/dump.sql:/docker-entrypoint-initdb.d/dump.sql:ro - ./src/assistant/data/dump.sql:/docker-entrypoint-initdb.d/dump.sql:ro
networks: networks:
- backend_network - backend_network
api: api:
build: build:
context: . context: ./src/assistant/
container_name: api container_name: api
image: fastapi_app image: fastapi_app
restart: always restart: always
entrypoint: ["/opt/app/entrypoint.sh"]
env_file: env_file:
- ./src/assistant/.env - .env
expose: expose:
- "${API_PORT}" - "${API_PORT}"
depends_on: depends_on:
@ -52,20 +51,21 @@ services:
image: "${BOT_IMAGE_NAME:-tg_bot-image}" image: "${BOT_IMAGE_NAME:-tg_bot-image}"
container_name: "${BOT_CONTAINER_NAME:-tg_bot-container}" container_name: "${BOT_CONTAINER_NAME:-tg_bot-container}"
build: build:
context: ./src/bot_aiogram/Dockerfile context: ./src/bot_aiogram/
restart: always restart: always
env_file: env_file:
- ./src/bot_aiogram/.env - .env
networks: networks:
- backend_network - backend_network
- api_network - api_network
depends_on: api depends_on:
- api
redis: redis:
image: redis:7.0.11 image: redis:7.0.11
restart: always restart: always
env_file: env_file:
- ./src/bot_aiogram/.env - .env
ports: ports:
- "127.0.0.1:${REDIS_PORT}:${REDIS_PORT}" - "127.0.0.1:${REDIS_PORT}:${REDIS_PORT}"
command: redis-server --bind 0.0.0.0 --appendonly yes command: redis-server --bind 0.0.0.0 --appendonly yes

View File

@ -18,6 +18,11 @@ RUN pip install poetry \
COPY bin /opt/app/bin COPY bin /opt/app/bin
COPY lib /opt/app/lib COPY lib /opt/app/lib
COPY alembic /opt/app/alembic
COPY alembic.ini /opt/app/alembic.ini
COPY entrypoint.sh /opt/app/entrypoint.sh COPY entrypoint.sh /opt/app/entrypoint.sh
RUN chmod +x /opt/app/entrypoint.sh RUN chmod +x /opt/app/entrypoint.sh
ENTRYPOINT ["/opt/app/entrypoint.sh"]

View File

@ -2,7 +2,7 @@ version: "3"
services: services:
postgres: postgres:
image: postgres:15.2 image: ankane/pgvector:v0.5.0
restart: always restart: always
environment: environment:
POSTGRES_USER: ${POSTGRES_USER} POSTGRES_USER: ${POSTGRES_USER}
@ -13,6 +13,7 @@ services:
ports: ports:
- "${POSTGRES_PORT}:${POSTGRES_PORT}" - "${POSTGRES_PORT}:${POSTGRES_PORT}"
volumes: volumes:
- ./dump.sql:/docker-entrypoint-initdb.d/dump.sql:ro
- postgres_data:/var/lib/postgresql/data/ - postgres_data:/var/lib/postgresql/data/
networks: networks:
- backend_network - backend_network
@ -23,7 +24,6 @@ services:
container_name: fastapi_app container_name: fastapi_app
image: fastapi_app image: fastapi_app
restart: always restart: always
entrypoint: ["/opt/app/entrypoint.sh"]
env_file: env_file:
- .env - .env
ports: ports:
@ -48,9 +48,6 @@ services:
networks: networks:
- api_network - api_network
volumes:
postgres_data:
networks: networks:
api_network: api_network:
driver: bridge driver: bridge

View File

@ -23,7 +23,6 @@ services:
container_name: api container_name: api
image: fastapi_app image: fastapi_app
restart: always restart: always
entrypoint: ["/opt/app/entrypoint.sh"]
env_file: env_file:
- .env - .env
expose: expose:

View File

@ -23,7 +23,6 @@ services:
container_name: api container_name: api
image: fastapi_app image: fastapi_app
restart: always restart: always
entrypoint: ["/opt/app/entrypoint.sh"]
env_file: env_file:
- .env - .env
expose: expose:

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
while ! nc -z postgres 5432; do sleep 1; done; while ! nc -z $POSTGRES_HOST $POSTGRES_PORT; do sleep 1; done;
alembic upgrade head poetry run alembic upgrade head
exec .venv/bin/python -m bin exec .venv/bin/python -m bin

View File

@ -7,6 +7,7 @@ import sqlalchemy.ext.asyncio as sa_asyncio
import lib.agent.repositories as repositories import lib.agent.repositories as repositories
import lib.models as models import lib.models as models
import lib.orm_models as orm_models import lib.orm_models as orm_models
import lib.app.settings as app_settings
class OpenAIFunctions: class OpenAIFunctions:
@ -16,10 +17,12 @@ class OpenAIFunctions:
self, self,
repository: repositories.EmbeddingRepository, repository: repositories.EmbeddingRepository,
pg_async_session: sa_asyncio.async_sessionmaker[sa_asyncio.AsyncSession], pg_async_session: sa_asyncio.async_sessionmaker[sa_asyncio.AsyncSession],
settings: app_settings.Settings,
) -> None: ) -> None:
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
self.pg_async_session = pg_async_session self.pg_async_session = pg_async_session
self.repository = repository self.repository = repository
self.settings = settings
async def get_movie_by_description(self, description: str) -> list[models.Movie] | None: 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.""" """Use this function to find data about a movie by movie's description."""
@ -32,7 +35,7 @@ class OpenAIFunctions:
stmt = ( stmt = (
sa.select(orm_models.FilmWork) sa.select(orm_models.FilmWork)
.order_by(orm_models.FilmWork.embeddings.cosine_distance(embedded_description.root)) .order_by(orm_models.FilmWork.embeddings.cosine_distance(embedded_description.root))
.limit(5) .limit(self.settings.agent.embeddings_limit)
) )
response = await session.execute(stmt) response = await session.execute(stmt)
neighbours = response.scalars() neighbours = response.scalars()

View File

@ -47,4 +47,3 @@ class VoiceResponseHandler:
) )
) )
return fastapi.responses.StreamingResponse(io.BytesIO(response.audio_content), media_type="audio/ogg") return fastapi.responses.StreamingResponse(io.BytesIO(response.audio_content), media_type="audio/ogg")
# return fastapi.responses.StreamingResponse(io.BytesIO(voice), media_type="audio/ogg")

View File

@ -97,7 +97,9 @@ class Application:
) )
embedding_repository = agent_repositories.EmbeddingRepository(settings=settings) embedding_repository = agent_repositories.EmbeddingRepository(settings=settings)
agent_tools = agent_functions.OpenAIFunctions( agent_tools = agent_functions.OpenAIFunctions(
repository=embedding_repository, pg_async_session=postgres_client.get_async_session() repository=embedding_repository,
pg_async_session=postgres_client.get_async_session(),
settings=settings
) )
tts_yandex_repository = tts.TTSYandexRepository( tts_yandex_repository = tts.TTSYandexRepository(
tts_settings=app_split_settings.TTSYandexSettings(), tts_settings=app_split_settings.TTSYandexSettings(),

View File

@ -4,6 +4,7 @@ import lib.app.split_settings as app_split_settings
class Settings(pydantic_settings.BaseSettings): class Settings(pydantic_settings.BaseSettings):
agent: app_split_settings.AgentSettings = app_split_settings.AgentSettings()
api: app_split_settings.ApiSettings = app_split_settings.ApiSettings() api: app_split_settings.ApiSettings = app_split_settings.ApiSettings()
app: app_split_settings.AppSettings = app_split_settings.AppSettings() app: app_split_settings.AppSettings = app_split_settings.AppSettings()
postgres: app_split_settings.PostgresSettings = app_split_settings.PostgresSettings() postgres: app_split_settings.PostgresSettings = app_split_settings.PostgresSettings()

View File

@ -1,3 +1,4 @@
from .agent import *
from .api import * from .api import *
from .app import * from .app import *
from .logger import * from .logger import *
@ -9,6 +10,7 @@ from .tts import *
from .voice import * from .voice import *
__all__ = [ __all__ = [
"AgentSettings",
"ApiSettings", "ApiSettings",
"AppSettings", "AppSettings",
"LoggingSettings", "LoggingSettings",

View File

@ -0,0 +1,14 @@
import pydantic_settings
import lib.app.split_settings.utils as app_split_settings_utils
class AgentSettings(pydantic_settings.BaseSettings):
model_config = pydantic_settings.SettingsConfigDict(
env_file=app_split_settings_utils.ENV_PATH,
env_prefix="AGENT_",
env_file_encoding="utf-8",
extra="ignore",
)
embeddings_limit: int = 5

View File

@ -13,7 +13,7 @@ COPY poetry.toml /opt/app/poetry.toml
WORKDIR /opt/app WORKDIR /opt/app
RUN pip install poetry \ RUN pip install poetry \
&& poetry install --no-dev && poetry install --no-dev
COPY bin /opt/app/bin COPY bin /opt/app/bin
@ -21,3 +21,5 @@ COPY lib /opt/app/lib
COPY entrypoint.sh /opt/app/entrypoint.sh COPY entrypoint.sh /opt/app/entrypoint.sh
RUN chmod +x /opt/app/entrypoint.sh RUN chmod +x /opt/app/entrypoint.sh
CMD [".venv/bin/python", "-m", "bin"]

View File

@ -1,5 +1,3 @@
#!/bin/bash #!/bin/bash
while ! nc -z postgres 5432; do sleep 1; done; while ! nc -z postgres 5432; do sleep 1; done;
exec .venv/bin/python -m bin