From 47f5d475e4a25d007af38d18edcfde03573cb8d0 Mon Sep 17 00:00:00 2001 From: Sveinbjorn Thordarson Date: Thu, 24 Oct 2024 19:50:14 +0000 Subject: [PATCH 1/7] Tweaks to pyproject, CI --- .github/workflows/main.yml | 2 +- keys/.gitkeep | 0 pyproject.toml | 8 ++++---- 3 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 keys/.gitkeep diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 41ea216..5b8434b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: - python-version: ["3.9", "3.12", "pypy-3.10"] + python-version: ["3.9", "3.12", "3.13", "pypy-3.10"] steps: - uses: actions/checkout@v4 diff --git a/keys/.gitkeep b/keys/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/pyproject.toml b/pyproject.toml index 56d650c..97c47b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,6 @@ [project] name = "icespeak" -# Versioning is automatic (w/setuptools-scm) -dynamic = ["version"] +version = "0.3.6" description = "Icespeak - Icelandic TTS library" authors = [{ name = "Miðeind ehf.", email = "mideind@mideind.is" }] readme = { file = "README.md", content-type = "text/markdown" } @@ -19,11 +18,12 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Text Processing :: Linguistic", "Topic :: Multimedia :: Sound/Audio :: Speech", "Typing :: Typed", ] -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = [ # "aiohttp[speedups]>=3.8.4", "requests>=2.31.0", @@ -32,7 +32,7 @@ dependencies = [ "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 From ff2f63d8122043a587b93dba77374aee304a424f Mon Sep 17 00:00:00 2001 From: Sveinbjorn Thordarson Date: Fri, 25 Oct 2024 16:02:07 +0000 Subject: [PATCH 2/7] Bumped package dependency versions --- pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 97c47b8..b5e00c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ requires-python = ">=3.10" 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", @@ -36,14 +36,14 @@ dependencies = [ "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] From cc3081f505ea4a98fc3fdc5a9271d39e1f05b37c Mon Sep 17 00:00:00 2001 From: Sveinbjorn Thordarson Date: Fri, 25 Oct 2024 16:26:58 +0000 Subject: [PATCH 3/7] Silenced some typing complaints --- pyproject.toml | 1 + tests/test_tts.py | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b5e00c5..99e340e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,6 +63,7 @@ dev = [ "ruff>=0.5.7", "pre-commit>=3.3.3", "mypy>=1.4.1", + "boto3-stubs>=1.35.48", ] # *** Configuration of tools *** diff --git a/tests/test_tts.py b/tests/test_tts.py index ecf71d1..93838ce 100644 --- a/tests/test_tts.py +++ b/tests/test_tts.py @@ -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 ( @@ -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") @@ -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, From 91b18e8ed0ef80dbc742647dfb86caf9e3358fae Mon Sep 17 00:00:00 2001 From: Sveinbjorn Thordarson Date: Fri, 25 Oct 2024 16:31:46 +0000 Subject: [PATCH 4/7] CI tweak --- .github/workflows/main.yml | 6 +++--- keys/.gitkeep | 0 pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 keys/.gitkeep diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5b8434b..4ae2f8b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: - python-version: ["3.9", "3.12", "3.13", "pypy-3.10"] + python-version: ["3.9", "3.12", "pypy-3.10"] steps: - uses: actions/checkout@v4 @@ -26,7 +26,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip wheel setuptools - pip install -e '.[dev]' + pip install -e '.[dev]' --ignore-requires-python - name: Set up API keys run: | # Azure TTS key @@ -51,7 +51,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip wheel setuptools - pip install -e '.[dev]' + pip install -e '.[dev]' --ignore-requires-python - name: Set up API keys run: | # Azure TTS key diff --git a/keys/.gitkeep b/keys/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/pyproject.toml b/pyproject.toml index 99e340e..8d4be4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ classifiers = [ "Topic :: Multimedia :: Sound/Audio :: Speech", "Typing :: Typed", ] -requires-python = ">=3.10" +requires-python = ">=3.9" dependencies = [ # "aiohttp[speedups]>=3.8.4", "requests>=2.32.3", From 6c1559f84764ad9dc9f281cceff8ca91f8bdcdb4 Mon Sep 17 00:00:00 2001 From: Sveinbjorn Thordarson Date: Tue, 29 Oct 2024 17:35:55 +0000 Subject: [PATCH 5/7] Load keys from environment, with fallback to key files in keys folder if not set in env --- .gitignore | 2 + keys/.gitkeep | 0 src/icespeak/settings.py | 80 +++++++++++++++++++++++----------------- 3 files changed, 49 insertions(+), 33 deletions(-) delete mode 100644 keys/.gitkeep diff --git a/.gitignore b/.gitignore index ee4effd..fdae95a 100644 --- a/.gitignore +++ b/.gitignore @@ -166,3 +166,5 @@ $RECYCLE.BIN/ audio/* keys/* +keys*/ +env.sh diff --git a/keys/.gitkeep b/keys/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/icespeak/settings.py b/src/icespeak/settings.py index 64c4897..88e8bda 100644 --- a/src/icespeak/settings.py +++ b/src/icespeak/settings.py @@ -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, + ) From ff9512a53dba6b79ab7ec539aa5bad520cdd241e Mon Sep 17 00:00:00 2001 From: Sveinbjorn Thordarson Date: Tue, 29 Oct 2024 17:39:39 +0000 Subject: [PATCH 6/7] CI tweak --- .github/workflows/main.yml | 6 +++--- keys/.gitkeep | 0 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 keys/.gitkeep diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4ae2f8b..730b020 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,7 +26,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip wheel setuptools - pip install -e '.[dev]' --ignore-requires-python + python -m pip install -e '.[dev]' - name: Set up API keys run: | # Azure TTS key @@ -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 @@ -51,7 +51,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip wheel setuptools - pip install -e '.[dev]' --ignore-requires-python + pip install -e '.[dev]' - name: Set up API keys run: | # Azure TTS key diff --git a/keys/.gitkeep b/keys/.gitkeep new file mode 100644 index 0000000..e69de29 From d6d5560855005301e87040a79ce9b97e3563fde8 Mon Sep 17 00:00:00 2001 From: Sveinbjorn Thordarson Date: Tue, 29 Oct 2024 17:50:03 +0000 Subject: [PATCH 7/7] Bumped version to 0.3.7, updated docs to reflect that API keys can now be set as env variables --- README.md | 9 +++++++++ pyproject.toml | 3 +-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 97178ee..d9e590f 100644 --- a/README.md +++ b/README.md @@ -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 `/icespeak` diff --git a/pyproject.toml b/pyproject.toml index 8d4be4b..f18c38a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "icespeak" -version = "0.3.6" +version = "0.3.7" description = "Icespeak - Icelandic TTS library" authors = [{ name = "Miðeind ehf.", email = "mideind@mideind.is" }] readme = { file = "README.md", content-type = "text/markdown" } @@ -18,7 +18,6 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", "Topic :: Text Processing :: Linguistic", "Topic :: Multimedia :: Sound/Audio :: Speech", "Typing :: Typed",