Skip to content

Commit

Permalink
Merge pull request #14 from mideind/keys_from_env
Browse files Browse the repository at this point in the history
Keys from env
  • Loading branch information
sveinbjornt authored Oct 29, 2024
2 parents 3eb20b6 + d6d5560 commit 31760f4
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 47 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip wheel setuptools
pip install -e '.[dev]'
python -m pip install -e '.[dev]'
- name: Set up API keys
run: |
# Azure TTS key
Expand All @@ -35,7 +35,7 @@ jobs:
echo '${{ secrets.AWS_POLLY_KEY }}' > keys/AWSPollyServerKey.json
- name: Test with pytest
run: |
pytest --run-slow -vvvrP --log-level=DEBUG --capture=tee-sys
python -m pytest --run-slow -vvvrP --log-level=DEBUG --capture=tee-sys
# - name: Lint with pre-commit hooks
# run: |
# pre-commit run --all-files
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,5 @@ $RECYCLE.BIN/

audio/*
keys/*
keys*/
env.sh
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ python3 -m pip install -e '.[dev]'
Before using, place API keys for the relevant services in the `/keys` folder
(or a folder specified by the `ICESPEAK_KEYS_DIR` environment variable).

Alternately, you can set the following environment variables:

```sh
export ICESPEAK_AWSPOLLY_API_KEY=your-aws-polly-api-key
export ICESPEAK_AZURE_API_KEY=your-azure-api-key
export ICESPEAK_GOOGLE_API_KEY=your-google-api-key
export ICESPEAK_OPENAI_API_KEY=your-openai-api-key
```

