Skip to content

Comments

Update API#217

Open
vagruchi wants to merge 6 commits intomainfrom
update-api
Open

Update API#217
vagruchi wants to merge 6 commits intomainfrom
update-api

Conversation

@vagruchi
Copy link
Contributor

@vagruchi vagruchi commented Feb 13, 2026

Summary by CodeRabbit

  • New Features

    • Future-dated channel ban querying, recording controls (type + external storage), participant session metrics, pinned-activities query, activity partial-batch updates, activity restore, SIP inbound resolution, webhook parsing/verification.
  • Enhancements

    • Channel queries: predefined filters and custom sort values.
    • Push controls: per-channel-type push level and skip-push toggles.
    • Activities/comments: expanded notification, mention and visibility options.
    • Moderation: submit actions now support flagging.
    • Feeds: friend-reactions options for feeds.
  • Tests

    • Recording tests updated for new recording-mode parameter.

@coderabbitai
Copy link

coderabbitai bot commented Feb 13, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Converted many ad-hoc JSON payload constructions to typed Request models (.to_dict()), extended numerous public method signatures with new optional parameters and payload types, added video recording and participant-session endpoints, introduced webhook parsing utilities and tests, and propagated notification/notification-control flags across Feeds and Chat APIs.

Changes

Cohort / File(s) Summary
Chat API surface
getstream/chat/async_rest_client.py, getstream/chat/rest_client.py
Replaced raw body builders with Request models (.to_dict()); added predefined_filter, filter_values, sort_values to query_channels; added push_level to channel type create/update; added skip_push to message/channel operations; several endpoints now return MessageActionResponse; added query_future_channel_bans.
Common client payloads
getstream/common/async_rest_client.py, getstream/common/rest_client.py
Switched body construction to Request models and .to_dict(); query param style moved to dict-unpacking; changed upsert_push_provider param type from PushProvider to PushProviderRequest.
Feeds — activities, comments, reactions
getstream/feeds/rest_client.py, getstream/feeds/feeds.py
Replaced build_body_dict with Request models; added/propagated flags such as copy_custom_to_notification, delete_notification_activity, skip_push, handle_mention_notifications, visibility_tag; added friend_reactions_options on Feed.get_or_create; added update_activities_partial_batch, restore_activity, and query_pinned_activities.
Moderation payloads & submit_action
getstream/moderation/async_rest_client.py, getstream/moderation/rest_client.py
Converted payloads to typed Request/ Payload variants and .to_dict(); adjusted method signatures to use *Payload types; submit_action now accepts payload variants and an optional flag field; query param construction standardized.
Video — recordings, metrics, SIP
getstream/video/rest_client.py, getstream/video/async_rest_client.py, getstream/video/call.py, getstream/video/async_call.py
Added recording endpoints requiring recording_type (start_recording/stop_recording), added get_call_participant_session_metrics and query_call_participant_sessions; replaced many body builders with Request models; switched SIP endpoints to inbound_* paths and added resolve_sip_inbound; changed notification_settings to NotificationSettingsRequest.
RTC coordinator typing
getstream/video/rtc/coordinator/ws.py
Replaced WebSocketClientProtocol typing with ClientConnection, updated imports and added an assertion after opening socket.
Webhook module & tests
getstream/webhook.py, getstream/tests/test_webhook.py
Added webhook utilities: get_event_type, parse_webhook_event, _get_event_class, verify_webhook_signature; comprehensive tests for webhook parsing and signature verification added.
Tests — video examples
tests/test_video_examples.py
Updated test to call start_recording/stop_recording with recording_type (e.g., "composite"), renamed test and adjusted assertions.
Widespread request-model migration
multiple modules (chat, feeds, moderation, common, video, getstream/...)
Broad pattern change: replace build_body_dict usage with per-endpoint Request classes and .to_dict(); many method signatures accept new optional params or payload-type refinements; query param assembly standardized to dict-unpacking where applicable.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I hopped through diffs beneath the moon,

