getstream 3.3.2__tar.gz → 3.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {getstream-3.3.2 → getstream-3.3.4}/PKG-INFO +1 -1
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/encoders_patches.py +54 -8
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pc.py +7 -6
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/reconnection.py +3 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/signaling.py +17 -9
- {getstream-3.3.2 → getstream-3.3.4}/.cursor/worktrees.json +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/.env.example +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/.github/actions/python-uv-setup/action.yml +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/.github/workflows/ci.yml +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/.github/workflows/release.yml +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/.github/workflows/run_tests.yml +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/.github/workflows/stream-py.code-workspace +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/.gitignore +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/.gitmodules +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/.pre-commit-config.yaml +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/AGENTS.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/CHANGELOG.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/DEVELOPMENT.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/LICENSE.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/MIGRATION_v2_to_v3.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/Makefile +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/README.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/dev.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/docs/migration-from-stream-chat-python/01-setup-and-auth.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/docs/migration-from-stream-chat-python/02-users.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/docs/migration-from-stream-chat-python/03-channels.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/docs/migration-from-stream-chat-python/04-messages-and-reactions.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/docs/migration-from-stream-chat-python/05-moderation.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/docs/migration-from-stream-chat-python/06-devices.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/docs/migration-from-stream-chat-python/README.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/generate.sh +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/generate_webrtc.sh +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/base.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/chat/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/chat/async_channel.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/chat/async_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/chat/async_rest_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/chat/channel.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/chat/client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/chat/rest_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/common/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/common/async_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/common/async_rest_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/common/client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/common/rest_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/common/telemetry.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/config.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/feeds/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/feeds/client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/feeds/feeds.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/feeds/rest_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/generic.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/meta.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/models/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/moderation/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/moderation/async_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/moderation/async_rest_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/moderation/client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/moderation/rest_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/rate_limit.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/stream.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/stream_response.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/tests/test_webhook.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/utils/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/utils/event_emitter.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/utils/retry.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/version.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/async_call.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/async_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/async_rest_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/call.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/openai.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rest_client.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/README.md +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/audio_track.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/connection_manager.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/connection_utils.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/coordinator/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/coordinator/backoff.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/coordinator/errors.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/coordinator/ws.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/coordinator_api.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/g711.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/location_discovery.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/models.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/network_monitor.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/participants.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/event/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/event/events_pb2.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/event/events_pb2.pyi +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/models/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/models/models_pb2.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/models/models_pb2.pyi +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/signal_rpc/__init__.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/signal_rpc/signal_pb2.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/signal_rpc/signal_pb2.pyi +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/signal_rpc/signal_twirp.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/peer_connection.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/recording.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/stats_reporter.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/stats_tracer.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/tracer.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/track_util.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/tracks.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/twirp_client_wrapper.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/utils.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/getstream/webhook.py +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/pyproject.toml +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/pytest.ini +0 -0
- {getstream-3.3.2 → getstream-3.3.4}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: getstream
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.4
|
|
4
4
|
Summary: GetStream Python SDK - Build scalable activity feeds, chat, and video calling applications
|
|
5
5
|
Author-email: sachaarbonel <sacha.arbonel@hotmail.fr>, tbarbugli <tbarbugli@gmail.com>
|
|
6
6
|
License-File: LICENSE.md
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import fractions
|
|
1
2
|
import logging
|
|
2
3
|
import os
|
|
3
4
|
from typing import Optional
|
|
4
5
|
|
|
6
|
+
import av
|
|
5
7
|
from aiortc import RTCRtpCodecParameters
|
|
8
|
+
from aiortc.codecs.h264 import MAX_FRAME_RATE as H264_MAX_FRAME_RATE
|
|
6
9
|
from aiortc.codecs.h264 import H264Encoder
|
|
7
10
|
from aiortc.codecs.vpx import Vp8Encoder
|
|
8
11
|
from aiortc.rtcrtpsender import RTCEncodedFrame, RTCRtpSender
|
|
@@ -26,6 +29,11 @@ BITRATE_PATCH_DISABLED = os.getenv(
|
|
|
26
29
|
"off",
|
|
27
30
|
)
|
|
28
31
|
|
|
32
|
+
# libx264 preset for the StreamH264Encoder. Defaults to "ultrafast" for
|
|
33
|
+
# real-time CPU; can be raised (e.g. "veryfast", "medium") for better
|
|
34
|
+
# quality-per-bit at the cost of more CPU per frame.
|
|
35
|
+
STREAM_H264_PRESET = os.getenv("STREAM_PATCH_AIORTC_H264_PRESET", "ultrafast").strip()
|
|
36
|
+
|
|
29
37
|
|
|
30
38
|
try:
|
|
31
39
|
# Verify the name-mangled attributes we depend on still exist.
|
|
@@ -51,11 +59,13 @@ try:
|
|
|
51
59
|
self._Vp8Encoder__target_bitrate = bitrate
|
|
52
60
|
|
|
53
61
|
class StreamH264Encoder(H264Encoder):
|
|
54
|
-
"""H264Encoder subclass with higher bitrate bounds
|
|
62
|
+
"""H264Encoder subclass with higher bitrate bounds and a real-time
|
|
63
|
+
libx264 preset for Stream calls."""
|
|
55
64
|
|
|
56
65
|
def __init__(self) -> None:
|
|
57
66
|
super().__init__()
|
|
58
67
|
self._H264Encoder__target_bitrate = STREAM_VIDEO_DEFAULT_BITRATE
|
|
68
|
+
self.preset = STREAM_H264_PRESET
|
|
59
69
|
|
|
60
70
|
@property
|
|
61
71
|
def target_bitrate(self) -> int:
|
|
@@ -68,10 +78,45 @@ try:
|
|
|
68
78
|
)
|
|
69
79
|
self._H264Encoder__target_bitrate = bitrate
|
|
70
80
|
|
|
81
|
+
def _encode_frame(self, frame, force_keyframe):
|
|
82
|
+
# Mirror parent's invalidation policy so we own codec creation in
|
|
83
|
+
# both first-init AND recreation (resolution/bitrate change) paths;
|
|
84
|
+
# otherwise parent's `if self.codec is None` branch silently
|
|
85
|
+
# reverts our preset to libx264's default `medium`.
|
|
86
|
+
codec = self.codec
|
|
87
|
+
if (
|
|
88
|
+
codec is not None
|
|
89
|
+
and codec.bit_rate
|
|
90
|
+
and (
|
|
91
|
+
frame.width != codec.width
|
|
92
|
+
or frame.height != codec.height
|
|
93
|
+
or abs(self.target_bitrate - codec.bit_rate) / codec.bit_rate > 0.1
|
|
94
|
+
)
|
|
95
|
+
):
|
|
96
|
+
self.buffer_data = b""
|
|
97
|
+
self.buffer_pts = None
|
|
98
|
+
self.codec = None
|
|
99
|
+
|
|
100
|
+
if self.codec is None:
|
|
101
|
+
self.codec = av.CodecContext.create("libx264", "w")
|
|
102
|
+
self.codec.width = frame.width
|
|
103
|
+
self.codec.height = frame.height
|
|
104
|
+
self.codec.bit_rate = self.target_bitrate
|
|
105
|
+
self.codec.pix_fmt = "yuv420p"
|
|
106
|
+
self.codec.framerate = fractions.Fraction(H264_MAX_FRAME_RATE, 1)
|
|
107
|
+
self.codec.time_base = fractions.Fraction(1, H264_MAX_FRAME_RATE)
|
|
108
|
+
self.codec.options = {
|
|
109
|
+
"level": "31",
|
|
110
|
+
"tune": "zerolatency",
|
|
111
|
+
"preset": self.preset,
|
|
112
|
+
}
|
|
113
|
+
self.codec.profile = "Baseline"
|
|
114
|
+
yield from super()._encode_frame(frame, force_keyframe)
|
|
115
|
+
|
|
71
116
|
except Exception:
|
|
72
117
|
logger.warning(
|
|
73
|
-
"Failed to patch aiortc
|
|
74
|
-
"falling back to default aiortc
|
|
118
|
+
"Failed to patch aiortc encoder subclasses with Stream values (aiortc internals may have changed), "
|
|
119
|
+
"falling back to default aiortc encoders. \n"
|
|
75
120
|
"Set STREAM_PATCH_AIORTC_BITRATES=0 to disable patching.",
|
|
76
121
|
exc_info=True,
|
|
77
122
|
)
|
|
@@ -80,10 +125,11 @@ except Exception:
|
|
|
80
125
|
|
|
81
126
|
|
|
82
127
|
def patch_sender_encoder(sender: RTCRtpSender) -> None:
|
|
83
|
-
"""Patch a
|
|
128
|
+
"""Patch a sender to use Stream's tuned encoders for the negotiated codec.
|
|
84
129
|
|
|
85
|
-
|
|
86
|
-
|
|
130
|
+
Works for video (VP8/H264) senders. If anything
|
|
131
|
+
goes wrong (e.g. aiortc internals changed), the sender is left untouched
|
|
132
|
+
and will use the stock encoder via get_encoder().
|
|
87
133
|
"""
|
|
88
134
|
if StreamVp8Encoder is None or StreamH264Encoder is None:
|
|
89
135
|
return
|
|
@@ -105,8 +151,8 @@ def patch_sender_encoder(sender: RTCRtpSender) -> None:
|
|
|
105
151
|
sender._next_encoded_frame = _next_with_stream_encoder # type: ignore[method-assign]
|
|
106
152
|
except Exception:
|
|
107
153
|
logger.warning(
|
|
108
|
-
"Failed to patch aiortc
|
|
109
|
-
"falling back to default aiortc
|
|
154
|
+
"Failed to patch aiortc encoder subclasses with Stream values (aiortc internals may have changed), "
|
|
155
|
+
"falling back to default aiortc encoders. \n"
|
|
110
156
|
"Set STREAM_PATCH_AIORTC_BITRATES=0 to disable patching.",
|
|
111
157
|
exc_info=True,
|
|
112
158
|
)
|
|
@@ -53,10 +53,6 @@ class PublisherPeerConnection(aiortc.RTCPeerConnection):
|
|
|
53
53
|
self._closed = False
|
|
54
54
|
self._connected_event = asyncio.Event()
|
|
55
55
|
|
|
56
|
-
for transceiver in self.getTransceivers():
|
|
57
|
-
if transceiver.kind == "video":
|
|
58
|
-
transceiver.setCodecPreferences(publish_codec_preferences())
|
|
59
|
-
|
|
60
56
|
@self.on("icegatheringstatechange")
|
|
61
57
|
def on_icegatheringstatechange():
|
|
62
58
|
logger.info(
|
|
@@ -79,8 +75,13 @@ class PublisherPeerConnection(aiortc.RTCPeerConnection):
|
|
|
79
75
|
|
|
80
76
|
def addTrack(self, track: MediaStreamTrack) -> RTCRtpSender:
|
|
81
77
|
sender = super().addTrack(track)
|
|
82
|
-
if track.kind == "video"
|
|
83
|
-
|
|
78
|
+
if track.kind == "video":
|
|
79
|
+
for transceiver in self.getTransceivers():
|
|
80
|
+
if transceiver.sender is sender:
|
|
81
|
+
transceiver.setCodecPreferences(publish_codec_preferences())
|
|
82
|
+
break
|
|
83
|
+
if not BITRATE_PATCH_DISABLED:
|
|
84
|
+
patch_sender_encoder(sender)
|
|
84
85
|
return sender
|
|
85
86
|
|
|
86
87
|
async def handle_answer(self, response):
|
|
@@ -218,6 +218,9 @@ class ReconnectionManager:
|
|
|
218
218
|
token=self.connection_manager.join_response.credentials.token
|
|
219
219
|
if self.connection_manager.join_response
|
|
220
220
|
else None,
|
|
221
|
+
ws_url=self.connection_manager.join_response.credentials.server.ws_endpoint
|
|
222
|
+
if self.connection_manager.join_response
|
|
223
|
+
else None,
|
|
221
224
|
session_id=self.connection_manager.session_id,
|
|
222
225
|
)
|
|
223
226
|
|
|
@@ -68,6 +68,10 @@ class WebSocketClient(StreamAsyncIOEventEmitter):
|
|
|
68
68
|
self.running = False
|
|
69
69
|
self.closed = False
|
|
70
70
|
self._connection_lost_sent = False
|
|
71
|
+
# Set when a `call_ended` SFU event arrives. Read by `_on_close` to
|
|
72
|
+
# suppress `connection_lost`, since the close frame that follows carries
|
|
73
|
+
# no distinguishing status code or reason.
|
|
74
|
+
self._call_ended = False
|
|
71
75
|
|
|
72
76
|
# For ping/health check mechanism
|
|
73
77
|
self.ping_thread = None
|
|
@@ -168,6 +172,9 @@ class WebSocketClient(StreamAsyncIOEventEmitter):
|
|
|
168
172
|
event_type = event.WhichOneof("event_payload")
|
|
169
173
|
logger.debug(f"WebSocket message received {event_type}")
|
|
170
174
|
|
|
175
|
+
if event_type and event_type == "call_ended":
|
|
176
|
+
self._call_ended = True
|
|
177
|
+
|
|
171
178
|
if event.HasField("health_check_response"):
|
|
172
179
|
logger.debug("received health check response")
|
|
173
180
|
self.last_health_check_time = time.time()
|
|
@@ -199,29 +206,30 @@ class WebSocketClient(StreamAsyncIOEventEmitter):
|
|
|
199
206
|
|
|
200
207
|
def _on_error(self, ws, error):
|
|
201
208
|
"""Handle WebSocket error."""
|
|
202
|
-
|
|
209
|
+
is_close_frame = (
|
|
203
210
|
isinstance(error, websocket.ABNF)
|
|
204
211
|
and error.opcode == websocket.ABNF.OPCODE_CLOSE
|
|
205
|
-
)
|
|
206
|
-
|
|
207
|
-
#
|
|
208
|
-
logger.debug(f"WebSocket
|
|
212
|
+
)
|
|
213
|
+
if is_close_frame or not self.running:
|
|
214
|
+
# Close-frame-as-error or post-disconnect teardown noise.
|
|
215
|
+
logger.debug(f"WebSocket error after disconnect: {error}")
|
|
209
216
|
else:
|
|
210
217
|
logger.error(f"WebSocket error: {error}")
|
|
211
218
|
|
|
212
219
|
if not self.first_message_event.is_set():
|
|
213
|
-
#
|
|
220
|
+
# Mid-handshake failure: unblock `connect()` with a synthetic
|
|
221
|
+
# error event instead of leaving it parked on `first_message_event`.
|
|
214
222
|
error_event = events_pb2.SfuEvent()
|
|
215
223
|
error_event.error.error.message = str(error)
|
|
216
224
|
self.first_message = error_event
|
|
217
225
|
self.first_message_event.set()
|
|
218
|
-
elif not self.closed:
|
|
226
|
+
elif not self.closed and not is_close_frame:
|
|
219
227
|
self._notify_connection_lost(f"error: {error}")
|
|
220
228
|
|
|
221
229
|
def _on_close(self, ws, close_status_code, close_msg):
|
|
222
230
|
"""Handle WebSocket close event."""
|
|
223
231
|
logger.debug(f"WebSocket connection closed: {close_status_code} {close_msg}")
|
|
224
|
-
was_unexpected = not self.closed
|
|
232
|
+
was_unexpected = not self.closed and not self._call_ended
|
|
225
233
|
self.running = False
|
|
226
234
|
if was_unexpected:
|
|
227
235
|
self._notify_connection_lost(
|
|
@@ -248,7 +256,7 @@ class WebSocketClient(StreamAsyncIOEventEmitter):
|
|
|
248
256
|
logger.exception("Failed to schedule connection_lost emit")
|
|
249
257
|
|
|
250
258
|
def _claim_connection_lost(self) -> bool:
|
|
251
|
-
"""Return True
|
|
259
|
+
"""Return True if this is the first connection-lost notification."""
|
|
252
260
|
if self._connection_lost_sent:
|
|
253
261
|
return False
|
|
254
262
|
self._connection_lost_sent = True
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{getstream-3.3.2 → getstream-3.3.4}/docs/migration-from-stream-chat-python/01-setup-and-auth.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/event/__init__.py
RENAMED
|
File without changes
|
{getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/event/events_pb2.py
RENAMED
|
File without changes
|
{getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/event/events_pb2.pyi
RENAMED
|
File without changes
|
{getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/models/__init__.py
RENAMED
|
File without changes
|
{getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/models/models_pb2.py
RENAMED
|
File without changes
|
{getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/models/models_pb2.pyi
RENAMED
|
File without changes
|
{getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/signal_rpc/__init__.py
RENAMED
|
File without changes
|
{getstream-3.3.2 → getstream-3.3.4}/getstream/video/rtc/pb/stream/video/sfu/signal_rpc/signal_pb2.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|