Output audio files are saved to the directory specified
by the `ICESPEAK_AUDIO_DIR` environment variable.
By default Icespeak creates the directory `<TEMP DIR>/icespeak`
Expand Down
14 changes: 7 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[project]
name = "icespeak"
# Versioning is automatic (w/setuptools-scm)
dynamic = ["version"]
version = "0.3.7"
description = "Icespeak - Icelandic TTS library"
authors = [{ name = "Miðeind ehf.", email = "[email protected]" }]
readme = { file = "README.md", content-type = "text/markdown" }
Expand All @@ -26,24 +25,24 @@ classifiers = [
requires-python = ">=3.9"
dependencies = [
# "aiohttp[speedups]>=3.8.4",
"requests>=2.31.0",
"typing-extensions>=4.7.1",
"requests>=2.32.3",
"typing-extensions>=4.12.2",
"pydantic==2.3.0",
"pydantic-settings>=2.0.3",
"cachetools>=5.5.0",
# For parsing Icelandic text
"islenska==1.0.3",
"islenska<2.0.0",
"reynir<4.0.0",
"tokenizer<4.0.0",
# Azure TTS
"azure-cognitiveservices-speech>=1.38.0",
"azure-cognitiveservices-speech>=1.41.1",
# Google TTS
#"google-cloud-texttospeech>=2.14.0",
# AWS Polly TTS
"botocore>=1.21.40",
"boto3>=1.18.40",
# OpenAI TTS
"openai>=1.44",
"openai>=1.52.2",
]

[project.urls]
Expand All @@ -63,6 +62,7 @@ dev = [
"ruff>=0.5.7",
"pre-commit>=3.3.3",
"mypy>=1.4.1",
"boto3-stubs>=1.35.48",
]

# *** Configuration of tools ***
Expand Down
80 changes: 47 additions & 33 deletions src/icespeak/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,47 +217,61 @@ def __eq__(self, other: object):
_kd = SETTINGS.KEYS_DIR
if not (_kd.exists() and _kd.is_dir()):
_LOG.warning(
"Keys directory missing or incorrect, TTS will not work! Set to: %s", _kd
"Keys directory missing or incorrect: %s", _kd
)
else:
# Load API keys, logging exceptions in level DEBUG so they aren't logged twice,
# as exceptions are logged as warnings when voice modules are initialized
try:

# Load API keys, logging exceptions in level DEBUG so they aren't logged twice,
# as exceptions are logged as warnings when voice modules are initialized

# Amazon Polly
try:
if key := os.getenv("ICESPEAK_AWSPOLLY_API_KEY"):
API_KEYS.aws = AWSPollyKey.model_validate_json(key)
else:
API_KEYS.aws = AWSPollyKey.model_validate_json(
(_kd / SETTINGS.AWSPOLLY_KEY_FILENAME).read_text().strip()
)
except Exception as err:
_LOG.debug(
"Could not load AWS Polly API key, ASR with AWS Polly will not work. Error: %s",
err,
)
try:
except Exception as err:
_LOG.debug(
"Could not load AWS Polly API key, ASR with AWS Polly will not work. Error: %s",
err,
)
# Azure
try:
if key := os.getenv("ICESPEAK_AZURE_API_KEY"):
API_KEYS.azure = AzureKey.model_validate_json(key)
else:
API_KEYS.azure = AzureKey.model_validate_json(
(_kd / SETTINGS.AZURE_KEY_FILENAME).read_text().strip()
)
except Exception as err:
_LOG.debug(
"Could not load Azure API key, ASR with Azure will not work. Error: %s", err
)
try:
except Exception as err:
_LOG.debug(
"Could not load Azure API key, ASR with Azure will not work. Error: %s", err
)
# Google
try:
if key := os.getenv("ICESPEAK_GOOGLE_API_KEY"):
API_KEYS.google = json.loads(key)
else:
API_KEYS.google = json.loads(
(_kd / SETTINGS.GOOGLE_KEY_FILENAME).read_text().strip()
)
except Exception as err:
_LOG.debug(
"Could not load Google API key, ASR with Google will not work. Error: %s",
err,
)
try:
# First try to load the key from environment variable OPENAI_API_KEY
if key := os.getenv("OPENAI_API_KEY"):
API_KEYS.openai = OpenAIKey(api_key=SecretStr(key))
else:
API_KEYS.openai = OpenAIKey.model_validate_json(
(_kd / SETTINGS.OPENAI_KEY_FILENAME).read_text().strip()
)
except Exception as err:
_LOG.debug(
"Could not load OpenAI API key, ASR with OpenAI will not work. Error: %s",
err,
except Exception as err:
_LOG.debug(
"Could not load Google API key, ASR with Google will not work. Error: %s",
err,
)
# OpenAI
try:
# First try to load the key from environment variable OPENAI_API_KEY
if key := os.getenv("ICESPEAK_OPENAI_API_KEY"):
API_KEYS.openai = OpenAIKey(api_key=SecretStr(key))
else:
API_KEYS.openai = OpenAIKey.model_validate_json(
(_kd / SETTINGS.OPENAI_KEY_FILENAME).read_text().strip()
)
except Exception as err:
_LOG.debug(
"Could not load OpenAI API key, ASR with OpenAI will not work. Error: %s",
err,
)
11 changes: 6 additions & 5 deletions tests/test_tts.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from unittest.mock import MagicMock, patch

import pytest
from pydantic import SecretStr

from icespeak import TTSOptions, tts_to_file
from icespeak.settings import (
Expand Down Expand Up @@ -144,12 +145,12 @@ def test_OpenAI_speech_synthesis():
def test_keys_override_in_tts_to_file():
"""Test if keys_override is correctly passed into service.text_to_speech."""
_TEXT = "Test"
SERVICES["mock_service"].audio_formats = ["mp3"]
SERVICES["mock_service"].audio_formats = ["mp3"] # type: ignore
keys_override = Keys(
aws=AWSPollyKey(
aws_access_key_id="test",
aws_secret_access_key="test",
region_name="test",
aws_access_key_id=SecretStr("test"),
aws_secret_access_key=SecretStr("test"),
region_name=SecretStr("test"),
)
)
opts = TTSOptions(text_format=TextFormats.TEXT, audio_format="mp3", voice="Dora")
Expand All @@ -159,7 +160,7 @@ def test_keys_override_in_tts_to_file():
transcribe=False,
keys_override=keys_override,
)
SERVICES["mock_service"].text_to_speech.assert_called_once_with(
SERVICES["mock_service"].text_to_speech.assert_called_once_with( # type: ignore
_TEXT,
opts,
keys_override,
Expand Down

0 comments on commit 31760f4

Please sign in to comment.