Typed requests, new flags, and recordings soon.
Webhooks sing and metrics softly hum,
Payloads tidy, many endpoints come.
A rabbit cheers — the code’s a gentle tune.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title "Update API" is too vague and generic, failing to convey the specific nature of this extensive refactoring from build_body_dict to Request models across multiple modules. Replace with a specific title describing the main change, such as "Refactor: Replace build_body_dict with typed Request models and to_dict() serialization" or "Refactor: Migrate REST clients to use explicit Request payload models".
Docstring Coverage ⚠️ Warning Docstring coverage is 0.87% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch update-api

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.

Copy link

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@getstream/video/rtc/coordinator/ws.py`:
- Line 154: Replace the runtime-only assertion with an explicit guard that
survives Python -O: check that self._websocket (typed
Optional[ClientConnection]) is not None and if it is None raise an explicit
exception (e.g., RuntimeError or ValueError) with a clear message; update the
code path around the assert self._websocket is not None to perform this check
and then proceed using self._websocket as a non-None ClientConnection.

self._build_auth_payload(),
)
self._logger.debug("WebSocket connection established")
assert self._websocket is not None
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Replace assert with an explicit guard — assert is stripped under python -O.

Since self._websocket is typed Optional[ClientConnection], the assertion is here purely for type narrowing. However, assert statements are silently removed when Python runs with the -O (optimize) flag, which can affect production deployments. Prefer an explicit guard that survives optimization:

🛡️ Proposed fix
-        assert self._websocket is not None
+        if self._websocket is None:
+            raise StreamWSConnectionError("WebSocket connection was not established after connect()")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@getstream/video/rtc/coordinator/ws.py` at line 154, Replace the runtime-only
assertion with an explicit guard that survives Python -O: check that
self._websocket (typed Optional[ClientConnection]) is not None and if it is None
raise an explicit exception (e.g., RuntimeError or ValueError) with a clear
message; update the code path around the assert self._websocket is not None to
perform this check and then proceed using self._websocket as a non-None
ClientConnection.

