Skip to content
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
4 changes: 1 addition & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ dependencies = [
"lazy-object-proxy>=1.10.0",
"more_itertools>=10.2.0",
"typing-extensions>=4.1.0",
# TODO: Relax the upper bound once the issue is resolved:
# https://github.com/apify/apify-sdk-python/issues/325
"websockets>=10.0,<14.0.0",
"websockets>=14.0",
]

[project.optional-dependencies]
Expand Down
6 changes: 3 additions & 3 deletions src/apify/_platform_event_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from datetime import datetime
from typing import TYPE_CHECKING, Annotated, Any, Literal, Union

import websockets.client
import websockets.asyncio.client
from pydantic import BaseModel, Discriminator, Field, TypeAdapter
from typing_extensions import Self, Unpack, override

Expand Down Expand Up @@ -143,7 +143,7 @@ class PlatformEventManager(EventManager):
but instead use it via the `Actor.on()` and `Actor.off()` methods.
"""

_platform_events_websocket: websockets.client.WebSocketClientProtocol | None = None
_platform_events_websocket: websockets.asyncio.client.ClientConnection | None = None
_process_platform_messages_task: asyncio.Task | None = None
_send_system_info_interval_task: asyncio.Task | None = None
_connected_to_platform_websocket: asyncio.Future = asyncio.Future()
Expand Down Expand Up @@ -196,7 +196,7 @@ async def __aexit__(

async def _process_platform_messages(self, ws_url: str) -> None:
try:
async with websockets.client.connect(ws_url) as websocket:
async with websockets.asyncio.client.connect(ws_url) as websocket:
self._platform_events_websocket = websocket
self._connected_to_platform_websocket.set_result(True)

Expand Down
8 changes: 4 additions & 4 deletions tests/unit/actor/test_actor_lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from unittest.mock import AsyncMock, Mock

import pytest
import websockets.server
import websockets.asyncio.server
from lazy_object_proxy import Proxy

from apify_shared.consts import ActorEnvVars, ApifyEnvVars
Expand Down Expand Up @@ -139,10 +139,10 @@ def log_persist_state(data: Any) -> None:
nonlocal persist_state_events_data
persist_state_events_data.append(data)

async def handler(websocket: websockets.server.WebSocketServerProtocol) -> None:
async def handler(websocket: websockets.asyncio.server.ServerConnection) -> None:
await websocket.wait_closed()

async with websockets.server.serve(handler, host='localhost') as ws_server:
async with websockets.asyncio.server.serve(handler, host='localhost') as ws_server:
port: int = ws_server.sockets[0].getsockname()[1] # type: ignore[index]
monkeypatch.setenv(ApifyEnvVars.ACTOR_EVENTS_WS_URL, f'ws://localhost:{port}')

Expand Down Expand Up @@ -181,7 +181,7 @@ async def handler(websocket: websockets.server.WebSocketServerProtocol) -> None:
Actor.on(Event.PERSIST_STATE, log_persist_state)
await asyncio.sleep(2)

for socket in ws_server.websockets:
for socket in ws_server.connections:
await socket.send(
json.dumps(
{
Expand Down
14 changes: 7 additions & 7 deletions tests/unit/test_platform_event_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import pytest
import websockets
import websockets.server
import websockets.asyncio.server

from apify_shared.consts import ActorEnvVars
from crawlee.events._types import Event
Expand Down Expand Up @@ -133,16 +133,16 @@ async def test_lifecycle_on_platform_without_websocket(monkeypatch: pytest.Monke


async def test_lifecycle_on_platform(monkeypatch: pytest.MonkeyPatch) -> None:
connected_ws_clients: set[websockets.server.WebSocketServerProtocol] = set()
connected_ws_clients: set[websockets.asyncio.server.ServerConnection] = set()

async def handler(websocket: websockets.server.WebSocketServerProtocol) -> None:
async def handler(websocket: websockets.asyncio.server.ServerConnection) -> None:
connected_ws_clients.add(websocket)
try:
await websocket.wait_closed()
finally:
connected_ws_clients.remove(websocket)

async with websockets.server.serve(handler, host='localhost') as ws_server:
async with websockets.asyncio.server.serve(handler, host='localhost') as ws_server:
# When you don't specify a port explicitly, the websocket connection is opened on a random free port.
# We need to find out which port is that.
port: int = ws_server.sockets[0].getsockname()[1] # type: ignore[index]
Expand All @@ -153,9 +153,9 @@ async def handler(websocket: websockets.server.WebSocketServerProtocol) -> None:


async def test_event_handling_on_platform(monkeypatch: pytest.MonkeyPatch) -> None:
connected_ws_clients: set[websockets.server.WebSocketServerProtocol] = set()
connected_ws_clients: set[websockets.asyncio.server.ServerConnection] = set()

async def handler(websocket: websockets.server.WebSocketServerProtocol) -> None:
async def handler(websocket: websockets.asyncio.server.ServerConnection) -> None:
connected_ws_clients.add(websocket)
try:
await websocket.wait_closed()
Expand All @@ -169,7 +169,7 @@ async def send_platform_event(event_name: Event, data: Any = None) -> None:

websockets.broadcast(connected_ws_clients, json.dumps(message))

async with websockets.server.serve(handler, host='localhost') as ws_server:
async with websockets.asyncio.server.serve(handler, host='localhost') as ws_server:
# When you don't specify a port explicitly, the websocket connection is opened on a random free port.
# We need to find out which port is that.
port: int = ws_server.sockets[0].getsockname()[1] # type: ignore[index]
Expand Down
Loading
Loading