Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable override on API keys for external services #7

Merged
merged 12 commits into from
Mar 12, 2024
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
icespeak-venv
4 changes: 2 additions & 2 deletions src/icespeak/voices/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

from pydantic import BaseModel, Field

from icespeak.settings import MAX_SPEED, MIN_SPEED, SETTINGS, TextFormats
from icespeak.settings import Keys, MAX_SPEED, MIN_SPEED, SETTINGS, TextFormats
from icespeak.transcribe import DefaultTranscriber

if TYPE_CHECKING:
Expand Down Expand Up @@ -125,5 +125,5 @@ def load_api_keys(self) -> None:
raise NotImplementedError

@abstractmethod
def text_to_speech(self, text: str, options: TTSOptions) -> Path:
def text_to_speech(self, text: str, options: TTSOptions, keys_override: Keys | None = None) -> Path:
raise NotImplementedError
20 changes: 17 additions & 3 deletions src/icespeak/voices/aws_polly.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

import boto3

from icespeak.settings import API_KEYS, SETTINGS
from icespeak.settings import API_KEYS, Keys, SETTINGS

from . import BaseVoice, ModuleAudioFormatsT, ModuleVoicesT, TTSOptions

Expand All @@ -47,6 +47,14 @@ class AWSPollyVoice(BaseVoice):

_lock = Lock()

def _create_client(self, aws_key: AWSPollyKey) -> boto3.client:
return boto3.client(
"polly",
region_name=aws_key.region_name.get_secret_value(),
aws_access_key_id=aws_key.aws_access_key_id.get_secret_value(),
aws_secret_access_key=aws_key.aws_secret_access_key.get_secret_value(),
)

@property
@override
def name(self):
Expand Down Expand Up @@ -78,7 +86,13 @@ def load_api_keys(self):
)

@override
def text_to_speech(self, text: str, options: TTSOptions):
def text_to_speech(self, text: str, options: TTSOptions, keys_override: Keys | None = None):
if keys_override and keys_override.aws:
_LOG.info(f"Using overridden AWS keys")
client = self._create_client(keys_override.aws)
else:
_LOG.info(f"Using default AWS keys")
client = self._aws_client
# Special preprocessing for SSML markup
if options.text_format == "ssml":
# Adjust voice speed as appropriate
Expand All @@ -99,7 +113,7 @@ def text_to_speech(self, text: str, options: TTSOptions):
"OutputFormat": options.audio_format,
}
_LOG.debug("Synthesizing with AWS Polly: %s", aws_args)
response: dict[str, Any] = self._aws_client.synthesize_speech(**aws_args)
response: dict[str, Any] = client.synthesize_speech(**aws_args)
except Exception:
_LOG.exception("Error synthesizing speech.")
raise
Expand Down
16 changes: 11 additions & 5 deletions src/icespeak/voices/azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

import azure.cognitiveservices.speech as speechsdk

from icespeak.settings import API_KEYS, SETTINGS
from icespeak.settings import API_KEYS, Keys, SETTINGS
from icespeak.transcribe import DefaultTranscriber, strip_markup

from . import BaseVoice, ModuleAudioFormatsT, ModuleVoicesT, TTSOptions
Expand Down Expand Up @@ -179,10 +179,16 @@ def load_api_keys(self):
AzureVoice.AZURE_REGION = API_KEYS.azure.region.get_secret_value()

@override
def text_to_speech(self, text: str, options: TTSOptions):
speech_conf = speechsdk.SpeechConfig(
subscription=AzureVoice.AZURE_KEY, region=AzureVoice.AZURE_REGION
)
def text_to_speech(self, text: str, options: TTSOptions, keys_override: Keys | None = None):
if keys_override and keys_override.azure:
_LOG.info(f"Using overridden Azure keys")
subscription = keys_override.azure.key
region = keys_override.azure.region
else:
_LOG.info(f"Using default Azure keys")
subscription = API_KEYS.azure.key
region = API_KEYS.azure.region
speech_conf = speechsdk.SpeechConfig(subscription=subscription, region=region)

azure_voice_id = AzureVoice._VOICES[options.voice]["id"]
speech_conf.speech_synthesis_voice_name = azure_voice_id
Expand Down
4 changes: 2 additions & 2 deletions src/icespeak/voices/tiro.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

import requests

from icespeak.settings import SETTINGS
from icespeak.settings import Keys, SETTINGS
from icespeak.transcribe import strip_markup

from . import BaseVoice, ModuleAudioFormatsT, ModuleVoicesT, TTSOptions
Expand Down Expand Up @@ -70,7 +70,7 @@ def load_api_keys(self):
pass

@override
def text_to_speech(self, text: str, options: TTSOptions):
def text_to_speech(self, text: str, options: TTSOptions, keys_override: Keys | None = None):
# TODO: Tiro's API supports a subset of SSML tags
# See https://tts.tiro.is/#tag/speech/paths/~1v0~1speech/post

Expand Down
Loading