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

Make Speechmatics client compatible with websockets 14.0 #110

Merged
merged 1 commit into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9]
python-version: ["3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v2
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.0.0] - 2024-11-12

### Changed

- Renamed `extra_headers` to `additional_headers` in `websockets.connect()` to support WebSockets version 14.0,
as per [documentation](https://websockets.readthedocs.io/en/stable/howto/upgrade.html#arguments-of-connect)
- Updated `speechmatics-python` to require `Python >= 3.9`, aligning with WebSockets 14.0

## [2.0.3] - 2024-11-12

speechmatics-python `2.0.3` is the last version supporting `Python 3.8`
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.3
3.0.0
1 change: 0 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
asynctest==0.13.0
pytest==7.1.1
pytest-asyncio==0.18.3
pytest-mock==3.7.0
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
websockets>=10.0,<=13.1
websockets>=14.0
httpx[http2]~=0.23
polling2~=0.5
toml~=0.10.2
Expand Down
5 changes: 2 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,10 @@ def get_version(fname):
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Topic :: Multimedia :: Sound/Audio :: Speech",
"Topic :: Software Development :: Libraries :: Python Modules",
],
include_package_data=True,
python_requires=">=3.7",
python_requires=">=3.9",
)
2 changes: 1 addition & 1 deletion speechmatics/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ async def run(
ping_timeout=self.connection_settings.ping_timeout_seconds,
# Don't limit the max. size of incoming messages
max_size=None,
extra_headers=extra_headers,
additional_headers=extra_headers,
) as self.websocket:
await self._communicate(stream, audio_settings)
finally:
Expand Down
7 changes: 3 additions & 4 deletions speechmatics/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@

import asyncio
import concurrent.futures
import importlib.metadata
import inspect
import json
import os
import sys

import pkg_resources


def del_none(dictionary):
"""
Expand Down Expand Up @@ -84,8 +83,8 @@ def get_version() -> str:
:rtype: str
"""
try:
version = pkg_resources.get_distribution("speechmatics-python").version
except pkg_resources.DistributionNotFound:
version = importlib.metadata.version("speechmatics-python")
except importlib.metadata.PackageNotFoundError:
# The library is not running from the distributed package
# Get the version from the VERSION file
base_path = os.path.abspath(os.path.dirname(__file__))
Expand Down
4 changes: 2 additions & 2 deletions tests/mock_rt_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ def dummy_add_transcript():
async def mock_server_handler(websocket, logbook):
mock_server_handler.next_audio_seq_no = 1
address, _ = websocket.remote_address
logbook.connection_request = websocket.request_headers
logbook.path = websocket.path
logbook.connection_request = websocket.request.headers
logbook.path = websocket.request.path

# Begin a connection
logging.info("%s %s", address, "connected")
Expand Down
11 changes: 5 additions & 6 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from unittest.mock import patch, MagicMock
from typing import Any

import asynctest
import pytest

from pytest_httpx import HTTPXMock
Expand Down Expand Up @@ -221,7 +220,7 @@ async def test_send_message(mock_server, message_type: str, message_data: Any):
ssl=ws_client.connection_settings.ssl_context,
ping_timeout=ws_client.connection_settings.ping_timeout_seconds,
max_size=None,
extra_headers=None,
additional_headers=None,
) as ws_client.websocket:
await ws_client.send_message(message_type, message_data)
assert message_type in [
Expand Down Expand Up @@ -377,7 +376,7 @@ def call_exit(*args, **kwargs):
except Exception:
assert len(connect_mock.mock_calls) == 1
assert (
connect_mock.mock_calls[0][2]["extra_headers"] == extra_headers
connect_mock.mock_calls[0][2]["additional_headers"] == extra_headers
), f"Extra headers don't appear in the call list = {connect_mock.mock_calls}"


Expand Down Expand Up @@ -445,7 +444,7 @@ async def test__producer_happy_path(mocker):
await ws_client._init_synchronization_primitives()
original_state = deepcopy_state(ws_client)

async_iter_mock = asynctest.MagicMock()
async_iter_mock = MagicMock()
async_iter_mock.return_value.__aiter__.return_value = range(no_chunks_to_send)
mock_read_in_chunks = mocker.patch(
"speechmatics.client.read_in_chunks", new=async_iter_mock
Expand Down Expand Up @@ -498,7 +497,7 @@ async def test__producer_semaphore_pause_and_resume(mocker):
)
await ws_client._init_synchronization_primitives()

async_iter_mock = asynctest.MagicMock()
async_iter_mock = MagicMock()
async_iter_mock.return_value.__aiter__.return_value = range(no_chunks_to_send)
mocker.patch(
"speechmatics.client.read_in_chunks", new=async_iter_mock
Expand Down Expand Up @@ -553,7 +552,7 @@ async def test__producer_semaphore_timeout(mocker):
)
await ws_client._init_synchronization_primitives()

async_iter_mock = asynctest.MagicMock()
async_iter_mock = MagicMock()
async_iter_mock.return_value.__aiter__.return_value = range(no_chunks_to_send)
mocker.patch(
"speechmatics.client.read_in_chunks", new=async_iter_mock
Expand Down
Loading