Skip to content

build: upgrade websockets dependency to support v14-v16#398

Open
omidroshani wants to merge 3 commits intoautoscrape-labs:mainfrom
omidroshani:build/upgrade-websockets-v16
Open

build: upgrade websockets dependency to support v14-v16#398
omidroshani wants to merge 3 commits intoautoscrape-labs:mainfrom
omidroshani:build/upgrade-websockets-v16

Conversation

@omidroshani
Copy link
Copy Markdown

@omidroshani omidroshani commented Apr 9, 2026

Summary

  • Broadens the websockets version constraint from ^14 (>=14, <15) to >=14, <17
  • Resolves dependency conflicts with packages requiring websockets >=15 (e.g. fastmcp 3.1.0)
  • No source code changes needed — the existing websockets API usage is fully compatible with v16

Closes #388

Test plan

  • All 1767 existing tests pass with websockets 16.0
  • Ruff lint checks pass
  • Verified ConnectionClosed, ClientConnection, State, connect(), send(), recv(), ping(), close() APIs are unchanged in v16

Summary by CodeRabbit

  • Chores

    • Updated the websockets dependency constraint to improve compatibility and stability across supported versions.
  • Tests

    • Added async tests covering concurrent sends, receiver-task lifecycle behavior, and uniqueness of generated command IDs to strengthen connection-handling reliability and prevent regressions.

Broadens the websockets version constraint from ^14 (>=14, <15) to
>=14,<17, resolving dependency conflicts with packages requiring
websockets >=15 (e.g. fastmcp).

Closes autoscrape-labs#388
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

Updated pyproject.toml to broaden the websockets constraint to >=14,<17 and added three asyncio tests for ConnectionHandler covering concurrent sends, receiver-task creation/idempotence, and command ID uniqueness.

Changes

Cohort / File(s) Summary
Dependency Version Update
pyproject.toml
Changed websockets version constraint from ^14 to >=14,<17 (permits 14.x, 15.x, 16.x).
ConnectionHandler Tests
tests/test_connection_handler.py
Added three pytest.mark.asyncio tests: concurrency/send stub asserting five sends, receiver-task creation/idempotence with task cancellation handling, and command ID uniqueness under repeated create_command_future calls.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibbled at a version line,
Let websockets stretch to fifteen and sixteen fine.
I raced five sends across the night,
Kept one receiver in soft moonlight.
Little rabbit smiles — tests all right. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: upgrading the websockets dependency constraint to support versions 14-16, which is the primary objective of the PR.
Description check ✅ Passed The PR description addresses the core requirements with a clear summary, test plan, and resolution details. However, it does not follow the provided template structure with Type of Change checkboxes and formal sections.
Linked Issues check ✅ Passed The PR successfully addresses issue #388 by updating the websockets constraint from ^14 to >=14,<17, resolving the dependency conflict with fastmcp 3.1.0 that requires websockets>=15. The code changes support this objective.
Out of Scope Changes check ✅ Passed All changes are in scope: pyproject.toml dependency update addresses issue #388, and test additions in test_connection_handler.py verify compatibility and robustness with the new websockets versions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@dean985
Copy link
Copy Markdown
Contributor

dean985 commented Apr 9, 2026

hey @omidroshani , thanks for this!
before merge, can you take a look at my comment here #388 (comment)
I'd appreciated if you can comment on it.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/test_connection_handler.py (1)

384-392: Test name says “concurrent”, but execution is sequential.

This loop runs create_command_future sequentially, so it validates uniqueness across repeated calls, not true concurrency. Please either rename the test or introduce real concurrent invocation.

Minimal clarity fix (rename)
-async def test_command_ids_unique_under_concurrent_calls(connection_handler):
+async def test_command_ids_unique_across_multiple_calls(connection_handler):
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_connection_handler.py` around lines 384 - 392, The test
test_command_ids_unique_under_concurrent_calls currently calls
connection_handler._command_manager.create_command_future sequentially; change
it to actually invoke create_command_future concurrently (or rename the test).
To fix by making it concurrent, wrap the calls in async tasks and await them
together (e.g., create a list of asyncio.create_task(...) or use asyncio.gather
to call connection_handler._command_manager.create_command_future(cmd) 100
times) so IDs are assigned under true concurrency, then collect cmd['id'] values
and assert len(set(assigned_ids)) == 100; alternatively, if you prefer the
minimal change, rename the test to
test_command_ids_unique_under_sequential_calls and leave the loop as-is.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/test_connection_handler.py`:
- Around line 363-380: The test test_single_receiver_task_created cancels the
receiver task (first_task.cancel()) but never awaits it, which can leave a
pending task; update the test to await the canceled task (await first_task) and
handle the expected cancellation (e.g., catching asyncio.CancelledError) after
calling first_task.cancel() so _receive_task is properly cleaned up and no
pending-task warnings occur; locate usage of
connection_handler_closed._receive_task and the final first_task.cancel() in the
test and replace the bare cancel with cancel then await/handle the cancellation.

