Skip to content

feat: add optional headers support to WebSocket connection#83

Open
sam-s10s wants to merge 2 commits intomainfrom
fix/websocket-headers
Open

feat: add optional headers support to WebSocket connection#83
sam-s10s wants to merge 2 commits intomainfrom
fix/websocket-headers

Conversation

@sam-s10s
Copy link
Member

@sam-s10s sam-s10s commented Feb 11, 2026

Introduce an optional ws_headers parameter to the connect method in VoiceAgentClient and the underlying AsyncClient. This allows users to pass custom headers when establishing the WebSocket connection to the Speechmatics API.

Test tests/voice/test_06_stt_config.py tests for valid and invalid ws_headers passed to the connect method.

Introduce an optional `ws_headers` parameter to the `connect` method in
`VoiceAgentClient`. This allows users to pass custom headers when
establishing the WebSocket connection to the Speechmatics API.
@LArmstrongDev
Copy link
Contributor

LArmstrongDev commented Feb 12, 2026

Can you add a comment with the testing you've done? Thanks.

Introduce two new tests to validate header
handling in the STT client. `test_with_headers`
checks successful connection using valid headers,
while `test_with_corrupted_headers` ensures
connection failure with invalid header format.
@sam-s10s
Copy link
Member Author

sam-s10s commented Mar 3, 2026

Looks good. Can you add a comment with the testing you've done? Thanks.

@LArmstrongDev - new test has been added to include valid and invalid header testing.

"""Tests that a client can be created.

- Checks for a valid session
- Checks that 'English' is the language pack info
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This docstring isn't correct. There's no check for the language pack.

async def test_no_partials():
"""Tests for STT config (no partials)."""
async def test_with_corrupted_headers():
"""Tests that a client can be created.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This docstring isn't correct - it's a test for handling corrupted/invalid headers.

# Check we are connected OK
try:
await client.connect(ws_headers=ws_headers)
except AttributeError:
Copy link
Contributor

@LArmstrongDev LArmstrongDev Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we silently pass here? This will mask any bugs that come up in the client connection code. Given that the headers are corrupted, I assume we expect a failure - but here, if connect() raises no exception somehow, the test would still pass (false positive).

await client.connect(ws_headers=ws_headers)

# Check we are connected
assert client._is_connected
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, you access a private attribute - a public property or function would be better.

@pytest.mark.asyncio
async def test_no_partials():
"""Tests for STT config (no partials)."""
async def test_with_corrupted_headers():
Copy link
Contributor

@LArmstrongDev LArmstrongDev Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test name should convey the expected outcome. Can you improve the naming? Same for the test above.

@LArmstrongDev
Copy link
Contributor

In the test, you have shared setup. This should be extracted into a fixture to avoid repetition and make it easier to extend - e.g. for the API key check, the client creation each time, and to add disconnect() to tear-down behaviour.


# Check we are connected OK
try:
await client.connect(ws_headers=ws_headers)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this, could add a timeout to avoid hanging indefinitely, waiting to connect.

@pytest.mark.asyncio
async def test_no_partials():
"""Tests for STT config (no partials)."""
async def test_with_corrupted_headers():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only tests passing a list instead of a dict.

Could expand test coverage to test a few other cases - empty dict, headers with non-string values, very large values etc, with parametrizing a few test headers.

@LArmstrongDev
Copy link
Contributor

Several comments in the invalid header test have been copied from the valid headers test and not updated, making them inaccurate. Rather than fixing them, most should just be removed - the code is self-explanatory and the comments add noise, rather than clarity. Comments should only be present where they add context the code can't provide for ease of understanding and readability.

@@ -1,8 +1,78 @@
import os
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a topline description for the test file?

@LArmstrongDev
Copy link
Contributor

What's the actual behaviour in the malformed headers test case? When sending an invalid websocket header, what connection error message do we expect? This should be included in the test.

)

# Headers
ws_headers = {"Z-TEST-HEADER-1": "ValueOne", "Z-TEST-HEADER-2": "ValueTwo"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the two ws_headers used, it would be clearer to pull them out as constants and have a VALID_WS_HEADERS, INVALID_WS_HEADERS, or something similar, rather than hard-coding them into the tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants