diff --git a/getstream/chat/async_channel.py b/getstream/chat/async_channel.py index c9a24e01..15089ab3 100644 --- a/getstream/chat/async_channel.py +++ b/getstream/chat/async_channel.py @@ -23,10 +23,13 @@ def _sync_from_response(self, data): @attach_channel_cid_async async def delete( - self, hard_delete: Optional[bool] = None + self, hard_delete: Optional[bool] = None, skip_truncate: Optional[bool] = None ) -> StreamResponse[DeleteChannelResponse]: response = await self.client.delete_channel( - type=self.channel_type, id=self.channel_id, hard_delete=hard_delete + type=self.channel_type, + id=self.channel_id, + hard_delete=hard_delete, + skip_truncate=skip_truncate, ) self._sync_from_response(response.data) return response diff --git a/getstream/chat/async_rest_client.py b/getstream/chat/async_rest_client.py index 1162e6a6..5f89a2ba 100644 --- a/getstream/chat/async_rest_client.py +++ b/getstream/chat/async_rest_client.py @@ -243,6 +243,7 @@ async def channel_batch_update( self, operation: str, filter: Dict[str, object], + hide_history_before: Optional[datetime] = None, custom_unset: Optional[List[str]] = None, members: Optional[List[ChannelBatchMemberRequest]] = None, custom_set: Optional[Dict[str, object]] = None, @@ -251,6 +252,7 @@ async def channel_batch_update( json = ChannelBatchUpdateRequest( operation=operation, filter=filter, + hide_history_before=hide_history_before, custom_unset=custom_unset, members=members, custom_set=custom_set, @@ -262,9 +264,14 @@ async def channel_batch_update( @telemetry.operation_name("getstream.api.chat.delete_channels") async def delete_channels( - self, cids: List[str], hard_delete: Optional[bool] = None + self, + cids: List[str], + hard_delete: Optional[bool] = None, + skip_truncate: Optional[bool] = None, ) -> StreamResponse[DeleteChannelsResponse]: - json = DeleteChannelsRequest(cids=cids, hard_delete=hard_delete).to_dict() + json = DeleteChannelsRequest( + cids=cids, hard_delete=hard_delete, skip_truncate=skip_truncate + ).to_dict() return await self.post( "/api/v2/chat/channels/delete", DeleteChannelsResponse, json=json ) @@ -350,9 +357,15 @@ async def get_or_create_distinct_channel( @telemetry.operation_name("getstream.api.chat.delete_channel") async def delete_channel( - self, type: str, id: str, hard_delete: Optional[bool] = None + self, + type: str, + id: str, + hard_delete: Optional[bool] = None, + skip_truncate: Optional[bool] = None, ) -> StreamResponse[DeleteChannelResponse]: - query_params = build_query_param(hard_delete=hard_delete) + query_params = build_query_param( + hard_delete=hard_delete, skip_truncate=skip_truncate + ) path_params = { "type": type, "id": id, diff --git a/getstream/chat/channel.py b/getstream/chat/channel.py index c3974a28..da454a14 100644 --- a/getstream/chat/channel.py +++ b/getstream/chat/channel.py @@ -23,10 +23,13 @@ def _sync_from_response(self, data): @attach_channel_cid def delete( - self, hard_delete: Optional[bool] = None + self, hard_delete: Optional[bool] = None, skip_truncate: Optional[bool] = None ) -> StreamResponse[DeleteChannelResponse]: response = self.client.delete_channel( - type=self.channel_type, id=self.channel_id, hard_delete=hard_delete + type=self.channel_type, + id=self.channel_id, + hard_delete=hard_delete, + skip_truncate=skip_truncate, ) self._sync_from_response(response.data) return response diff --git a/getstream/chat/rest_client.py b/getstream/chat/rest_client.py index c20a4b48..9c7d6ce0 100644 --- a/getstream/chat/rest_client.py +++ b/getstream/chat/rest_client.py @@ -239,6 +239,7 @@ def channel_batch_update( self, operation: str, filter: Dict[str, object], + hide_history_before: Optional[datetime] = None, custom_unset: Optional[List[str]] = None, members: Optional[List[ChannelBatchMemberRequest]] = None, custom_set: Optional[Dict[str, object]] = None, @@ -247,6 +248,7 @@ def channel_batch_update( json = ChannelBatchUpdateRequest( operation=operation, filter=filter, + hide_history_before=hide_history_before, custom_unset=custom_unset, members=members, custom_set=custom_set, @@ -258,9 +260,14 @@ def channel_batch_update( @telemetry.operation_name("getstream.api.chat.delete_channels") def delete_channels( - self, cids: List[str], hard_delete: Optional[bool] = None + self, + cids: List[str], + hard_delete: Optional[bool] = None, + skip_truncate: Optional[bool] = None, ) -> StreamResponse[DeleteChannelsResponse]: - json = DeleteChannelsRequest(cids=cids, hard_delete=hard_delete).to_dict() + json = DeleteChannelsRequest( + cids=cids, hard_delete=hard_delete, skip_truncate=skip_truncate + ).to_dict() return self.post( "/api/v2/chat/channels/delete", DeleteChannelsResponse, json=json ) @@ -344,9 +351,15 @@ def get_or_create_distinct_channel( @telemetry.operation_name("getstream.api.chat.delete_channel") def delete_channel( - self, type: str, id: str, hard_delete: Optional[bool] = None + self, + type: str, + id: str, + hard_delete: Optional[bool] = None, + skip_truncate: Optional[bool] = None, ) -> StreamResponse[DeleteChannelResponse]: - query_params = build_query_param(hard_delete=hard_delete) + query_params = build_query_param( + hard_delete=hard_delete, skip_truncate=skip_truncate + ) path_params = { "type": type, "id": id, diff --git a/getstream/common/async_rest_client.py b/getstream/common/async_rest_client.py index 2f7881cc..20967244 100644 --- a/getstream/common/async_rest_client.py +++ b/getstream/common/async_rest_client.py @@ -998,6 +998,8 @@ async def get_rate_limits( ios: Optional[bool] = None, web: Optional[bool] = None, unity: Optional[bool] = None, + unity_desktop: Optional[bool] = None, + unity_console: Optional[bool] = None, endpoints: Optional[str] = None, ) -> StreamResponse[GetRateLimitsResponse]: query_params = build_query_param( @@ -1006,6 +1008,8 @@ async def get_rate_limits( ios=ios, web=web, unity=unity, + unity_desktop=unity_desktop, + unity_console=unity_console, endpoints=endpoints, ) return await self.get( diff --git a/getstream/common/rest_client.py b/getstream/common/rest_client.py index 1003add8..06405a58 100644 --- a/getstream/common/rest_client.py +++ b/getstream/common/rest_client.py @@ -982,6 +982,8 @@ def get_rate_limits( ios: Optional[bool] = None, web: Optional[bool] = None, unity: Optional[bool] = None, + unity_desktop: Optional[bool] = None, + unity_console: Optional[bool] = None, endpoints: Optional[str] = None, ) -> StreamResponse[GetRateLimitsResponse]: query_params = build_query_param( @@ -990,6 +992,8 @@ def get_rate_limits( ios=ios, web=web, unity=unity, + unity_desktop=unity_desktop, + unity_console=unity_console, endpoints=endpoints, ) return self.get( diff --git a/getstream/feeds/rest_client.py b/getstream/feeds/rest_client.py index 97f8a127..cd5c6b47 100644 --- a/getstream/feeds/rest_client.py +++ b/getstream/feeds/rest_client.py @@ -1328,6 +1328,7 @@ def create_feed_group( activity_processors: Optional[List[ActivityProcessorConfig]] = None, activity_selectors: Optional[List[ActivitySelectorConfig]] = None, activity_filter: Optional[ActivityFilterConfig] = None, + activity_marks: Optional[ActivityMarksConfig] = None, activity_processing: Optional[ActivityProcessingConfig] = None, aggregation: Optional[AggregationConfig] = None, custom: Optional[Dict[str, object]] = None, @@ -1343,6 +1344,7 @@ def create_feed_group( activity_processors=activity_processors, activity_selectors=activity_selectors, activity_filter=activity_filter, + activity_marks=activity_marks, activity_processing=activity_processing, aggregation=aggregation, custom=custom, @@ -1788,6 +1790,7 @@ def get_or_create_feed_group( activity_processors: Optional[List[ActivityProcessorConfig]] = None, activity_selectors: Optional[List[ActivitySelectorConfig]] = None, activity_filter: Optional[ActivityFilterConfig] = None, + activity_marks: Optional[ActivityMarksConfig] = None, activity_processing: Optional[ActivityProcessingConfig] = None, aggregation: Optional[AggregationConfig] = None, custom: Optional[Dict[str, object]] = None, @@ -1805,6 +1808,7 @@ def get_or_create_feed_group( activity_processors=activity_processors, activity_selectors=activity_selectors, activity_filter=activity_filter, + activity_marks=activity_marks, activity_processing=activity_processing, aggregation=aggregation, custom=custom, @@ -1829,6 +1833,7 @@ def update_feed_group( activity_processors: Optional[List[ActivityProcessorConfig]] = None, activity_selectors: Optional[List[ActivitySelectorConfig]] = None, activity_filter: Optional[ActivityFilterConfig] = None, + activity_marks: Optional[ActivityMarksConfig] = None, activity_processing: Optional[ActivityProcessingConfig] = None, aggregation: Optional[AggregationConfig] = None, custom: Optional[Dict[str, object]] = None, @@ -1846,6 +1851,7 @@ def update_feed_group( activity_processors=activity_processors, activity_selectors=activity_selectors, activity_filter=activity_filter, + activity_marks=activity_marks, activity_processing=activity_processing, aggregation=aggregation, custom=custom, @@ -2054,6 +2060,8 @@ def get_feeds_rate_limits( ios: Optional[bool] = None, web: Optional[bool] = None, unity: Optional[bool] = None, + unity_desktop: Optional[bool] = None, + unity_console: Optional[bool] = None, server_side: Optional[bool] = None, ) -> StreamResponse[GetFeedsRateLimitsResponse]: query_params = build_query_param( @@ -2062,6 +2070,8 @@ def get_feeds_rate_limits( ios=ios, web=web, unity=unity, + unity_desktop=unity_desktop, + unity_console=unity_console, server_side=server_side, ) return self.get( diff --git a/getstream/models/__init__.py b/getstream/models/__init__.py index 86e33507..12d28cd4 100644 --- a/getstream/models/__init__.py +++ b/getstream/models/__init__.py @@ -605,6 +605,18 @@ class ActivityMarkEvent(DataClassJsonMixin): ) +@dataclass +class ActivityMarksConfig(DataClassJsonMixin): + # Whether to return per-activity read status on content feeds + track_read: bool | None = dc_field( + default=None, metadata=dc_config(field_name="track_read") + ) + # Whether to return per-activity seen status on content feeds + track_seen: bool | None = dc_field( + default=None, metadata=dc_config(field_name="track_seen") + ) + + @dataclass class ActivityPinResponse(DataClassJsonMixin): # When the pin was created @@ -672,7 +684,11 @@ class ActivityPinnedEvent(DataClassJsonMixin): @dataclass class ActivityProcessingConfig(DataClassJsonMixin): - # When set, the LLM activity processors may only write interest tags from this list. Tags are matched literally after lower-casing and trimming, so a generic vocabulary matches more often than in-house terms. Mutually exclusive with blocked_tags. + # When true, this feed group's allowed_tags is given to the model as a constrained vocabulary so it maps its own wording onto a configured tag instead of that output being discarded. Improves how often a tag is produced, at the cost of sending the list on every request. Scoped to this group's own list: leaving it false keeps this group's tags out of the request even when another feed group on the same activity sets it true. Requires allowed_tags. Off by default. + send_allowed_tags_to_ai: bool | None = dc_field( + default=None, metadata=dc_config(field_name="send_allowed_tags_to_ai") + ) + # When set, the LLM activity processors may only write interest tags from this list. By default the model is not told about the list, so a tag is only written when the model happens to produce that exact word after lower-casing and trimming, which for any vocabulary is often not the case; set send_allowed_tags_to_ai to have the model choose from the list instead. Mutually exclusive with blocked_tags. allowed_tags: list[str] | None = dc_field( default=None, metadata=dc_config(field_name="allowed_tags") ) @@ -1179,6 +1195,9 @@ class ActivitySelectorConfig(DataClassJsonMixin): sort: "list[SortParamRequest] | None" = dc_field( default=None, metadata=dc_config(field_name="sort") ) + feed_groups: "FeedGroupScope | None" = dc_field( + default=None, metadata=dc_config(field_name="feed_groups") + ) # Filter for activity selection filter: dict[str, object] | None = dc_field( default=None, metadata=dc_config(field_name="filter") @@ -1214,6 +1233,9 @@ class ActivitySelectorConfigResponse(DataClassJsonMixin): sort: "list[SortParamRequest] | None" = dc_field( default=None, metadata=dc_config(field_name="sort") ) + feed_groups: "FeedGroupScope | None" = dc_field( + default=None, metadata=dc_config(field_name="feed_groups") + ) # Filter for activity selection filter: dict[str, object] | None = dc_field( default=None, metadata=dc_config(field_name="filter") @@ -2399,8 +2421,7 @@ class AsyncExportErrorEvent(DataClassJsonMixin): task_id: str = dc_field(metadata=dc_config(field_name="task_id")) custom: dict[str, object] = dc_field(metadata=dc_config(field_name="custom")) type: str = dc_field( - default="export.bulk_image_moderation.error", - metadata=dc_config(field_name="type"), + default="export.users.error", metadata=dc_config(field_name="type") ) received_at: datetime | None = dc_field( default=None, @@ -6118,6 +6139,16 @@ class ChannelBatchUpdateRequest(DataClassJsonMixin): operation: str = dc_field(metadata=dc_config(field_name="operation")) # Filter to apply to the query filter: dict[str, object] = dc_field(metadata=dc_config(field_name="filter")) + # Required with the `addMembersHideHistory` operation, and rejected with every other operation including `addMembers`. Hides each matched channel's history before this time from the members the operation adds. Members that already belong to a matched channel are never affected. Must be in RFC3339 format (e.g., "2024-01-01T10:00:00Z") and in the past. + hide_history_before: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="hide_history_before", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) # `updateData` only. Deletes these keys from each channel's existing custom object, leaving every other custom key untouched. Keys are dot-paths; deleting a key that does not exist is a no-op. Cannot be combined with `data.custom` custom_unset: list[str] | None = dc_field( default=None, metadata=dc_config(field_name="custom_unset") @@ -9789,6 +9820,9 @@ class CreateFeedGroupRequest(DataClassJsonMixin): activity_filter: "ActivityFilterConfig | None" = dc_field( default=None, metadata=dc_config(field_name="activity_filter") ) + activity_marks: "ActivityMarksConfig | None" = dc_field( + default=None, metadata=dc_config(field_name="activity_marks") + ) activity_processing: "ActivityProcessingConfig | None" = dc_field( default=None, metadata=dc_config(field_name="activity_processing") ) @@ -10656,10 +10690,14 @@ class DeleteChannelResponse(DataClassJsonMixin): class DeleteChannelsRequest(DataClassJsonMixin): # All channels that should be deleted cids: list[str] = dc_field(metadata=dc_config(field_name="cids")) - # Specify if channels and all ressources should be hard deleted + # Server-side only. When true, the channels and all their resources are permanently deleted instead of soft-deleted. hard_delete: bool | None = dc_field( default=None, metadata=dc_config(field_name="hard_delete") ) + # Server-side only. When true, the soft delete preserves message history instead of hiding it, so a later recreation of any of these channel IDs restores the full history. Only supported for distinct channels. Cannot be combined with hard_delete. + skip_truncate: bool | None = dc_field( + default=None, metadata=dc_config(field_name="skip_truncate") + ) @dataclass @@ -12171,6 +12209,9 @@ class FeedGroupResponse(DataClassJsonMixin): activity_filter: "ActivityFilterConfig | None" = dc_field( default=None, metadata=dc_config(field_name="activity_filter") ) + activity_marks: "ActivityMarksConfig | None" = dc_field( + default=None, metadata=dc_config(field_name="activity_marks") + ) activity_processing: "ActivityProcessingConfig | None" = dc_field( default=None, metadata=dc_config(field_name="activity_processing") ) @@ -12228,6 +12269,18 @@ class FeedGroupRestoredEvent(DataClassJsonMixin): ) +@dataclass +class FeedGroupScope(DataClassJsonMixin): + # Select activities from every feed group except these. An activity cross-posted to an excluded and a non-excluded group is still selected. Mutually exclusive with include + exclude: list[str] | None = dc_field( + default=None, metadata=dc_config(field_name="exclude") + ) + # Select only activities that live in a feed belonging to one of these feed groups. Mutually exclusive with exclude + include: list[str] | None = dc_field( + default=None, metadata=dc_config(field_name="include") + ) + + @dataclass class FeedInput(DataClassJsonMixin): description: str | None = dc_field( @@ -14673,6 +14726,14 @@ class GetFeedsRateLimitsResponse(DataClassJsonMixin): unity: "dict[str, LimitInfoResponse] | None" = dc_field( default=None, metadata=dc_config(field_name="unity") ) + # Rate limits for Unity console platform (endpoint name -> limit info) + unity_console: "dict[str, LimitInfoResponse] | None" = dc_field( + default=None, metadata=dc_config(field_name="unity_console") + ) + # Rate limits for Unity desktop platform (endpoint name -> limit info) + unity_desktop: "dict[str, LimitInfoResponse] | None" = dc_field( + default=None, metadata=dc_config(field_name="unity_desktop") + ) # Rate limits for Web platform (endpoint name -> limit info) web: "dict[str, LimitInfoResponse] | None" = dc_field( default=None, metadata=dc_config(field_name="web") @@ -14902,6 +14963,9 @@ class GetOrCreateFeedGroupRequest(DataClassJsonMixin): activity_filter: "ActivityFilterConfig | None" = dc_field( default=None, metadata=dc_config(field_name="activity_filter") ) + activity_marks: "ActivityMarksConfig | None" = dc_field( + default=None, metadata=dc_config(field_name="activity_marks") + ) activity_processing: "ActivityProcessingConfig | None" = dc_field( default=None, metadata=dc_config(field_name="activity_processing") ) @@ -15138,6 +15202,14 @@ class GetRateLimitsResponse(DataClassJsonMixin): unity: "dict[str, LimitInfoResponse] | None" = dc_field( default=None, metadata=dc_config(field_name="unity") ) + # Map of endpoint rate limits for the Unity console platform + unity_console: "dict[str, LimitInfoResponse] | None" = dc_field( + default=None, metadata=dc_config(field_name="unity_console") + ) + # Map of endpoint rate limits for the Unity desktop platform + unity_desktop: "dict[str, LimitInfoResponse] | None" = dc_field( + default=None, metadata=dc_config(field_name="unity_desktop") + ) # Map of endpoint rate limits for the web platform web: "dict[str, LimitInfoResponse] | None" = dc_field( default=None, metadata=dc_config(field_name="web") @@ -18659,6 +18731,9 @@ class ModerationDashboardPreferences(DataClassJsonMixin): disable_flagging_reviewed_entity: bool | None = dc_field( default=None, metadata=dc_config(field_name="disable_flagging_reviewed_entity") ) + enforce_shadow_server_side: bool | None = dc_field( + default=None, metadata=dc_config(field_name="enforce_shadow_server_side") + ) escalation_queue_enabled: bool | None = dc_field( default=None, metadata=dc_config(field_name="escalation_queue_enabled") ) @@ -19923,6 +19998,10 @@ class PagerResponse(DataClassJsonMixin): @dataclass class PaginationParams(DataClassJsonMixin): + id_gt: int | None = dc_field(default=None, metadata=dc_config(field_name="id_gt")) + id_gte: int | None = dc_field(default=None, metadata=dc_config(field_name="id_gte")) + id_lt: int | None = dc_field(default=None, metadata=dc_config(field_name="id_lt")) + id_lte: int | None = dc_field(default=None, metadata=dc_config(field_name="id_lte")) limit: int | None = dc_field(default=None, metadata=dc_config(field_name="limit")) offset: int | None = dc_field(default=None, metadata=dc_config(field_name="offset")) @@ -21652,6 +21731,42 @@ class QueryBannedUsersPayload(DataClassJsonMixin): filter_conditions: dict[str, object] = dc_field( metadata=dc_config(field_name="filter_conditions") ) + created_at_after: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="created_at_after", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + created_at_after_or_equal: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="created_at_after_or_equal", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + created_at_before: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="created_at_before", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + created_at_before_or_equal: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="created_at_before_or_equal", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) # Whether to exclude expired bans or not exclude_expired_bans: bool | None = dc_field( default=None, metadata=dc_config(field_name="exclude_expired_bans") @@ -22393,6 +22508,42 @@ class QueryFollowsResponse(DataClassJsonMixin): @dataclass class QueryFutureChannelBansPayload(DataClassJsonMixin): + created_at_after: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="created_at_after", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + created_at_after_or_equal: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="created_at_after_or_equal", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + created_at_before: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="created_at_before", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + created_at_before_or_equal: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="created_at_before_or_equal", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) # Whether to exclude expired bans or not exclude_expired_bans: bool | None = dc_field( default=None, metadata=dc_config(field_name="exclude_expired_bans") @@ -22466,12 +22617,60 @@ class QueryLabelResultsResponse(DataClassJsonMixin): @dataclass class QueryMembersPayload(DataClassJsonMixin): type: str = dc_field(metadata=dc_config(field_name="type")) + created_at_after: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="created_at_after", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + created_at_after_or_equal: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="created_at_after_or_equal", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + created_at_before: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="created_at_before", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + created_at_before_or_equal: datetime | None = dc_field( + default=None, + metadata=dc_config( + field_name="created_at_before_or_equal", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) id: str | None = dc_field(default=None, metadata=dc_config(field_name="id")) limit: int | None = dc_field(default=None, metadata=dc_config(field_name="limit")) offset: int | None = dc_field(default=None, metadata=dc_config(field_name="offset")) user_id: str | None = dc_field( default=None, metadata=dc_config(field_name="user_id") ) + user_id_gt: str | None = dc_field( + default=None, metadata=dc_config(field_name="user_id_gt") + ) + user_id_gte: str | None = dc_field( + default=None, metadata=dc_config(field_name="user_id_gte") + ) + user_id_lt: str | None = dc_field( + default=None, metadata=dc_config(field_name="user_id_lt") + ) + user_id_lte: str | None = dc_field( + default=None, metadata=dc_config(field_name="user_id_lte") + ) members: "list[ChannelMemberRequest] | None" = dc_field( default=None, metadata=dc_config(field_name="members") ) @@ -23125,6 +23324,10 @@ class QueryUsersPayload(DataClassJsonMixin): filter_conditions: dict[str, object] = dc_field( metadata=dc_config(field_name="filter_conditions") ) + id_gt: str | None = dc_field(default=None, metadata=dc_config(field_name="id_gt")) + id_gte: str | None = dc_field(default=None, metadata=dc_config(field_name="id_gte")) + id_lt: str | None = dc_field(default=None, metadata=dc_config(field_name="id_lt")) + id_lte: str | None = dc_field(default=None, metadata=dc_config(field_name="id_lte")) include_deactivated_users: bool | None = dc_field( default=None, metadata=dc_config(field_name="include_deactivated_users") ) @@ -24371,6 +24574,10 @@ class ReviewQueueItemResponse(DataClassJsonMixin): mm_field=fields.DateTime(format="iso"), ), ) + # Highest per-label confidence (0-1) any provider reported across the item's flags; absent when no flag carried one + confidence_score: float | None = dc_field( + default=None, metadata=dc_config(field_name="confidence_score") + ) config_key: str | None = dc_field( default=None, metadata=dc_config(field_name="config_key") ) @@ -24695,6 +24902,9 @@ class RuleBuilderCondition(DataClassJsonMixin): default=None, metadata=dc_config(field_name="user_identical_content_count_params"), ) + user_reaction_count_params: "UserReactionCountRuleParameters | None" = dc_field( + default=None, metadata=dc_config(field_name="user_reaction_count_params") + ) user_role_params: "UserRoleParameters | None" = dc_field( default=None, metadata=dc_config(field_name="user_role_params") ) @@ -24749,6 +24959,9 @@ class RuleBuilderRule(DataClassJsonMixin): @dataclass class RunStats(DataClassJsonMixin): + activities_deleted: int | None = dc_field( + default=None, metadata=dc_config(field_name="activities_deleted") + ) channels_deleted: int | None = dc_field( default=None, metadata=dc_config(field_name="channels_deleted") ) @@ -28824,6 +29037,9 @@ class UpdateFeedGroupRequest(DataClassJsonMixin): activity_filter: "ActivityFilterConfig | None" = dc_field( default=None, metadata=dc_config(field_name="activity_filter") ) + activity_marks: "ActivityMarksConfig | None" = dc_field( + default=None, metadata=dc_config(field_name="activity_marks") + ) activity_processing: "ActivityProcessingConfig | None" = dc_field( default=None, metadata=dc_config(field_name="activity_processing") ) @@ -29492,6 +29708,8 @@ class UpdateUsersRequest(DataClassJsonMixin): class UpdateUsersResponse(DataClassJsonMixin): # Duration of the request in milliseconds duration: str = dc_field(metadata=dc_config(field_name="duration")) + # Deprecated: always empty. Removing a user from a team no longer deletes their memberships in that team's channels, so there is no task to poll + # Deprecated membership_deletion_task_id: str = dc_field( metadata=dc_config(field_name="membership_deletion_task_id") ) @@ -30629,6 +30847,16 @@ class UserRatingReportResponse(DataClassJsonMixin): count: int = dc_field(metadata=dc_config(field_name="count")) +@dataclass +class UserReactionCountRuleParameters(DataClassJsonMixin): + threshold: int | None = dc_field( + default=None, metadata=dc_config(field_name="threshold") + ) + time_window: str | None = dc_field( + default=None, metadata=dc_config(field_name="time_window") + ) + + @dataclass class UserReactivatedEvent(DataClassJsonMixin): # Date/time of creation @@ -31463,6 +31691,24 @@ class WebhookFailoverConfig(DataClassJsonMixin): gcs_path: str | None = dc_field( default=None, metadata=dc_config(field_name="gcs_path") ) + s3_api_key: str | None = dc_field( + default=None, metadata=dc_config(field_name="s3_api_key") + ) + s3_bucket: str | None = dc_field( + default=None, metadata=dc_config(field_name="s3_bucket") + ) + s3_path: str | None = dc_field( + default=None, metadata=dc_config(field_name="s3_path") + ) + s3_region: str | None = dc_field( + default=None, metadata=dc_config(field_name="s3_region") + ) + s3_role_arn: str | None = dc_field( + default=None, metadata=dc_config(field_name="s3_role_arn") + ) + s3_secret: str | None = dc_field( + default=None, metadata=dc_config(field_name="s3_secret") + ) type: str | None = dc_field(default=None, metadata=dc_config(field_name="type")) diff --git a/tests/test_activity_marks_ranking.py b/tests/test_activity_marks_ranking.py new file mode 100644 index 00000000..3d3dbee8 --- /dev/null +++ b/tests/test_activity_marks_ranking.py @@ -0,0 +1,16 @@ +from getstream.models import ActivityMarksConfig, CreateFeedGroupRequest, RankingConfig + + +def test_create_feed_group_serializes_activity_marks_ranking_is_seen(): + request = CreateFeedGroupRequest( + id="timeline", + activity_marks=ActivityMarksConfig(track_seen=True, track_read=True), + ranking=RankingConfig(type="expression", score="is_seen ? 0 : 100"), + ) + + payload = request.to_dict() + + assert payload["activity_marks"]["track_seen"] is True + assert payload["activity_marks"]["track_read"] is True + assert payload["ranking"]["type"] == "expression" + assert payload["ranking"]["score"] == "is_seen ? 0 : 100"