Skip to content

Commit bbea1f5

Browse files
authored
Use persistent HTTP clients for TTS (#125)
* Use persistent HTTP clients for TTS Add httpx as a dependency and configure persistent HTTP clients for text-to-speech requests. The OpenAI client is now initialized with a custom httpx.Client (HTTP/2, connection limits and timeouts) in the live-stream output. The non-live output stream now reuses a requests.Session for POST requests and closes it on shutdown to improve connection reuse and performance. Also import httpx where needed and adjust resource cleanup accordingly. * Use ANY for http_client and Session.post in tests Update tests to accommodate an injected HTTP client and to patch the correct requests API. Added ANY to unittest.mock imports and assert_called_once_with checks for http_client=ANY in om1_speech audio live stream tests, and changed the patch target from requests.post to requests.Session.post in the audio output stream tests. These are test-only changes to align mocks with the implementation.
1 parent 5a8a633 commit bbea1f5

6 files changed

Lines changed: 64 additions & 4 deletions

File tree

poetry.lock

Lines changed: 42 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ openai= "1.60.1"
3535
filelock = "3.20.3"
3636
prometheus-client = "0.25.0"
3737
urllib3="2.7.0"
38+
httpx = {extras = ["http2"], version = "^0.28.1"}
3839

3940

4041
[tool.poetry.extras]

src/om1_speech/audio/audio_output_live_stream.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from queue import Queue
99
from typing import Any, Callable, Dict, Optional
1010

11+
import httpx
1112
import openai
1213
import zenoh
1314

@@ -70,6 +71,15 @@ def __init__(
7071
self.openai_client = openai.OpenAI(
7172
base_url=self._url,
7273
api_key=self._api_key or "no-need-api-key",
74+
http_client=httpx.Client(
75+
http2=True,
76+
limits=httpx.Limits(
77+
max_keepalive_connections=10,
78+
max_connections=20,
79+
keepalive_expiry=300.0,
80+
),
81+
timeout=httpx.Timeout(60.0, connect=5.0),
82+
),
7383
)
7484

7585
# Callback for TTS state

src/om1_speech/audio/audio_output_stream.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ def __init__(
5858
# Callback for TTS state
5959
self._tts_state_callback = tts_state_callback
6060

61+
# HTTP session
62+
self._session = requests.Session()
63+
6164
# Zenoh
6265
self.topic = "robot/status/audio"
6366
self.session = None
@@ -166,7 +169,7 @@ def _process_audio(self):
166169
try:
167170
start_time = time.time()
168171
tts_request = self._pending_requests.get()
169-
response = requests.post(
172+
response = self._session.post(
170173
self._url,
171174
data=json.dumps(tts_request),
172175
headers=self._headers,
@@ -381,6 +384,9 @@ def stop(self):
381384
"""
382385
self.running = False
383386

387+
if self._session:
388+
self._session.close()
389+
384390
if self.session:
385391
self.session.close()
386392

tests/om1_speech/audio/test_audio_output_live_stream.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import threading
44
import time
55
from queue import Queue
6-
from unittest.mock import Mock, patch
6+
from unittest.mock import ANY, Mock, patch
77

88
import pytest
99

@@ -518,6 +518,7 @@ def test_openai_client_creation(mock_openai, mock_zenoh):
518518
mock_openai.assert_called_once_with(
519519
base_url="http://test-server/v1",
520520
api_key="test-key",
521+
http_client=ANY,
521522
)
522523

523524
stream.stop()
@@ -534,6 +535,7 @@ def test_openai_client_no_api_key(mock_openai, mock_zenoh):
534535
mock_openai.assert_called_once_with(
535536
base_url="http://test-server/v1",
536537
api_key="no-need-api-key",
538+
http_client=ANY,
537539
)
538540

539541
stream.stop()

tests/om1_speech/audio/test_audio_output_stream.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def mock_ffplay():
4848

4949
@pytest.fixture
5050
def mock_requests():
51-
with patch("requests.post") as mock:
51+
with patch("requests.Session.post") as mock:
5252
# Setup mock response
5353
mock_response = Mock()
5454
mock_response.status_code = 200

0 commit comments

Comments
 (0)