---

Nitpick comments:
In `@tests/test_connection_handler.py`:
- Around line 384-392: The test test_command_ids_unique_under_concurrent_calls
currently calls connection_handler._command_manager.create_command_future
sequentially; change it to actually invoke create_command_future concurrently
(or rename the test). To fix by making it concurrent, wrap the calls in async
tasks and await them together (e.g., create a list of asyncio.create_task(...)
or use asyncio.gather to call
connection_handler._command_manager.create_command_future(cmd) 100 times) so IDs
are assigned under true concurrency, then collect cmd['id'] values and assert
len(set(assigned_ids)) == 100; alternatively, if you prefer the minimal change,
rename the test to test_command_ids_unique_under_sequential_calls and leave the
loop as-is.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 506ab5d0-495f-4cb4-ac5b-cf36e4ebee54

📥 Commits

Reviewing files that changed from the base of the PR and between e038f8a and 3d8fcdd.

📒 Files selected for processing (1)
  • tests/test_connection_handler.py

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
tests/test_connection_handler.py (2)

387-395: Test name and behavior are mismatched (concurrent vs sequential loop).

At Line 387, the test title says “concurrent calls”, but Line 389–Line 392 executes sequentially. Rename it (or make it truly concurrent) to keep intent accurate.

Minimal rename for accuracy
-async def test_command_ids_unique_under_concurrent_calls(connection_handler):
+async def test_command_ids_unique_across_multiple_calls(connection_handler):
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_connection_handler.py` around lines 387 - 395, The test name
claims concurrency but the loop calls
connection_handler._command_manager.create_command_future(cmd) sequentially;
either rename test_command_ids_unique_under_concurrent_calls to something like
test_command_ids_unique_under_sequential_calls or modify the test to perform
concurrent invocations (e.g., schedule many create_command_future calls via
asyncio.gather or similar) so create_command_future is exercised concurrently;
update references to the test function name and keep assertions on cmd['id']
uniqueness and count unchanged.

339-360: Strengthen concurrent-send assertions to validate response correctness, not just count.

Right now the test only verifies total results and send count. Adding response-shape checks would better guard against mismatched futures/results under concurrency.

Suggested assertion hardening
     assert len(results) == 5
+    assert {result['id'] for result in results} == {1, 2, 3, 4, 5}
+    assert {result['result'] for result in results} == {
+        'ok1', 'ok2', 'ok3', 'ok4', 'ok5'
+    }
     assert connection_handler._ws_connection.send.await_count == 5
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_connection_handler.py` around lines 339 - 360, The test
test_concurrent_send_does_not_raise currently only checks length and send
await_count; enhance it to verify each returned result matches the expected
payload and that each send call carried the correct command by asserting the
results list equals ['ok1','ok2',... ] (or the full parsed JSON per command)
and/or asserting _ws_connection.send was called with the expected serialized
commands in the same order; locate the test body and update assertions around
connection_handler.execute_command, connection_handler._ws_connection.send, and
connection_handler._command_manager.create_command_future to compare actual
responses (parsed JSON or result values) against the expected per-command
responses rather than only checking counts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/test_connection_handler.py`:
- Around line 387-395: The test name claims concurrency but the loop calls
connection_handler._command_manager.create_command_future(cmd) sequentially;
either rename test_command_ids_unique_under_concurrent_calls to something like
test_command_ids_unique_under_sequential_calls or modify the test to perform
concurrent invocations (e.g., schedule many create_command_future calls via
asyncio.gather or similar) so create_command_future is exercised concurrently;
update references to the test function name and keep assertions on cmd['id']
uniqueness and count unchanged.
- Around line 339-360: The test test_concurrent_send_does_not_raise currently
only checks length and send await_count; enhance it to verify each returned
result matches the expected payload and that each send call carried the correct
command by asserting the results list equals ['ok1','ok2',... ] (or the full
parsed JSON per command) and/or asserting _ws_connection.send was called with
the expected serialized commands in the same order; locate the test body and
update assertions around connection_handler.execute_command,
connection_handler._ws_connection.send, and
connection_handler._command_manager.create_command_future to compare actual
responses (parsed JSON or result values) against the expected per-command
responses rather than only checking counts.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 20d369a3-cac5-4b74-a3a3-e089cec41572

📥 Commits

Reviewing files that changed from the base of the PR and between 3d8fcdd and 3a13a25.

📒 Files selected for processing (1)
  • tests/test_connection_handler.py

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request]: adapts websockets 15

2 participants