mirror of
https://github.com/ijaric/voice_assistant.git
synced 2025-05-24 14:33:26 +00:00
fix: [#28] review fixes
This commit is contained in:
parent
0ef28afa22
commit
48a6f4e167
|
@ -3,16 +3,18 @@ from .token import Token
|
||||||
from .tts import *
|
from .tts import *
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
"AVAILABLE_MODELS_TYPE",
|
||||||
"Base",
|
"Base",
|
||||||
"BaseLanguageCodesEnum",
|
"BaseLanguageCodesEnum",
|
||||||
"BaseVoiceModel",
|
"BaseVoiceModel",
|
||||||
"BaseVoiceModel",
|
|
||||||
"ElevenLabsLanguageCodesEnum",
|
"ElevenLabsLanguageCodesEnum",
|
||||||
"IdCreatedUpdatedBaseMixin",
|
"IdCreatedUpdatedBaseMixin",
|
||||||
"LANGUAGE_CODES_ENUM_TYPE",
|
"LANGUAGE_CODES_ENUM_TYPE",
|
||||||
|
"LIST_VOICE_MODELS_TYPE",
|
||||||
"TTSCreateRequestModel",
|
"TTSCreateRequestModel",
|
||||||
"TTSCreateResponseModel",
|
"TTSCreateResponseModel",
|
||||||
"TTSSearchVoiceRequestModel",
|
"TTSSearchVoiceRequestModel",
|
||||||
"Token",
|
"Token",
|
||||||
|
"VoiceModelProvidersEnum",
|
||||||
"YandexLanguageCodesEnum",
|
"YandexLanguageCodesEnum",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
from .base import *
|
from .models import *
|
||||||
from .languages import *
|
from .voice import *
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
"AVAILABLE_MODELS_TYPE",
|
||||||
"BaseLanguageCodesEnum",
|
"BaseLanguageCodesEnum",
|
||||||
"BaseVoiceModel",
|
"BaseVoiceModel",
|
||||||
"ElevenLabsLanguageCodesEnum",
|
"ElevenLabsLanguageCodesEnum",
|
||||||
"LANGUAGE_CODES_ENUM_TYPE",
|
"LANGUAGE_CODES_ENUM_TYPE",
|
||||||
|
"LIST_VOICE_MODELS_TYPE",
|
||||||
"TTSCreateRequestModel",
|
"TTSCreateRequestModel",
|
||||||
"TTSCreateResponseModel",
|
"TTSCreateResponseModel",
|
||||||
"TTSSearchVoiceRequestModel",
|
"TTSSearchVoiceRequestModel",
|
||||||
|
"VoiceModelProvidersEnum",
|
||||||
"YandexLanguageCodesEnum",
|
"YandexLanguageCodesEnum",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
import typing
|
|
||||||
|
|
||||||
import pydantic
|
import pydantic
|
||||||
|
|
||||||
import lib.models.tts.languages as models_tts_languages
|
import lib.models.tts.voice as models_tts_voice
|
||||||
|
import lib.models.tts.voice.languages as models_tts_languages
|
||||||
|
|
||||||
|
AVAILABLE_MODELS_TYPE = models_tts_voice.YandexVoiceModel | models_tts_voice.ElevenLabsVoiceModel
|
||||||
|
LIST_VOICE_MODELS_TYPE = models_tts_voice.YandexListVoiceModelsModel | models_tts_voice.ElevenLabsListVoiceModelsModel
|
||||||
|
|
||||||
|
|
||||||
class TTSCreateRequestModel(pydantic.BaseModel):
|
class TTSCreateRequestModel(pydantic.BaseModel):
|
||||||
model_config = pydantic.ConfigDict(use_enum_values=True)
|
model_config = pydantic.ConfigDict(use_enum_values=True)
|
||||||
|
|
||||||
voice_model_name: str
|
voice_model: AVAILABLE_MODELS_TYPE
|
||||||
text: str
|
text: str
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,22 +18,6 @@ class TTSCreateResponseModel(pydantic.BaseModel):
|
||||||
audio_content: bytes
|
audio_content: bytes
|
||||||
|
|
||||||
|
|
||||||
class BaseVoiceModel(pydantic.BaseModel):
|
|
||||||
voice_id: str
|
|
||||||
voice_name: str | None = None
|
|
||||||
languages: list[models_tts_languages.LANGUAGE_CODES_ENUM_TYPE]
|
|
||||||
company_name: str
|
|
||||||
|
|
||||||
@pydantic.model_validator(mode="before")
|
|
||||||
@classmethod
|
|
||||||
def check_voice_name_exists(cls, data: typing.Any) -> typing.Any:
|
|
||||||
voice_id = data.get("voice_id")
|
|
||||||
voice_name = data.get("voice_name")
|
|
||||||
if not voice_name and voice_id:
|
|
||||||
data["voice_name"] = voice_id
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
class TTSSearchVoiceRequestModel(pydantic.BaseModel):
|
class TTSSearchVoiceRequestModel(pydantic.BaseModel):
|
||||||
voice_id: str | None = None
|
voice_id: str | None = None
|
||||||
voice_name: str | None = None
|
voice_name: str | None = None
|
17
src/assistant/lib/models/tts/voice/__init__.py
Normal file
17
src/assistant/lib/models/tts/voice/__init__.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
from .base import *
|
||||||
|
from .eleven_labs import *
|
||||||
|
from .languages import *
|
||||||
|
from .yandex import *
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BaseLanguageCodesEnum",
|
||||||
|
"BaseVoiceModel",
|
||||||
|
"ElevenLabsLanguageCodesEnum",
|
||||||
|
"ElevenLabsListVoiceModelsModel",
|
||||||
|
"ElevenLabsVoiceModel",
|
||||||
|
"LANGUAGE_CODES_ENUM_TYPE",
|
||||||
|
"VoiceModelProvidersEnum",
|
||||||
|
"YandexLanguageCodesEnum",
|
||||||
|
"YandexListVoiceModelsModel",
|
||||||
|
"YandexVoiceModel",
|
||||||
|
]
|
27
src/assistant/lib/models/tts/voice/base.py
Normal file
27
src/assistant/lib/models/tts/voice/base.py
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import enum
|
||||||
|
import typing
|
||||||
|
|
||||||
|
import pydantic
|
||||||
|
|
||||||
|
import lib.models.tts.voice.languages as models_tts_languages
|
||||||
|
|
||||||
|
|
||||||
|
class VoiceModelProvidersEnum(enum.Enum):
|
||||||
|
YANDEX = "yandex"
|
||||||
|
ELEVEN_LABS = "eleven_labs"
|
||||||
|
|
||||||
|
|
||||||
|
class BaseVoiceModel(pydantic.BaseModel):
|
||||||
|
voice_id: str
|
||||||
|
voice_name: str | None = None
|
||||||
|
languages: list[models_tts_languages.LANGUAGE_CODES_ENUM_TYPE]
|
||||||
|
provider: VoiceModelProvidersEnum
|
||||||
|
|
||||||
|
@pydantic.model_validator(mode="before")
|
||||||
|
@classmethod
|
||||||
|
def check_voice_name_exists(cls, data: typing.Any) -> typing.Any:
|
||||||
|
voice_id = data.get("voice_id")
|
||||||
|
voice_name = data.get("voice_name")
|
||||||
|
if not voice_name and voice_id:
|
||||||
|
data["voice_name"] = voice_id
|
||||||
|
return data
|
75
src/assistant/lib/models/tts/voice/eleven_labs.py
Normal file
75
src/assistant/lib/models/tts/voice/eleven_labs.py
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
|
import pydantic
|
||||||
|
|
||||||
|
import lib.models.tts.voice.base as models_tts_base
|
||||||
|
import lib.models.tts.voice.languages as models_tts_languages
|
||||||
|
|
||||||
|
|
||||||
|
class ElevenLabsVoiceModel(models_tts_base.BaseVoiceModel):
|
||||||
|
model_config = pydantic.ConfigDict(use_enum_values=True)
|
||||||
|
voice_id: str
|
||||||
|
voice_name: str | None = None
|
||||||
|
languages: list[models_tts_languages.LANGUAGE_CODES_ENUM_TYPE]
|
||||||
|
provider: models_tts_base.VoiceModelProvidersEnum = models_tts_base.VoiceModelProvidersEnum.ELEVEN_LABS
|
||||||
|
|
||||||
|
|
||||||
|
class ElevenLabsListVoiceModelsModel(pydantic.BaseModel):
|
||||||
|
models: list[ElevenLabsVoiceModel] = [
|
||||||
|
ElevenLabsVoiceModel(
|
||||||
|
voice_id="eleven_multilingual_v1",
|
||||||
|
languages=[
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.ENGLISH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.GERMAN,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.POLISH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.SPANISH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.ITALIAN,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.FRENCH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.PORTUGUESE,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.HINDI,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.ARABIC,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ElevenLabsVoiceModel(
|
||||||
|
voice_id="eleven_multilingual_v2",
|
||||||
|
languages=[
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.ENGLISH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.JAPANESE,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.CHINESE,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.GERMAN,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.HINDI,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.FRENCH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.KOREAN,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.PORTUGUESE,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.ITALIAN,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.SPANISH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.INDONESIAN,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.DUTCH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.TURKISH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.FILIPINO,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.POLISH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.SWEDISH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.BULGARIAN,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.ROMANIAN,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.ARABIC,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.CZECH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.GREEK,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.FINNISH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.CROATIAN,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.MALAY,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.SLOVAK,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.DANISH,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.TAMIL,
|
||||||
|
models_tts_languages.ElevenLabsLanguageCodesEnum.UKRAINIAN,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ElevenLabsVoiceModel(
|
||||||
|
voice_id="eleven_multilingual_v2",
|
||||||
|
languages=[models_tts_languages.ElevenLabsLanguageCodesEnum.ENGLISH],
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_api(cls, voice_models_from_api: list[dict[str, typing.Any]]) -> typing.Self:
|
||||||
|
voice_models = [ElevenLabsVoiceModel.model_validate(voice_model) for voice_model in voice_models_from_api]
|
||||||
|
return ElevenLabsListVoiceModelsModel(models=voice_models)
|
97
src/assistant/lib/models/tts/voice/yandex.py
Normal file
97
src/assistant/lib/models/tts/voice/yandex.py
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
|
import pydantic
|
||||||
|
|
||||||
|
import lib.models.tts.voice.base as models_tts_base
|
||||||
|
import lib.models.tts.voice.languages as models_tts_languages
|
||||||
|
|
||||||
|
|
||||||
|
class YandexVoiceModel(models_tts_base.BaseVoiceModel):
|
||||||
|
voice_id: str
|
||||||
|
voice_name: str | None = None
|
||||||
|
languages: list[models_tts_languages.LANGUAGE_CODES_ENUM_TYPE]
|
||||||
|
provider: models_tts_base.VoiceModelProvidersEnum = models_tts_base.VoiceModelProvidersEnum.YANDEX
|
||||||
|
role: str | None = None
|
||||||
|
|
||||||
|
@pydantic.model_validator(mode="before")
|
||||||
|
@classmethod
|
||||||
|
def check_voice_name_exists(cls, data: typing.Any) -> typing.Any:
|
||||||
|
voice_id = data.get("voice_id")
|
||||||
|
voice_name = data.get("voice_name")
|
||||||
|
role = data.get("role")
|
||||||
|
if not voice_name and voice_id:
|
||||||
|
data["voice_name"] = f"{voice_id} {role}" if role else voice_id
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class YandexListVoiceModelsModel(pydantic.BaseModel):
|
||||||
|
models: list[YandexVoiceModel] = [
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="ermil", role="neutral", languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="ermil", role="good", languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="alena", role="neutral", languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="alena", role="good", languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="jane", role="neutral", languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="jane", role="good", languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="jane", role="evil", languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="omazh", role="neutral", languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="omazh", role="evil", languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="zahar", role="neutral", languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="zahar", role="good", languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="filipp", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="madirus", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(voice_id="dasha", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]),
|
||||||
|
YandexVoiceModel(voice_id="julia", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]),
|
||||||
|
YandexVoiceModel(voice_id="lera", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="marina", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="alexander", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="kirill", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(voice_id="anton", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.RUSSIAN]),
|
||||||
|
YandexVoiceModel(voice_id="john", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.ENGLISH]),
|
||||||
|
YandexVoiceModel(voice_id="amira", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.KAZAKH]),
|
||||||
|
YandexVoiceModel(voice_id="madi", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.KAZAKH]),
|
||||||
|
YandexVoiceModel(voice_id="lea", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.GERMAN]),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="naomi", role="modern", languages=[models_tts_languages.YandexLanguageCodesEnum.HEBREW]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(
|
||||||
|
voice_id="naomi", role="classic", languages=[models_tts_languages.YandexLanguageCodesEnum.HEBREW]
|
||||||
|
),
|
||||||
|
YandexVoiceModel(voice_id="nigora", role=None, languages=[models_tts_languages.YandexLanguageCodesEnum.UZBEK]),
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_api(cls, voice_models_from_api: list[dict[str, typing.Any]]) -> typing.Self:
|
||||||
|
voice_models = [YandexVoiceModel.model_validate(voice_model) for voice_model in voice_models_from_api]
|
||||||
|
return YandexListVoiceModelsModel(models=voice_models)
|
|
@ -1,17 +1,5 @@
|
||||||
from .repository import *
|
from .protocols import *
|
||||||
from .service import *
|
|
||||||
from .utils import *
|
|
||||||
from .voice import *
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"ElevenLabsListVoiceModelsModel",
|
|
||||||
"ElevenLabsVoiceModel",
|
|
||||||
"LIST_VOICE_MODELS_TYPE",
|
|
||||||
"LIST_VOICE_MODELS_TYPE",
|
|
||||||
"TTSCreateRequestServiceModel",
|
|
||||||
"TTSCreateResponseServiceModel",
|
|
||||||
"TTSRepositoryProtocol",
|
"TTSRepositoryProtocol",
|
||||||
"VOICE_MODELS_TYPE",
|
|
||||||
"YandexListVoiceModelsModel",
|
|
||||||
"YandexVoiceModel",
|
|
||||||
]
|
]
|
||||||
|
|
14
src/assistant/lib/tts/models/protocols.py
Normal file
14
src/assistant/lib/tts/models/protocols.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
|
import lib.models as models
|
||||||
|
|
||||||
|
|
||||||
|
class TTSRepositoryProtocol(typing.Protocol):
|
||||||
|
def get_audio_as_bytes(self, request: models.TTSCreateRequestModel) -> models.TTSCreateResponseModel:
|
||||||
|
...
|
||||||
|
|
||||||
|
def get_voice_model_by_name(self, voice_model_name: str) -> models.BaseVoiceModel | None:
|
||||||
|
...
|
||||||
|
|
||||||
|
def get_voice_models_by_fields(self, fields: models.TTSSearchVoiceRequestModel) -> models.LIST_VOICE_MODELS_TYPE:
|
||||||
|
...
|
|
@ -1,17 +0,0 @@
|
||||||
import typing
|
|
||||||
|
|
||||||
import lib.models as models
|
|
||||||
import lib.tts.models.utils as tts_models_utils
|
|
||||||
|
|
||||||
|
|
||||||
class TTSRepositoryProtocol(typing.Protocol):
|
|
||||||
def get_audio_as_bytes_from_text(self, text: str) -> models.TTSCreateResponseModel:
|
|
||||||
...
|
|
||||||
|
|
||||||
def get_voice_model_by_name(self, voice_model_name: str) -> models.BaseVoiceModel | None:
|
|
||||||
...
|
|
||||||
|
|
||||||
def get_voice_models_by_fields(
|
|
||||||
self, fields: models.TTSSearchVoiceRequestModel
|
|
||||||
) -> tts_models_utils.LIST_VOICE_MODELS_TYPE:
|
|
||||||
...
|
|
|
@ -1,9 +0,0 @@
|
||||||
import lib.models as models
|
|
||||||
|
|
||||||
|
|
||||||
class TTSCreateRequestServiceModel(models.TTSCreateRequestModel):
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class TTSCreateResponseServiceModel(models.TTSCreateResponseModel):
|
|
||||||
...
|
|
|
@ -1,4 +0,0 @@
|
||||||
import lib.tts.models.voice as tts_models_voice
|
|
||||||
|
|
||||||
VOICE_MODELS_TYPE = tts_models_voice.YandexVoiceModel | tts_models_voice.ElevenLabsVoiceModel
|
|
||||||
LIST_VOICE_MODELS_TYPE = tts_models_voice.YandexListVoiceModelsModel | tts_models_voice.ElevenLabsListVoiceModelsModel
|
|
|
@ -1,9 +0,0 @@
|
||||||
from .eleven_labs import *
|
|
||||||
from .yandex import *
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"ElevenLabsListVoiceModelsModel",
|
|
||||||
"ElevenLabsVoiceModel",
|
|
||||||
"YandexListVoiceModelsModel",
|
|
||||||
"YandexVoiceModel",
|
|
||||||
]
|
|
|
@ -1,73 +0,0 @@
|
||||||
import typing
|
|
||||||
|
|
||||||
import pydantic
|
|
||||||
|
|
||||||
import lib.models as models
|
|
||||||
|
|
||||||
|
|
||||||
class ElevenLabsVoiceModel(models.BaseVoiceModel):
|
|
||||||
voice_id: str
|
|
||||||
voice_name: str | None = None
|
|
||||||
languages: list[models.LANGUAGE_CODES_ENUM_TYPE]
|
|
||||||
company_name: str = "eleven labs"
|
|
||||||
|
|
||||||
|
|
||||||
class ElevenLabsListVoiceModelsModel(pydantic.BaseModel):
|
|
||||||
models: list[ElevenLabsVoiceModel] = [
|
|
||||||
ElevenLabsVoiceModel(
|
|
||||||
voice_id="eleven_multilingual_v1",
|
|
||||||
languages=[
|
|
||||||
models.ElevenLabsLanguageCodesEnum.ENGLISH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.GERMAN,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.POLISH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.SPANISH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.ITALIAN,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.FRENCH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.PORTUGUESE,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.HINDI,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.ARABIC,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
ElevenLabsVoiceModel(
|
|
||||||
voice_id="eleven_multilingual_v2",
|
|
||||||
languages=[
|
|
||||||
models.ElevenLabsLanguageCodesEnum.ENGLISH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.JAPANESE,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.CHINESE,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.GERMAN,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.HINDI,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.FRENCH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.KOREAN,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.PORTUGUESE,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.ITALIAN,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.SPANISH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.INDONESIAN,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.DUTCH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.TURKISH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.FILIPINO,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.POLISH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.SWEDISH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.BULGARIAN,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.ROMANIAN,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.ARABIC,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.CZECH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.GREEK,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.FINNISH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.CROATIAN,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.MALAY,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.SLOVAK,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.DANISH,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.TAMIL,
|
|
||||||
models.ElevenLabsLanguageCodesEnum.UKRAINIAN,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
ElevenLabsVoiceModel(
|
|
||||||
voice_id="eleven_multilingual_v2",
|
|
||||||
languages=[models.ElevenLabsLanguageCodesEnum.ENGLISH],
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_api(cls, voice_models_from_api: list[dict[str, typing.Any]]) -> typing.Self:
|
|
||||||
voice_models = [ElevenLabsVoiceModel.model_validate(voice_model) for voice_model in voice_models_from_api]
|
|
||||||
return ElevenLabsListVoiceModelsModel(models=voice_models)
|
|
|
@ -1,60 +0,0 @@
|
||||||
import typing
|
|
||||||
|
|
||||||
import pydantic
|
|
||||||
|
|
||||||
import lib.models as models
|
|
||||||
|
|
||||||
|
|
||||||
class YandexVoiceModel(models.BaseVoiceModel):
|
|
||||||
voice_id: str
|
|
||||||
voice_name: str | None = None
|
|
||||||
languages: list[models.LANGUAGE_CODES_ENUM_TYPE]
|
|
||||||
company_name: str = "yandex"
|
|
||||||
role: str | None = None
|
|
||||||
|
|
||||||
@pydantic.model_validator(mode="before")
|
|
||||||
@classmethod
|
|
||||||
def check_voice_name_exists(cls, data: typing.Any) -> typing.Any:
|
|
||||||
voice_id = data.get("voice_id")
|
|
||||||
voice_name = data.get("voice_name")
|
|
||||||
role = data.get("role")
|
|
||||||
if not voice_name and voice_id:
|
|
||||||
data["voice_name"] = f"{voice_id} {role}" if role else voice_id
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
class YandexListVoiceModelsModel(pydantic.BaseModel):
|
|
||||||
models: list[YandexVoiceModel] = [
|
|
||||||
YandexVoiceModel(voice_id="ermil", role="neutral", languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="ermil", role="good", languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="alena", role="neutral", languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="alena", role="good", languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="jane", role="neutral", languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="jane", role="good", languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="jane", role="evil", languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="omazh", role="neutral", languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="omazh", role="evil", languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="zahar", role="neutral", languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="zahar", role="good", languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="filipp", role=None, languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="madirus", role=None, languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="dasha", role=None, languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="julia", role=None, languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="lera", role=None, languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="marina", role=None, languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="alexander", role=None, languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="kirill", role=None, languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="anton", role=None, languages=[models.YandexLanguageCodesEnum.RUSSIAN]),
|
|
||||||
YandexVoiceModel(voice_id="john", role=None, languages=[models.YandexLanguageCodesEnum.ENGLISH]),
|
|
||||||
YandexVoiceModel(voice_id="amira", role=None, languages=[models.YandexLanguageCodesEnum.KAZAKH]),
|
|
||||||
YandexVoiceModel(voice_id="madi", role=None, languages=[models.YandexLanguageCodesEnum.KAZAKH]),
|
|
||||||
YandexVoiceModel(voice_id="lea", role=None, languages=[models.YandexLanguageCodesEnum.GERMAN]),
|
|
||||||
YandexVoiceModel(voice_id="naomi", role="modern", languages=[models.YandexLanguageCodesEnum.HEBREW]),
|
|
||||||
YandexVoiceModel(voice_id="naomi", role="classic", languages=[models.YandexLanguageCodesEnum.HEBREW]),
|
|
||||||
YandexVoiceModel(voice_id="nigora", role=None, languages=[models.YandexLanguageCodesEnum.UZBEK]),
|
|
||||||
]
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_api(cls, voice_models_from_api: list[dict[str, typing.Any]]) -> typing.Self:
|
|
||||||
voice_models = [YandexVoiceModel.model_validate(voice_model) for voice_model in voice_models_from_api]
|
|
||||||
return YandexListVoiceModelsModel(models=voice_models)
|
|
|
@ -1,7 +1,6 @@
|
||||||
import abc
|
import abc
|
||||||
|
|
||||||
import lib.models as models
|
import lib.models as models
|
||||||
import lib.tts.models as tts_models
|
|
||||||
|
|
||||||
|
|
||||||
class HttpClient: # Mocked class todo remove and use real http client from lib.clients.http_client
|
class HttpClient: # Mocked class todo remove and use real http client from lib.clients.http_client
|
||||||
|
@ -15,11 +14,11 @@ class TTSBaseRepository(abc.ABC):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def voice_models(self) -> tts_models.LIST_VOICE_MODELS_TYPE:
|
def voice_models(self) -> models.LIST_VOICE_MODELS_TYPE:
|
||||||
...
|
...
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def get_audio_as_bytes_from_text(self, text: str) -> models.TTSCreateResponseModel:
|
def get_audio_as_bytes(self, request: models.TTSCreateRequestModel) -> models.TTSCreateResponseModel:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def get_voice_model_by_name(self, voice_model_name: str) -> models.BaseVoiceModel | None:
|
def get_voice_model_by_name(self, voice_model_name: str) -> models.BaseVoiceModel | None:
|
||||||
|
@ -34,7 +33,7 @@ class TTSBaseRepository(abc.ABC):
|
||||||
|
|
||||||
def get_list_voice_models_by_fields(
|
def get_list_voice_models_by_fields(
|
||||||
self, fields: models.TTSSearchVoiceRequestModel
|
self, fields: models.TTSSearchVoiceRequestModel
|
||||||
) -> list[tts_models.VOICE_MODELS_TYPE]:
|
) -> list[models.AVAILABLE_MODELS_TYPE]:
|
||||||
"""
|
"""
|
||||||
Search voice model by fields
|
Search voice model by fields
|
||||||
:param fields: Any fields from TTSSearchVoiceRequestModel
|
:param fields: Any fields from TTSSearchVoiceRequestModel
|
||||||
|
@ -43,7 +42,6 @@ class TTSBaseRepository(abc.ABC):
|
||||||
fields_dump = fields.model_dump(exclude_none=True)
|
fields_dump = fields.model_dump(exclude_none=True)
|
||||||
voice_models_response = []
|
voice_models_response = []
|
||||||
for voice_model in self.voice_models.models:
|
for voice_model in self.voice_models.models:
|
||||||
voice_model: tts_models.VOICE_MODELS_TYPE
|
|
||||||
for field, field_value in fields_dump.items():
|
for field, field_value in fields_dump.items():
|
||||||
if field == "languages": # language is a list
|
if field == "languages": # language is a list
|
||||||
language_names: set[str] = {item.name for item in field_value}
|
language_names: set[str] = {item.name for item in field_value}
|
||||||
|
|
|
@ -7,32 +7,28 @@ class TTSService:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
settings: app_settings.Settings,
|
settings: app_settings.Settings,
|
||||||
tts_repositories: list[tts_models.TTSRepositoryProtocol],
|
repositories: dict[models.VoiceModelProvidersEnum, tts_models.TTSRepositoryProtocol],
|
||||||
):
|
):
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.tts_repositories = tts_repositories
|
self.repositories = repositories
|
||||||
|
|
||||||
def get_audio_as_bytes_from_text(self, tts_request: models.TTSCreateRequestModel) -> models.TTSCreateResponseModel:
|
def get_audio_as_bytes(self, request: models.TTSCreateRequestModel) -> models.TTSCreateResponseModel:
|
||||||
for repository in self.tts_repositories:
|
model = request.voice_model
|
||||||
voice_model = repository.get_voice_model_by_name(tts_request.voice_model_name)
|
repository = self.repositories[model.provider]
|
||||||
if voice_model:
|
audio_response = repository.get_audio_as_bytes(request)
|
||||||
audio_response = repository.get_audio_as_bytes_from_text(tts_request.text)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Voice model {tts_request.voice_model_name} not found")
|
|
||||||
return audio_response
|
return audio_response
|
||||||
|
|
||||||
def get_voice_model_by_name(self, voice_model_name: str) -> models.BaseVoiceModel | None:
|
def get_voice_model_by_name(self, voice_model_name: str) -> models.BaseVoiceModel | None:
|
||||||
for repository in self.tts_repositories:
|
for repository in self.repositories.values():
|
||||||
voice_model = repository.get_voice_model_by_name(voice_model_name)
|
voice_model = repository.get_voice_model_by_name(voice_model_name)
|
||||||
if voice_model:
|
if voice_model:
|
||||||
return voice_model
|
return voice_model
|
||||||
|
|
||||||
def get_list_voice_models_by_fields(
|
def get_list_voice_models_by_fields(
|
||||||
self, fields: models.TTSSearchVoiceRequestModel
|
self, fields: models.TTSSearchVoiceRequestModel
|
||||||
) -> list[tts_models.VOICE_MODELS_TYPE]:
|
) -> list[models.AVAILABLE_MODELS_TYPE]:
|
||||||
response_models: list[tts_models.VOICE_MODELS_TYPE] = []
|
response_models: list[models.AVAILABLE_MODELS_TYPE] = []
|
||||||
for repository in self.tts_repositories:
|
for repository in self.repositories.values():
|
||||||
voice_models = repository.get_voice_models_by_fields(fields)
|
voice_models = repository.get_voice_models_by_fields(fields)
|
||||||
if voice_models.models:
|
if voice_models.models:
|
||||||
response_models.extend(voice_models.models)
|
response_models.extend(voice_models.models)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user