Copy link

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@getstream/tests/test_webhook.py`:
- Around line 17-56: Replace the class-level setup_method in
TestVerifyWebhookSignature with pytest fixtures: create fixtures named secret,
body, and valid_signature that compute the same values (secret string, body
bytes, and HMAC using hashlib.sha256) and have tests accept those fixtures as
parameters; update each test method to remove self and use the fixture names
(e.g., def test_valid_signature(body, valid_signature, secret): assert
verify_webhook_signature(body, valid_signature, secret) is True) so
verify_webhook_signature is exercised via injected fixtures instead of instance
state.

In `@getstream/video/rest_client.py`:
- Around line 625-636: The get_call_participant_session_metrics function passes
datetime objects (since/until) directly into build_query_param which falls back
to json.dumps and will raise for datetimes; convert/serialize since and until to
an ISO-8601 string (or desired timestamp format) before calling
build_query_param (e.g., transform the values if not None) so build_query_param
receives strings; update the query_params creation in
get_call_participant_session_metrics to use the serialized values when calling
build_query_param.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fabb0cd and c73eccf.

📒 Files selected for processing (14)
  • getstream/chat/async_rest_client.py
  • getstream/chat/rest_client.py
  • getstream/common/async_rest_client.py
  • getstream/common/rest_client.py
  • getstream/feeds/feeds.py
  • getstream/feeds/rest_client.py
  • getstream/models/__init__.py
  • getstream/moderation/async_rest_client.py
  • getstream/moderation/rest_client.py
  • getstream/tests/test_webhook.py
  • getstream/video/async_rest_client.py
  • getstream/video/rest_client.py
  • getstream/webhook.py
  • tests/test_video_examples.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/test_video_examples.py

Comment on lines +17 to +56
class TestVerifyWebhookSignature:
def setup_method(self):
self.secret = "test-webhook-secret"
self.body = b'{"type":"test.event"}'
self.valid_signature = hmac.new(
self.secret.encode("utf-8"), self.body, hashlib.sha256
).hexdigest()

def test_valid_signature(self):
assert (
verify_webhook_signature(self.body, self.valid_signature, self.secret)
is True
)

def test_wrong_signature(self):
assert (
verify_webhook_signature(self.body, "invalidsignature", self.secret)
is False
)

def test_tampered_body(self):
assert (
verify_webhook_signature(
b'{"type":"tampered"}', self.valid_signature, self.secret
)
is False
)

def test_wrong_secret(self):
assert (
verify_webhook_signature(self.body, self.valid_signature, "wrong-secret")
is False
)

def test_string_body(self):
body_str = '{"type":"test.event"}'
sig = hmac.new(
self.secret.encode("utf-8"), body_str.encode("utf-8"), hashlib.sha256
).hexdigest()
assert verify_webhook_signature(body_str, sig, self.secret) is True
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Replace setup_method with pytest fixtures for shared webhook inputs.
This file uses instance state instead of fixtures for shared data; please switch to fixtures for the secret/body/signature setup.

♻️ Suggested fixture-based setup
-class TestVerifyWebhookSignature:
-    def setup_method(self):
-        self.secret = "test-webhook-secret"
-        self.body = b'{"type":"test.event"}'
-        self.valid_signature = hmac.new(
-            self.secret.encode("utf-8"), self.body, hashlib.sha256
-        ).hexdigest()
+@pytest.fixture
+def webhook_secret():
+    return "test-webhook-secret"
+
+@pytest.fixture
+def webhook_body():
+    return b'{"type":"test.event"}'
+
+@pytest.fixture
+def webhook_signature(webhook_secret, webhook_body):
+    return hmac.new(
+        webhook_secret.encode("utf-8"), webhook_body, hashlib.sha256
+    ).hexdigest()
+
+class TestVerifyWebhookSignature:
+    def test_valid_signature(self, webhook_body, webhook_signature, webhook_secret):
+        assert (
+            verify_webhook_signature(webhook_body, webhook_signature, webhook_secret)
+            is True
+        )

As per coding guidelines, “Use fixtures to inject objects in tests; test client fixtures can use the Stream API client”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@getstream/tests/test_webhook.py` around lines 17 - 56, Replace the
class-level setup_method in TestVerifyWebhookSignature with pytest fixtures:
create fixtures named secret, body, and valid_signature that compute the same
values (secret string, body bytes, and HMAC using hashlib.sha256) and have tests
accept those fixtures as parameters; update each test method to remove self and
use the fixture names (e.g., def test_valid_signature(body, valid_signature,
secret): assert verify_webhook_signature(body, valid_signature, secret) is True)
so verify_webhook_signature is exercised via injected fixtures instead of
instance state.

Comment on lines +625 to +636
def get_call_participant_session_metrics(
self,
type: str,
id: str,
session: str,
user: str,
user_session: str,
since: Optional[datetime] = None,
until: Optional[datetime] = None,
) -> StreamResponse[GetCallParticipantSessionMetricsResponse]:
query_params = build_query_param(**{"since": since, "until": until})
path_params = {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Serialize since/until before building query params.

build_query_param falls back to json.dumps for unknown types, and datetime isn’t JSON‑serializable, so this can raise at runtime when since/until are provided.

🛠️ Proposed fix
-        query_params = build_query_param(**{"since": since, "until": until})
+        query_params = build_query_param(
+            **{
+                "since": since.isoformat() if since else None,
+                "until": until.isoformat() if until else None,
+            }
+        )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@getstream/video/rest_client.py` around lines 625 - 636, The
get_call_participant_session_metrics function passes datetime objects
(since/until) directly into build_query_param which falls back to json.dumps and
will raise for datetimes; convert/serialize since and until to an ISO-8601
string (or desired timestamp format) before calling build_query_param (e.g.,
transform the values if not None) so build_query_param receives strings; update
the query_params creation in get_call_participant_session_metrics to use the
serialized values when calling build_query_param.

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.

3 participants