From 8f8a3342038a283917c39af11435adb729f4ce42 Mon Sep 17 00:00:00 2001 From: rany2 Date: Sat, 12 Aug 2023 17:25:46 +0300 Subject: [PATCH] Fix "unable to get local issuer certificate" when trust store is not available from OS Closes #129 Signed-off-by: rany2 --- setup.py | 1 + src/edge_tts/communicate.py | 6 +++++- src/edge_tts/list_voices.py | 4 ++++ src/edge_tts/version.py | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index b5472af..7b2b0f2 100644 --- a/setup.py +++ b/setup.py @@ -5,5 +5,6 @@ name="edge-tts", install_requires=[ "aiohttp>=3.8.0", + "certifi==2023.07.22", ], ) diff --git a/src/edge_tts/communicate.py b/src/edge_tts/communicate.py index 595e7e9..0a994da 100644 --- a/src/edge_tts/communicate.py +++ b/src/edge_tts/communicate.py @@ -5,6 +5,7 @@ import json import re +import ssl import time import uuid from contextlib import nullcontext @@ -23,6 +24,7 @@ from xml.sax.saxutils import escape import aiohttp +import certifi from edge_tts.exceptions import ( NoAudioReceived, @@ -302,9 +304,10 @@ async def stream(self) -> AsyncGenerator[Dict[str, Any], None]: prev_idx = -1 shift_time = -1 + ssl_ctx = ssl.create_default_context(cafile=certifi.where()) for idx, text in enumerate(texts): async with aiohttp.ClientSession( - trust_env=True + trust_env=True, ) as session, session.ws_connect( f"{WSS_URL}&ConnectionId={connect_id()}", compress=15, @@ -320,6 +323,7 @@ async def stream(self) -> AsyncGenerator[Dict[str, Any], None]: "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" " (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 Edg/91.0.864.41", }, + ssl=ssl_ctx, ) as websocket: # download indicates whether we should be expecting audio data, # this is so what we avoid getting binary data from the websocket diff --git a/src/edge_tts/list_voices.py b/src/edge_tts/list_voices.py index 96557c4..9b703f8 100644 --- a/src/edge_tts/list_voices.py +++ b/src/edge_tts/list_voices.py @@ -3,9 +3,11 @@ """ import json +import ssl from typing import Any, Dict, List, Optional import aiohttp +import certifi from .constants import VOICE_LIST @@ -20,6 +22,7 @@ async def list_voices(*, proxy: Optional[str] = None) -> Any: Returns: dict: A dictionary of voice attributes. """ + ssl_ctx = ssl.create_default_context(cafile=certifi.where()) async with aiohttp.ClientSession(trust_env=True) as session: async with session.get( VOICE_LIST, @@ -37,6 +40,7 @@ async def list_voices(*, proxy: Optional[str] = None) -> Any: "Accept-Language": "en-US,en;q=0.9", }, proxy=proxy, + ssl=ssl_ctx, ) as url: data = json.loads(await url.text()) return data diff --git a/src/edge_tts/version.py b/src/edge_tts/version.py index e972997..6c9e331 100644 --- a/src/edge_tts/version.py +++ b/src/edge_tts/version.py @@ -1,4 +1,4 @@ """Edge TTS version information.""" -__version__ = "6.1.7" +__version__ = "6.1.8" __version_info__ = tuple(int(num) for num in __version__.split("."))