Skip to content

feat: lower Python requirement to 3.10#77

Open
flochtililoch wants to merge 1 commit intofishjam-cloud:mainfrom
flochtililoch:feat/python-310-support
Open

feat: lower Python requirement to 3.10#77
flochtililoch wants to merge 1 commit intofishjam-cloud:mainfrom
flochtililoch:feat/python-310-support

Conversation

@flochtililoch
Copy link
Copy Markdown

Summary

The minimum Python version was set to >=3.11 despite the main library code being fully compatible with Python 3.10. The only 3.11-specific construct in the repository was asyncio.TaskGroup, which appeared exclusively in tests/test_notifier.py.

Changes

  • pyproject.toml: lower requires-python from >=3.11 to >=3.10
  • tests/test_notifier.py: replace all asyncio.TaskGroup usages with asyncio.ensure_future + asyncio.gather, which are available since Python 3.4 and 3.4 respectively
  • .github/workflows/ci.yml: add "3.10" to the Python version matrix for both type-check and test jobs

Motivation

Projects running Python 3.10 are currently blocked from upgrading past fishjam-server-sdk==0.20.0. This change unblocks them without affecting any existing Python 3.11+ users.

Made with Cursor

Replace asyncio.TaskGroup (Python 3.11+) in tests/test_notifier.py with
asyncio.ensure_future and asyncio.gather, which are compatible with
Python 3.10. Update requires-python in pyproject.toml and add 3.10 to
the CI test matrix.

Co-authored-by: Cursor <cursoragent@cursor.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR lowers the minimum supported Python version for the published fishjam-server-sdk package to 3.10 by updating packaging metadata, expanding CI coverage to include Python 3.10, and removing Python 3.11-only asyncio.TaskGroup usage from notifier tests.

Changes:

  • Lower requires-python in pyproject.toml from >=3.11 to >=3.10.
  • Replace asyncio.TaskGroup usage in tests/test_notifier.py with explicit task creation/cancellation.
  • Add Python 3.10 to the CI matrix for type-checking and tests.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
pyproject.toml Lowers the SDK’s declared minimum Python version to 3.10.
tests/test_notifier.py Removes TaskGroup to make tests runnable on Python 3.10.
.github/workflows/ci.yml Adds Python 3.10 to the CI matrix for type-check and test jobs.
Comments suppressed due to low confidence (1)

.github/workflows/ci.yml:36

  • python-version: ["3.10", ...] combined with uv sync --all-packages will try to sync all uv workspace members, but several example projects in pyproject.toml's workspace still declare requires-python = ">=3.11" (e.g. examples/transcription/pyproject.toml:6). This will likely make the 3.10 CI jobs fail during dependency resolution/installation. Consider either (a) adjusting the CI install step to sync only the main package (exclude --all-packages / examples) for the library CI, or (b) lowering the example projects' requires-python and removing their 3.11-only code so the whole workspace is 3.10-compatible.
    strategy: &strategy
      matrix:
        python-version: ["3.10", "3.11", "3.12", "3.13"]
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v5
        with:
          python-version: ${{ matrix.python-version }}
          enable-cache: true

      - name: Install project dependencies
        run: uv sync --locked --all-extras --all-packages

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pyproject.toml
Comment thread tests/test_notifier.py
Comment on lines +83 to +95
notifier_task = asyncio.ensure_future(notifier.connect())
await notifier.wait_ready()

assert (
notifier._websocket
and notifier._websocket.state == websockets.State.OPEN
)
assert (
notifier._websocket
and notifier._websocket.state == websockets.State.OPEN
)

notifier_task.cancel()
notifier_task.cancel()
try:
await notifier_task
except asyncio.CancelledError:
pass
Comment thread tests/test_notifier.py
Comment on lines +120 to +135
assert_task = asyncio.ensure_future(assert_events(notifier, event_checks.copy()))
notifier_task = asyncio.ensure_future(notifier.connect())
await notifier.wait_ready()

options = RoomOptions(webhook_url=WEBHOOK_URL)
room = room_api.create_room(options=options)
options = RoomOptions(webhook_url=WEBHOOK_URL)
room = room_api.create_room(options=options)

room_api.delete_room(room.id)
room_api.delete_room(room.id)

await assert_task
await assert_task

notifier_task.cancel()
notifier_task.cancel()
try:
await notifier_task
except asyncio.CancelledError:
pass
Comment thread tests/test_notifier.py
Comment on lines +152 to +172
assert_task = asyncio.ensure_future(assert_events(notifier, event_checks.copy()))
notifier_task = asyncio.ensure_future(notifier.connect())
await notifier.wait_ready()

options = RoomOptions(webhook_url=WEBHOOK_URL)
room = room_api.create_room(options=options)
options = RoomOptions(webhook_url=WEBHOOK_URL)
room = room_api.create_room(options=options)

peer, token = room_api.create_peer(room.id)
peer_socket = PeerSocket(fishjam_url=FISHJAM_ID)
peer_socket_task = tg.create_task(peer_socket.connect(token))
peer, token = room_api.create_peer(room.id)
peer_socket = PeerSocket(fishjam_url=FISHJAM_ID)
peer_socket_task = asyncio.ensure_future(peer_socket.connect(token))

await peer_socket.wait_ready()
await peer_socket.wait_ready()

room_api.delete_peer(room.id, peer.id)
room_api.delete_room(room.id)
room_api.delete_peer(room.id, peer.id)
room_api.delete_room(room.id)

await assert_task
await assert_task

notifier_task.cancel()
peer_socket_task.cancel()
notifier_task.cancel()
peer_socket_task.cancel()
await asyncio.gather(notifier_task, peer_socket_task, return_exceptions=True)
Comment thread tests/test_notifier.py
Comment on lines +188 to +207
assert_task = asyncio.ensure_future(assert_events(notifier, event_checks.copy()))
notifier_task = asyncio.ensure_future(notifier.connect())
await notifier.wait_ready()

options = RoomOptions(webhook_url=WEBHOOK_URL)
room = room_api.create_room(options=options)
_peer, token = room_api.create_peer(room.id)
options = RoomOptions(webhook_url=WEBHOOK_URL)
room = room_api.create_room(options=options)
_peer, token = room_api.create_peer(room.id)

peer_socket = PeerSocket(fishjam_url=FISHJAM_ID)
peer_socket_task = tg.create_task(peer_socket.connect(token))
peer_socket = PeerSocket(fishjam_url=FISHJAM_ID)
peer_socket_task = asyncio.ensure_future(peer_socket.connect(token))

await peer_socket.wait_ready()
await peer_socket.wait_ready()

room_api.delete_room(room.id)
room_api.delete_room(room.id)

await assert_task
await assert_task

notifier_task.cancel()
peer_socket_task.cancel()
notifier_task.cancel()
peer_socket_task.cancel()
await asyncio.gather(notifier_task, peer_socket_task, return_exceptions=True)
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.

2 participants