From e3341524c15617cf26946e26a13d2a2321cf963c Mon Sep 17 00:00:00 2001 From: Vishal Narkhede Date: Mon, 19 May 2025 13:39:44 +0200 Subject: [PATCH] added moderation endpoints --- getstream/chat/rest_client.py | 55 +- getstream/common/rest_client.py | 4 + getstream/models/__init__.py | 932 +++++++++++++++++++++++++++- getstream/moderation/rest_client.py | 422 +++++++++++++ uv.lock | 2 +- 5 files changed, 1394 insertions(+), 21 deletions(-) create mode 100644 getstream/moderation/rest_client.py diff --git a/getstream/chat/rest_client.py b/getstream/chat/rest_client.py index 1957ac81..cb070c4e 100644 --- a/getstream/chat/rest_client.py +++ b/getstream/chat/rest_client.py @@ -568,6 +568,7 @@ def truncate_channel( skip_push: Optional[bool] = None, truncated_at: Optional[datetime] = None, user_id: Optional[str] = None, + member_ids: Optional[List[str]] = None, message: Optional[MessageRequest] = None, user: Optional[UserRequest] = None, ) -> StreamResponse[TruncateChannelResponse]: @@ -580,6 +581,7 @@ def truncate_channel( skip_push=skip_push, truncated_at=truncated_at, user_id=user_id, + member_ids=member_ids, message=message, user=user, ) @@ -930,12 +932,18 @@ def get_message( ) def update_message( - self, id: str, message: MessageRequest, skip_enrich_url: Optional[bool] = None + self, + id: str, + message: MessageRequest, + skip_enrich_url: Optional[bool] = None, + skip_push: Optional[bool] = None, ) -> StreamResponse[UpdateMessageResponse]: path_params = { "id": id, } - json = build_body_dict(message=message, skip_enrich_url=skip_enrich_url) + json = build_body_dict( + message=message, skip_enrich_url=skip_enrich_url, skip_push=skip_push + ) return self.post( "/api/v2/chat/messages/{id}", @@ -1105,12 +1113,18 @@ def translate_message( ) def undelete_message( - self, id: str, message: MessageRequest, skip_enrich_url: Optional[bool] = None + self, + id: str, + message: MessageRequest, + skip_enrich_url: Optional[bool] = None, + skip_push: Optional[bool] = None, ) -> StreamResponse[UpdateMessageResponse]: path_params = { "id": id, } - json = build_body_dict(message=message, skip_enrich_url=skip_enrich_url) + json = build_body_dict( + message=message, skip_enrich_url=skip_enrich_url, skip_push=skip_push + ) return self.post( "/api/v2/chat/messages/{id}/undelete", @@ -1493,6 +1507,39 @@ def update_push_notification_preferences( "/api/v2/chat/push_preferences", UpsertPushPreferencesResponse, json=json ) + def get_push_templates( + self, push_provider_type: str, push_provider_name: Optional[str] = None + ) -> StreamResponse[GetPushTemplatesResponse]: + query_params = build_query_param( + push_provider_type=push_provider_type, push_provider_name=push_provider_name + ) + + return self.get( + "/api/v2/chat/push_templates", + GetPushTemplatesResponse, + query_params=query_params, + ) + + def upsert_push_template( + self, + event_type: str, + push_provider_type: str, + enable_push: Optional[bool] = None, + push_provider_name: Optional[str] = None, + template: Optional[str] = None, + ) -> StreamResponse[UpsertPushTemplateResponse]: + json = build_body_dict( + event_type=event_type, + push_provider_type=push_provider_type, + enable_push=enable_push, + push_provider_name=push_provider_name, + template=template, + ) + + return self.post( + "/api/v2/chat/push_templates", UpsertPushTemplateResponse, json=json + ) + def query_banned_users( self, payload: Optional[QueryBannedUsersPayload] = None ) -> StreamResponse[QueryBannedUsersResponse]: diff --git a/getstream/common/rest_client.py b/getstream/common/rest_client.py index 5dca77c3..7ce3a49e 100644 --- a/getstream/common/rest_client.py +++ b/getstream/common/rest_client.py @@ -67,6 +67,9 @@ def update_app( grants: Optional[Dict[str, List[str]]] = None, huawei_config: Optional[HuaweiConfig] = None, image_upload_config: Optional[FileUploadConfig] = None, + moderation_dashboard_preferences: Optional[ + ModerationDashboardPreferences + ] = None, push_config: Optional[PushConfig] = None, xiaomi_config: Optional[XiaomiConfig] = None, ) -> StreamResponse[Response]: @@ -112,6 +115,7 @@ def update_app( grants=grants, huawei_config=huawei_config, image_upload_config=image_upload_config, + moderation_dashboard_preferences=moderation_dashboard_preferences, push_config=push_config, xiaomi_config=xiaomi_config, ) diff --git a/getstream/models/__init__.py b/getstream/models/__init__.py index 5e201c92..c85174a4 100644 --- a/getstream/models/__init__.py +++ b/getstream/models/__init__.py @@ -93,9 +93,6 @@ class APNConfig(DataClassJsonMixin): class APNConfigFields(DataClassJsonMixin): development: bool = dc_field(metadata=dc_config(field_name="development")) enabled: bool = dc_field(metadata=dc_config(field_name="enabled")) - notification_template: str = dc_field( - metadata=dc_config(field_name="notification_template") - ) auth_key: Optional[str] = dc_field( default=None, metadata=dc_config(field_name="auth_key") ) @@ -109,6 +106,9 @@ class APNConfigFields(DataClassJsonMixin): key_id: Optional[str] = dc_field( default=None, metadata=dc_config(field_name="key_id") ) + notification_template: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="notification_template") + ) p12_cert: Optional[str] = dc_field( default=None, metadata=dc_config(field_name="p12_cert") ) @@ -121,6 +121,18 @@ class APNConfigFields(DataClassJsonMixin): class APNS(DataClassJsonMixin): body: str = dc_field(metadata=dc_config(field_name="body")) title: str = dc_field(metadata=dc_config(field_name="title")) + content_available: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="content-available") + ) + mutable_content: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="mutable-content") + ) + sound: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="sound") + ) + data: Optional[Dict[str, object]] = dc_field( + default=None, metadata=dc_config(field_name="data") + ) @dataclass @@ -323,6 +335,56 @@ class AppResponseFields(DataClassJsonMixin): datadog_info: "Optional[DataDogInfo]" = dc_field( default=None, metadata=dc_config(field_name="datadog_info") ) + moderation_dashboard_preferences: "Optional[ModerationDashboardPreferences]" = ( + dc_field( + default=None, + metadata=dc_config(field_name="moderation_dashboard_preferences"), + ) + ) + + +@dataclass +class AsyncBulkImageModerationEvent(DataClassJsonMixin): + created_at: datetime = dc_field( + metadata=dc_config( + field_name="created_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + finished_at: datetime = dc_field( + metadata=dc_config( + field_name="finished_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + started_at: datetime = dc_field( + metadata=dc_config( + field_name="started_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + task_id: str = dc_field(metadata=dc_config(field_name="task_id")) + url: str = dc_field(metadata=dc_config(field_name="url")) + custom: Dict[str, object] = dc_field(metadata=dc_config(field_name="custom")) + type: str = dc_field( + default="export.bulk_image_moderation.success", + metadata=dc_config(field_name="type"), + ) + received_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="received_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) @dataclass @@ -786,6 +848,9 @@ class BanActionRequest(DataClassJsonMixin): channel_ban_only: Optional[bool] = dc_field( default=None, metadata=dc_config(field_name="channel_ban_only") ) + delete_messages: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="delete_messages") + ) ip_ban: Optional[bool] = dc_field( default=None, metadata=dc_config(field_name="ip_ban") ) @@ -809,6 +874,9 @@ class BanRequest(DataClassJsonMixin): channel_cid: Optional[str] = dc_field( default=None, metadata=dc_config(field_name="channel_cid") ) + delete_messages: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="delete_messages") + ) ip_ban: Optional[bool] = dc_field( default=None, metadata=dc_config(field_name="ip_ban") ) @@ -1047,6 +1115,128 @@ class BrowserDataResponse(DataClassJsonMixin): ) +@dataclass +class BulkImageModerationRequest(DataClassJsonMixin): + csv_file: str = dc_field(metadata=dc_config(field_name="csv_file")) + + +@dataclass +class BulkImageModerationResponse(DataClassJsonMixin): + duration: str = dc_field(metadata=dc_config(field_name="duration")) + task_id: str = dc_field(metadata=dc_config(field_name="task_id")) + + +@dataclass +class Call(DataClassJsonMixin): + app_pk: int = dc_field(metadata=dc_config(field_name="AppPK")) + backstage: bool = dc_field(metadata=dc_config(field_name="Backstage")) + channel_cid: str = dc_field(metadata=dc_config(field_name="ChannelCID")) + cid: str = dc_field(metadata=dc_config(field_name="CID")) + created_at: datetime = dc_field( + metadata=dc_config( + field_name="CreatedAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + created_by_user_id: str = dc_field(metadata=dc_config(field_name="CreatedByUserID")) + current_session_id: str = dc_field( + metadata=dc_config(field_name="CurrentSessionID") + ) + id: str = dc_field(metadata=dc_config(field_name="ID")) + last_session_id: str = dc_field(metadata=dc_config(field_name="LastSessionID")) + team: str = dc_field(metadata=dc_config(field_name="Team")) + thumbnail_url: str = dc_field(metadata=dc_config(field_name="ThumbnailURL")) + type: str = dc_field(metadata=dc_config(field_name="Type")) + updated_at: datetime = dc_field( + metadata=dc_config( + field_name="UpdatedAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + blocked_user_i_ds: List[str] = dc_field( + metadata=dc_config(field_name="BlockedUserIDs") + ) + blocked_users: "List[User]" = dc_field( + metadata=dc_config(field_name="BlockedUsers") + ) + egresses: "List[CallEgress]" = dc_field(metadata=dc_config(field_name="Egresses")) + members: "List[CallMember]" = dc_field(metadata=dc_config(field_name="Members")) + custom: Dict[str, object] = dc_field(metadata=dc_config(field_name="Custom")) + deleted_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="DeletedAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + egress_updated_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="EgressUpdatedAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + ended_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="EndedAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + join_ahead_time_seconds: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="JoinAheadTimeSeconds") + ) + last_heartbeat_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="LastHeartbeatAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + member_count: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="MemberCount") + ) + starts_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="StartsAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + call_type: "Optional[CallType]" = dc_field( + default=None, metadata=dc_config(field_name="CallType") + ) + created_by: "Optional[User]" = dc_field( + default=None, metadata=dc_config(field_name="CreatedBy") + ) + member_lookup: "Optional[MemberLookup]" = dc_field( + default=None, metadata=dc_config(field_name="MemberLookup") + ) + session: "Optional[CallSession]" = dc_field( + default=None, metadata=dc_config(field_name="Session") + ) + settings: "Optional[CallSettings]" = dc_field( + default=None, metadata=dc_config(field_name="Settings") + ) + settings_overrides: "Optional[CallSettings]" = dc_field( + default=None, metadata=dc_config(field_name="SettingsOverrides") + ) + + @dataclass class CallAcceptedEvent(DataClassJsonMixin): call_cid: str = dc_field(metadata=dc_config(field_name="call_cid")) @@ -1179,6 +1369,45 @@ class CallDurationReportResponse(DataClassJsonMixin): ) +@dataclass +class CallEgress(DataClassJsonMixin): + app_pk: int = dc_field(metadata=dc_config(field_name="app_pk")) + call_id: str = dc_field(metadata=dc_config(field_name="call_id")) + call_type: str = dc_field(metadata=dc_config(field_name="call_type")) + egress_id: str = dc_field(metadata=dc_config(field_name="egress_id")) + egress_type: str = dc_field(metadata=dc_config(field_name="egress_type")) + instance_ip: str = dc_field(metadata=dc_config(field_name="instance_ip")) + started_at: datetime = dc_field( + metadata=dc_config( + field_name="started_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + state: str = dc_field(metadata=dc_config(field_name="state")) + updated_at: datetime = dc_field( + metadata=dc_config( + field_name="updated_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + stopped_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="stopped_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + config: "Optional[EgressTaskConfig]" = dc_field( + default=None, metadata=dc_config(field_name="config") + ) + + @dataclass class CallEndedEvent(DataClassJsonMixin): call_cid: str = dc_field(metadata=dc_config(field_name="call_cid")) @@ -1192,6 +1421,9 @@ class CallEndedEvent(DataClassJsonMixin): ) call: "CallResponse" = dc_field(metadata=dc_config(field_name="call")) type: str = dc_field(default="call.ended", metadata=dc_config(field_name="type")) + reason: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="reason") + ) user: "Optional[UserResponse]" = dc_field( default=None, metadata=dc_config(field_name="user") ) @@ -1352,6 +1584,41 @@ class CallLiveStartedEvent(DataClassJsonMixin): ) +@dataclass +class CallMember(DataClassJsonMixin): + created_at: datetime = dc_field( + metadata=dc_config( + field_name="created_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + role: str = dc_field(metadata=dc_config(field_name="role")) + updated_at: datetime = dc_field( + metadata=dc_config( + field_name="updated_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + user_id: str = dc_field(metadata=dc_config(field_name="user_id")) + custom: Dict[str, object] = dc_field(metadata=dc_config(field_name="custom")) + deleted_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="deleted_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + user: "Optional[User]" = dc_field( + default=None, metadata=dc_config(field_name="user") + ) + + @dataclass class CallMemberAddedEvent(DataClassJsonMixin): call_cid: str = dc_field(metadata=dc_config(field_name="call_cid")) @@ -1466,6 +1733,110 @@ class CallNotificationEvent(DataClassJsonMixin): ) +@dataclass +class CallParticipant(DataClassJsonMixin): + banned: bool = dc_field(metadata=dc_config(field_name="banned")) + id: str = dc_field(metadata=dc_config(field_name="id")) + joined_at: datetime = dc_field( + metadata=dc_config( + field_name="JoinedAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + online: bool = dc_field(metadata=dc_config(field_name="online")) + role: str = dc_field(metadata=dc_config(field_name="Role")) + role: str = dc_field(metadata=dc_config(field_name="role")) + user_session_id: str = dc_field(metadata=dc_config(field_name="UserSessionID")) + custom: Dict[str, object] = dc_field(metadata=dc_config(field_name="custom")) + teams_role: "Dict[str, str]" = dc_field(metadata=dc_config(field_name="teams_role")) + ban_expires: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="ban_expires", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + created_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="created_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + deactivated_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="deactivated_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + deleted_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="deleted_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + invisible: Optional[bool] = dc_field( + default=None, metadata=dc_config(field_name="invisible") + ) + language: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="language") + ) + last_active: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="last_active", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + last_engaged_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="last_engaged_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + revoke_tokens_issued_before: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="revoke_tokens_issued_before", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + updated_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="updated_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + teams: Optional[List[str]] = dc_field( + default=None, metadata=dc_config(field_name="teams") + ) + privacy_settings: "Optional[PrivacySettings]" = dc_field( + default=None, metadata=dc_config(field_name="privacy_settings") + ) + + @dataclass class CallParticipantCountReport(DataClassJsonMixin): histogram: "List[ReportByHistogramBucket]" = dc_field( @@ -1824,6 +2195,125 @@ class CallRtmpBroadcastStoppedEvent(DataClassJsonMixin): ) +@dataclass +class CallSession(DataClassJsonMixin): + anonymous_participant_count: int = dc_field( + metadata=dc_config(field_name="AnonymousParticipantCount") + ) + app_pk: int = dc_field(metadata=dc_config(field_name="AppPK")) + call_id: str = dc_field(metadata=dc_config(field_name="CallID")) + call_type: str = dc_field(metadata=dc_config(field_name="CallType")) + created_at: datetime = dc_field( + metadata=dc_config( + field_name="CreatedAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + session_id: str = dc_field(metadata=dc_config(field_name="SessionID")) + active_sf_us: "List[SFUIDLastSeen]" = dc_field( + metadata=dc_config(field_name="ActiveSFUs") + ) + participants: "List[CallParticipant]" = dc_field( + metadata=dc_config(field_name="Participants") + ) + sfui_ds: List[str] = dc_field(metadata=dc_config(field_name="SFUIDs")) + accepted_by: "Dict[str, datetime]" = dc_field( + metadata=dc_config( + field_name="AcceptedBy", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + missed_by: "Dict[str, datetime]" = dc_field( + metadata=dc_config( + field_name="MissedBy", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + participants_count_by_role: "Dict[str, int]" = dc_field( + metadata=dc_config(field_name="ParticipantsCountByRole") + ) + rejected_by: "Dict[str, datetime]" = dc_field( + metadata=dc_config( + field_name="RejectedBy", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + user_permission_overrides: "Dict[str, Dict[str, bool]]" = dc_field( + metadata=dc_config(field_name="UserPermissionOverrides") + ) + deleted_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="DeletedAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + ended_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="EndedAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + live_ended_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="LiveEndedAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + live_started_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="LiveStartedAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + ring_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="RingAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + started_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="StartedAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + timer_ends_at: Optional[datetime] = dc_field( + default=None, + metadata=dc_config( + field_name="TimerEndsAt", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ), + ) + + @dataclass class CallSessionEndedEvent(DataClassJsonMixin): call_cid: str = dc_field(metadata=dc_config(field_name="call_cid")) @@ -2175,6 +2665,7 @@ class CallTranscription(DataClassJsonMixin): ) ) filename: str = dc_field(metadata=dc_config(field_name="filename")) + session_id: str = dc_field(metadata=dc_config(field_name="session_id")) start_time: datetime = dc_field( metadata=dc_config( field_name="start_time", @@ -3919,6 +4410,14 @@ class CommitMessageRequest(DataClassJsonMixin): pass +@dataclass +class CompositeAppSettings(DataClassJsonMixin): + json_encoded_settings: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="json_encoded_settings") + ) + url: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="url")) + + @dataclass class ConfigOverrides(DataClassJsonMixin): commands: List[str] = dc_field(metadata=dc_config(field_name="commands")) @@ -4884,14 +5383,43 @@ class EgressRTMPResponse(DataClassJsonMixin): @dataclass -class EgressResponse(DataClassJsonMixin): - broadcasting: bool = dc_field(metadata=dc_config(field_name="broadcasting")) - rtmps: "List[EgressRTMPResponse]" = dc_field(metadata=dc_config(field_name="rtmps")) - frame_recording: "Optional[FrameRecordingResponse]" = dc_field( - default=None, metadata=dc_config(field_name="frame_recording") - ) - hls: "Optional[EgressHLSResponse]" = dc_field( - default=None, metadata=dc_config(field_name="hls") +class EgressResponse(DataClassJsonMixin): + broadcasting: bool = dc_field(metadata=dc_config(field_name="broadcasting")) + rtmps: "List[EgressRTMPResponse]" = dc_field(metadata=dc_config(field_name="rtmps")) + frame_recording: "Optional[FrameRecordingResponse]" = dc_field( + default=None, metadata=dc_config(field_name="frame_recording") + ) + hls: "Optional[EgressHLSResponse]" = dc_field( + default=None, metadata=dc_config(field_name="hls") + ) + + +@dataclass +class EgressTaskConfig(DataClassJsonMixin): + egress_user: "Optional[EgressUser]" = dc_field( + default=None, metadata=dc_config(field_name="egress_user") + ) + frame_recording_egress_config: "Optional[FrameRecordingEgressConfig]" = dc_field( + default=None, metadata=dc_config(field_name="frame_recording_egress_config") + ) + hls_egress_config: "Optional[HLSEgressConfig]" = dc_field( + default=None, metadata=dc_config(field_name="hls_egress_config") + ) + recording_egress_config: "Optional[RecordingEgressConfig]" = dc_field( + default=None, metadata=dc_config(field_name="recording_egress_config") + ) + rtmp_egress_config: "Optional[RTMPEgressConfig]" = dc_field( + default=None, metadata=dc_config(field_name="rtmp_egress_config") + ) + stt_egress_config: "Optional[STTEgressConfig]" = dc_field( + default=None, metadata=dc_config(field_name="stt_egress_config") + ) + + +@dataclass +class EgressUser(DataClassJsonMixin): + token: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="token") ) @@ -5187,6 +5715,7 @@ class ErrorResult(DataClassJsonMixin): class EventNotificationSettings(DataClassJsonMixin): enabled: bool = dc_field(metadata=dc_config(field_name="enabled")) apns: "APNS" = dc_field(metadata=dc_config(field_name="apns")) + fcm: "FCM" = dc_field(metadata=dc_config(field_name="fcm")) @dataclass @@ -5265,6 +5794,47 @@ class ExportUsersResponse(DataClassJsonMixin): task_id: str = dc_field(metadata=dc_config(field_name="task_id")) +@dataclass +class ExternalStorage(DataClassJsonMixin): + abs_account_name: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="abs_account_name") + ) + abs_client_id: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="abs_client_id") + ) + abs_client_secret: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="abs_client_secret") + ) + abs_tenant_id: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="abs_tenant_id") + ) + bucket: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="bucket") + ) + gcs_credentials: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="gcs_credentials") + ) + path: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="path")) + s3_api_key: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="s3_api_key") + ) + s3_custom_endpoint: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="s3_custom_endpoint") + ) + s3_region: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="s3_region") + ) + s3_secret_key: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="s3_secret_key") + ) + storage_name: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="storage_name") + ) + storage_type: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="storage_type") + ) + + @dataclass class ExternalStorageResponse(DataClassJsonMixin): bucket: str = dc_field(metadata=dc_config(field_name="bucket")) @@ -5273,6 +5843,13 @@ class ExternalStorageResponse(DataClassJsonMixin): type: str = dc_field(metadata=dc_config(field_name="type")) +@dataclass +class FCM(DataClassJsonMixin): + data: Optional[Dict[str, object]] = dc_field( + default=None, metadata=dc_config(field_name="data") + ) + + @dataclass class FeedsModerationTemplateConfig(DataClassJsonMixin): config_key: str = dc_field(metadata=dc_config(field_name="config_key")) @@ -5344,15 +5921,19 @@ class FirebaseConfig(DataClassJsonMixin): @dataclass class FirebaseConfigFields(DataClassJsonMixin): - apn_template: str = dc_field(metadata=dc_config(field_name="apn_template")) - data_template: str = dc_field(metadata=dc_config(field_name="data_template")) enabled: bool = dc_field(metadata=dc_config(field_name="enabled")) - notification_template: str = dc_field( - metadata=dc_config(field_name="notification_template") + apn_template: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="apn_template") ) credentials_json: Optional[str] = dc_field( default=None, metadata=dc_config(field_name="credentials_json") ) + data_template: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="data_template") + ) + notification_template: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="notification_template") + ) server_key: Optional[str] = dc_field( default=None, metadata=dc_config(field_name="server_key") ) @@ -5384,6 +5965,9 @@ class Flag(DataClassJsonMixin): entity_creator_id: Optional[str] = dc_field( default=None, metadata=dc_config(field_name="entity_creator_id") ) + is_streamed_content: Optional[bool] = dc_field( + default=None, metadata=dc_config(field_name="is_streamed_content") + ) moderation_payload_hash: Optional[str] = dc_field( default=None, metadata=dc_config(field_name="moderation_payload_hash") ) @@ -5403,6 +5987,9 @@ class Flag(DataClassJsonMixin): moderation_payload: "Optional[ModerationPayload]" = dc_field( default=None, metadata=dc_config(field_name="moderation_payload") ) + review_queue_item: "Optional[ReviewQueueItem]" = dc_field( + default=None, metadata=dc_config(field_name="review_queue_item") + ) user: "Optional[User]" = dc_field( default=None, metadata=dc_config(field_name="user") ) @@ -5520,6 +6107,22 @@ class FrameRecordSettings(DataClassJsonMixin): ) +@dataclass +class FrameRecordingEgressConfig(DataClassJsonMixin): + capture_interval_in_seconds: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="capture_interval_in_seconds") + ) + storage_name: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="storage_name") + ) + external_storage: "Optional[ExternalStorage]" = dc_field( + default=None, metadata=dc_config(field_name="external_storage") + ) + quality: "Optional[Quality]" = dc_field( + default=None, metadata=dc_config(field_name="quality") + ) + + @dataclass class FrameRecordingResponse(DataClassJsonMixin): status: str = dc_field(metadata=dc_config(field_name="status")) @@ -6019,6 +6622,14 @@ class GetOrCreateCallResponse(DataClassJsonMixin): call: "CallResponse" = dc_field(metadata=dc_config(field_name="call")) +@dataclass +class GetPushTemplatesResponse(DataClassJsonMixin): + duration: str = dc_field(metadata=dc_config(field_name="duration")) + templates: "List[PushTemplate]" = dc_field( + metadata=dc_config(field_name="templates") + ) + + @dataclass class GetRateLimitsResponse(DataClassJsonMixin): duration: str = dc_field(metadata=dc_config(field_name="duration")) @@ -6142,6 +6753,22 @@ class GroupedStatsResponse(DataClassJsonMixin): unique: int = dc_field(metadata=dc_config(field_name="unique")) +@dataclass +class HLSEgressConfig(DataClassJsonMixin): + playlist_url: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="playlist_url") + ) + start_unix_nano: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="start_unix_nano") + ) + qualities: "Optional[List[Quality]]" = dc_field( + default=None, metadata=dc_config(field_name="qualities") + ) + composite_app_settings: "Optional[CompositeAppSettings]" = dc_field( + default=None, metadata=dc_config(field_name="composite_app_settings") + ) + + @dataclass class HLSSettings(DataClassJsonMixin): auto_on: bool = dc_field(metadata=dc_config(field_name="auto_on")) @@ -6603,6 +7230,11 @@ class MemberAddedEvent(DataClassJsonMixin): ) +@dataclass +class MemberLookup(DataClassJsonMixin): + limit: int = dc_field(metadata=dc_config(field_name="Limit")) + + @dataclass class MemberRemovedEvent(DataClassJsonMixin): channel_id: str = dc_field(metadata=dc_config(field_name="channel_id")) @@ -7070,7 +7702,9 @@ class MessageNewEvent(DataClassJsonMixin): ) ) watcher_count: int = dc_field(metadata=dc_config(field_name="watcher_count")) - type: str = dc_field(default="message.new", metadata=dc_config(field_name="type")) + type: str = dc_field( + default="notification.thread_message_new", metadata=dc_config(field_name="type") + ) team: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="team")) thread_participants: "Optional[List[User]]" = dc_field( default=None, metadata=dc_config(field_name="thread_participants") @@ -7627,6 +8261,50 @@ class ModerationCustomActionEvent(DataClassJsonMixin): ) +@dataclass +class ModerationDashboardPreferences(DataClassJsonMixin): + media_queue_blur_enabled: Optional[bool] = dc_field( + default=None, metadata=dc_config(field_name="media_queue_blur_enabled") + ) + + +@dataclass +class ModerationFlagResponse(DataClassJsonMixin): + created_at: str = dc_field(metadata=dc_config(field_name="created_at")) + entity_id: str = dc_field(metadata=dc_config(field_name="entity_id")) + entity_type: str = dc_field(metadata=dc_config(field_name="entity_type")) + id: str = dc_field(metadata=dc_config(field_name="id")) + type: str = dc_field(metadata=dc_config(field_name="type")) + updated_at: str = dc_field(metadata=dc_config(field_name="updated_at")) + entity_creator_id: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="entity_creator_id") + ) + reason: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="reason") + ) + review_queue_item_id: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="review_queue_item_id") + ) + labels: Optional[List[str]] = dc_field( + default=None, metadata=dc_config(field_name="labels") + ) + result: "Optional[List[Dict[str, object]]]" = dc_field( + default=None, metadata=dc_config(field_name="result") + ) + custom: Optional[Dict[str, object]] = dc_field( + default=None, metadata=dc_config(field_name="custom") + ) + moderation_payload: "Optional[ModerationPayload]" = dc_field( + default=None, metadata=dc_config(field_name="moderation_payload") + ) + review_queue_item: "Optional[ReviewQueueItem]" = dc_field( + default=None, metadata=dc_config(field_name="review_queue_item") + ) + user: "Optional[UserResponse]" = dc_field( + default=None, metadata=dc_config(field_name="user") + ) + + @dataclass class ModerationFlaggedEvent(DataClassJsonMixin): created_at: datetime = dc_field( @@ -8776,6 +9454,9 @@ class PushProvider(DataClassJsonMixin): xiaomi_package_name: Optional[str] = dc_field( default=None, metadata=dc_config(field_name="xiaomi_package_name") ) + push_templates: "Optional[List[PushTemplate]]" = dc_field( + default=None, metadata=dc_config(field_name="push_templates") + ) @dataclass @@ -8878,6 +9559,51 @@ class PushProviderResponse(DataClassJsonMixin): ) +@dataclass +class PushTemplate(DataClassJsonMixin): + created_at: datetime = dc_field( + metadata=dc_config( + field_name="created_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + enable_push: bool = dc_field(metadata=dc_config(field_name="enable_push")) + event_type: str = dc_field(metadata=dc_config(field_name="event_type")) + updated_at: datetime = dc_field( + metadata=dc_config( + field_name="updated_at", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + template: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="template") + ) + + +@dataclass +class Quality(DataClassJsonMixin): + bitdepth: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="bitdepth") + ) + framerate: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="framerate") + ) + height: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="height") + ) + name: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="name")) + video_bitrate: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="video_bitrate") + ) + width: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="width") + ) + + @dataclass class QualityScoreReport(DataClassJsonMixin): histogram: "List[ReportByHistogramBucket]" = dc_field( @@ -9298,6 +10024,31 @@ class QueryModerationConfigsResponse(DataClassJsonMixin): prev: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="prev")) +@dataclass +class QueryModerationFlagsRequest(DataClassJsonMixin): + limit: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="limit") + ) + next: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="next")) + prev: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="prev")) + sort: "Optional[List[SortParam]]" = dc_field( + default=None, metadata=dc_config(field_name="sort") + ) + filter: Optional[Dict[str, object]] = dc_field( + default=None, metadata=dc_config(field_name="filter") + ) + + +@dataclass +class QueryModerationFlagsResponse(DataClassJsonMixin): + duration: str = dc_field(metadata=dc_config(field_name="duration")) + flags: "List[ModerationFlagResponse]" = dc_field( + metadata=dc_config(field_name="flags") + ) + next: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="next")) + prev: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="prev")) + + @dataclass class QueryModerationLogsRequest(DataClassJsonMixin): limit: Optional[int] = dc_field( @@ -9605,6 +10356,19 @@ class RTMPBroadcastRequest(DataClassJsonMixin): ) +@dataclass +class RTMPEgressConfig(DataClassJsonMixin): + rtmp_location: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="rtmp_location") + ) + composite_app_settings: "Optional[CompositeAppSettings]" = dc_field( + default=None, metadata=dc_config(field_name="composite_app_settings") + ) + quality: "Optional[Quality]" = dc_field( + default=None, metadata=dc_config(field_name="quality") + ) + + @dataclass class RTMPIngress(DataClassJsonMixin): address: str = dc_field(metadata=dc_config(field_name="address")) @@ -9952,6 +10716,28 @@ class RecordSettingsResponse(DataClassJsonMixin): layout: "LayoutSettingsResponse" = dc_field(metadata=dc_config(field_name="layout")) +@dataclass +class RecordingEgressConfig(DataClassJsonMixin): + audio_only: Optional[bool] = dc_field( + default=None, metadata=dc_config(field_name="audio_only") + ) + storage_name: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="storage_name") + ) + composite_app_settings: "Optional[CompositeAppSettings]" = dc_field( + default=None, metadata=dc_config(field_name="composite_app_settings") + ) + external_storage: "Optional[ExternalStorage]" = dc_field( + default=None, metadata=dc_config(field_name="external_storage") + ) + quality: "Optional[Quality]" = dc_field( + default=None, metadata=dc_config(field_name="quality") + ) + video_orientation_hint: "Optional[VideoOrientation]" = dc_field( + default=None, metadata=dc_config(field_name="video_orientation_hint") + ) + + @dataclass class ReportByHistogramBucket(DataClassJsonMixin): category: str = dc_field(metadata=dc_config(field_name="category")) @@ -10041,6 +10827,9 @@ class ReviewQueueItem(DataClassJsonMixin): assigned_to: "Optional[User]" = dc_field( default=None, metadata=dc_config(field_name="assigned_to") ) + call: "Optional[Call]" = dc_field( + default=None, metadata=dc_config(field_name="call") + ) entity_creator: "Optional[EntityCreator]" = dc_field( default=None, metadata=dc_config(field_name="entity_creator") ) @@ -10163,6 +10952,9 @@ class ReviewQueueItemResponse(DataClassJsonMixin): assigned_to: "Optional[UserResponse]" = dc_field( default=None, metadata=dc_config(field_name="assigned_to") ) + call: "Optional[CallResponse]" = dc_field( + default=None, metadata=dc_config(field_name="call") + ) entity_creator: "Optional[EntityCreatorResponse]" = dc_field( default=None, metadata=dc_config(field_name="entity_creator") ) @@ -10368,6 +11160,50 @@ class SDKUsageReportResponse(DataClassJsonMixin): ) +@dataclass +class SFUIDLastSeen(DataClassJsonMixin): + id: str = dc_field(metadata=dc_config(field_name="id")) + last_seen: datetime = dc_field( + metadata=dc_config( + field_name="last_seen", + encoder=encode_datetime, + decoder=datetime_from_unix_ns, + mm_field=fields.DateTime(format="iso"), + ) + ) + process_start_time: int = dc_field( + metadata=dc_config(field_name="process_start_time") + ) + + +@dataclass +class STTEgressConfig(DataClassJsonMixin): + closed_captions_enabled: Optional[bool] = dc_field( + default=None, metadata=dc_config(field_name="closed_captions_enabled") + ) + language: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="language") + ) + storage_name: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="storage_name") + ) + translations_enabled: Optional[bool] = dc_field( + default=None, metadata=dc_config(field_name="translations_enabled") + ) + upload_transcriptions: Optional[bool] = dc_field( + default=None, metadata=dc_config(field_name="upload_transcriptions") + ) + whisper_server_base_url: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="whisper_server_base_url") + ) + translation_languages: Optional[List[str]] = dc_field( + default=None, metadata=dc_config(field_name="translation_languages") + ) + external_storage: "Optional[ExternalStorage]" = dc_field( + default=None, metadata=dc_config(field_name="external_storage") + ) + + @dataclass class ScreensharingSettings(DataClassJsonMixin): access_request_enabled: bool = dc_field( @@ -10818,6 +11654,16 @@ class ShowChannelResponse(DataClassJsonMixin): duration: str = dc_field(metadata=dc_config(field_name="duration")) +@dataclass +class SortParam(DataClassJsonMixin): + direction: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="direction") + ) + field: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="field") + ) + + @dataclass class SortParamRequest(DataClassJsonMixin): direction: Optional[int] = dc_field( @@ -11427,6 +12273,9 @@ class TruncateChannelRequest(DataClassJsonMixin): user_id: Optional[str] = dc_field( default=None, metadata=dc_config(field_name="user_id") ) + member_ids: Optional[List[str]] = dc_field( + default=None, metadata=dc_config(field_name="member_ids") + ) message: "Optional[MessageRequest]" = dc_field( default=None, metadata=dc_config(field_name="message") ) @@ -11775,6 +12624,12 @@ class UpdateAppRequest(DataClassJsonMixin): image_upload_config: "Optional[FileUploadConfig]" = dc_field( default=None, metadata=dc_config(field_name="image_upload_config") ) + moderation_dashboard_preferences: "Optional[ModerationDashboardPreferences]" = ( + dc_field( + default=None, + metadata=dc_config(field_name="moderation_dashboard_preferences"), + ) + ) push_config: "Optional[PushConfig]" = dc_field( default=None, metadata=dc_config(field_name="push_config") ) @@ -12237,6 +13092,9 @@ class UpdateMessageRequest(DataClassJsonMixin): skip_enrich_url: Optional[bool] = dc_field( default=None, metadata=dc_config(field_name="skip_enrich_url") ) + skip_push: Optional[bool] = dc_field( + default=None, metadata=dc_config(field_name="skip_push") + ) @dataclass @@ -12539,6 +13397,31 @@ class UpsertPushProviderResponse(DataClassJsonMixin): ) +@dataclass +class UpsertPushTemplateRequest(DataClassJsonMixin): + event_type: str = dc_field(metadata=dc_config(field_name="event_type")) + push_provider_type: str = dc_field( + metadata=dc_config(field_name="push_provider_type") + ) + enable_push: Optional[bool] = dc_field( + default=None, metadata=dc_config(field_name="enable_push") + ) + push_provider_name: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="push_provider_name") + ) + template: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="template") + ) + + +@dataclass +class UpsertPushTemplateResponse(DataClassJsonMixin): + duration: str = dc_field(metadata=dc_config(field_name="duration")) + template: "Optional[PushTemplate]" = dc_field( + default=None, metadata=dc_config(field_name="template") + ) + + @dataclass class User(DataClassJsonMixin): banned: bool = dc_field(metadata=dc_config(field_name="banned")) @@ -13295,6 +14178,23 @@ class VelocityFilterConfigRule(DataClassJsonMixin): ) +@dataclass +class VideoEndCallRequest(DataClassJsonMixin): + pass + + +@dataclass +class VideoKickUserRequest(DataClassJsonMixin): + pass + + +@dataclass +class VideoOrientation(DataClassJsonMixin): + orientation: Optional[int] = dc_field( + default=None, metadata=dc_config(field_name="orientation") + ) + + @dataclass class VideoSettings(DataClassJsonMixin): access_request_enabled: bool = dc_field( diff --git a/getstream/moderation/rest_client.py b/getstream/moderation/rest_client.py new file mode 100644 index 00000000..e9073a16 --- /dev/null +++ b/getstream/moderation/rest_client.py @@ -0,0 +1,422 @@ +# Code generated by GetStream internal OpenAPI code generator. DO NOT EDIT. +from getstream.base import BaseClient +from getstream.models import * +from getstream.stream_response import StreamResponse +from getstream.utils import build_query_param, build_body_dict + + +class ModerationRestClient(BaseClient): + def __init__(self, api_key: str, base_url: str, timeout: float, token: str): + """ + Initializes ModerationClient with BaseClient instance + :param api_key: A string representing the client's API key + :param base_url: A string representing the base uniform resource locator + :param timeout: A number representing the time limit for a request + :param token: A string instance representing the client's token + """ + super().__init__( + api_key=api_key, + base_url=base_url, + timeout=timeout, + token=token, + ) + + def ban( + self, + target_user_id: str, + banned_by_id: Optional[str] = None, + channel_cid: Optional[str] = None, + delete_messages: Optional[str] = None, + ip_ban: Optional[bool] = None, + reason: Optional[str] = None, + shadow: Optional[bool] = None, + timeout: Optional[int] = None, + banned_by: Optional[UserRequest] = None, + ) -> StreamResponse[BanResponse]: + json = build_body_dict( + target_user_id=target_user_id, + banned_by_id=banned_by_id, + channel_cid=channel_cid, + delete_messages=delete_messages, + ip_ban=ip_ban, + reason=reason, + shadow=shadow, + timeout=timeout, + banned_by=banned_by, + ) + + return self.post("/api/v2/moderation/ban", BanResponse, json=json) + + def bulk_image_moderation( + self, csv_file: str + ) -> StreamResponse[BulkImageModerationResponse]: + json = build_body_dict(csv_file=csv_file) + + return self.post( + "/api/v2/moderation/bulk_image_moderation", + BulkImageModerationResponse, + json=json, + ) + + def check( + self, + config_key: str, + entity_creator_id: str, + entity_id: str, + entity_type: str, + config_team: Optional[str] = None, + test_mode: Optional[bool] = None, + user_id: Optional[str] = None, + moderation_payload: Optional[ModerationPayload] = None, + options: Optional[Dict[str, object]] = None, + user: Optional[UserRequest] = None, + ) -> StreamResponse[CheckResponse]: + json = build_body_dict( + config_key=config_key, + entity_creator_id=entity_creator_id, + entity_id=entity_id, + entity_type=entity_type, + config_team=config_team, + test_mode=test_mode, + user_id=user_id, + moderation_payload=moderation_payload, + options=options, + user=user, + ) + + return self.post("/api/v2/moderation/check", CheckResponse, json=json) + + def upsert_config( + self, + key: str, + _async: Optional[bool] = None, + team: Optional[str] = None, + user_id: Optional[str] = None, + ai_image_config: Optional[AIImageConfig] = None, + ai_text_config: Optional[AITextConfig] = None, + ai_video_config: Optional[AIVideoConfig] = None, + automod_platform_circumvention_config: Optional[ + AutomodPlatformCircumventionConfig + ] = None, + automod_semantic_filters_config: Optional[AutomodSemanticFiltersConfig] = None, + automod_toxicity_config: Optional[AutomodToxicityConfig] = None, + aws_rekognition_config: Optional[AIImageConfig] = None, + block_list_config: Optional[BlockListConfig] = None, + bodyguard_config: Optional[AITextConfig] = None, + google_vision_config: Optional[GoogleVisionConfig] = None, + rule_builder_config: Optional[RuleBuilderConfig] = None, + user: Optional[UserRequest] = None, + velocity_filter_config: Optional[VelocityFilterConfig] = None, + ) -> StreamResponse[UpsertConfigResponse]: + json = build_body_dict( + key=key, + _async=_async, + team=team, + user_id=user_id, + ai_image_config=ai_image_config, + ai_text_config=ai_text_config, + ai_video_config=ai_video_config, + automod_platform_circumvention_config=automod_platform_circumvention_config, + automod_semantic_filters_config=automod_semantic_filters_config, + automod_toxicity_config=automod_toxicity_config, + aws_rekognition_config=aws_rekognition_config, + block_list_config=block_list_config, + bodyguard_config=bodyguard_config, + google_vision_config=google_vision_config, + rule_builder_config=rule_builder_config, + user=user, + velocity_filter_config=velocity_filter_config, + ) + + return self.post("/api/v2/moderation/config", UpsertConfigResponse, json=json) + + def delete_config( + self, key: str, team: Optional[str] = None + ) -> StreamResponse[DeleteModerationConfigResponse]: + query_params = build_query_param(team=team) + path_params = { + "key": key, + } + + return self.delete( + "/api/v2/moderation/config/{key}", + DeleteModerationConfigResponse, + query_params=query_params, + path_params=path_params, + ) + + def get_config( + self, key: str, team: Optional[str] = None + ) -> StreamResponse[GetConfigResponse]: + query_params = build_query_param(team=team) + path_params = { + "key": key, + } + + return self.get( + "/api/v2/moderation/config/{key}", + GetConfigResponse, + query_params=query_params, + path_params=path_params, + ) + + def query_moderation_configs( + self, + limit: Optional[int] = None, + next: Optional[str] = None, + prev: Optional[str] = None, + user_id: Optional[str] = None, + sort: Optional[List[SortParamRequest]] = None, + filter: Optional[Dict[str, object]] = None, + user: Optional[UserRequest] = None, + ) -> StreamResponse[QueryModerationConfigsResponse]: + json = build_body_dict( + limit=limit, + next=next, + prev=prev, + user_id=user_id, + sort=sort, + filter=filter, + user=user, + ) + + return self.post( + "/api/v2/moderation/configs", QueryModerationConfigsResponse, json=json + ) + + def custom_check( + self, + entity_id: str, + entity_type: str, + flags: List[CustomCheckFlag], + entity_creator_id: Optional[str] = None, + user_id: Optional[str] = None, + moderation_payload: Optional[ModerationPayload] = None, + user: Optional[UserRequest] = None, + ) -> StreamResponse[CustomCheckResponse]: + json = build_body_dict( + entity_id=entity_id, + entity_type=entity_type, + flags=flags, + entity_creator_id=entity_creator_id, + user_id=user_id, + moderation_payload=moderation_payload, + user=user, + ) + + return self.post( + "/api/v2/moderation/custom_check", CustomCheckResponse, json=json + ) + + def v2_delete_template(self) -> StreamResponse[DeleteModerationTemplateResponse]: + return self.delete( + "/api/v2/moderation/feeds_moderation_template", + DeleteModerationTemplateResponse, + ) + + def v2_query_templates( + self, + ) -> StreamResponse[QueryFeedModerationTemplatesResponse]: + return self.get( + "/api/v2/moderation/feeds_moderation_template", + QueryFeedModerationTemplatesResponse, + ) + + def v2_upsert_template( + self, name: str, config: FeedsModerationTemplateConfig + ) -> StreamResponse[UpsertModerationTemplateResponse]: + json = build_body_dict(name=name, config=config) + + return self.post( + "/api/v2/moderation/feeds_moderation_template", + UpsertModerationTemplateResponse, + json=json, + ) + + def flag( + self, + entity_id: str, + entity_type: str, + entity_creator_id: Optional[str] = None, + reason: Optional[str] = None, + user_id: Optional[str] = None, + custom: Optional[Dict[str, object]] = None, + moderation_payload: Optional[ModerationPayload] = None, + user: Optional[UserRequest] = None, + ) -> StreamResponse[FlagResponse]: + json = build_body_dict( + entity_id=entity_id, + entity_type=entity_type, + entity_creator_id=entity_creator_id, + reason=reason, + user_id=user_id, + custom=custom, + moderation_payload=moderation_payload, + user=user, + ) + + return self.post("/api/v2/moderation/flag", FlagResponse, json=json) + + def query_moderation_flags( + self, + limit: Optional[int] = None, + next: Optional[str] = None, + prev: Optional[str] = None, + sort: Optional[List[SortParam]] = None, + filter: Optional[Dict[str, object]] = None, + ) -> StreamResponse[QueryModerationFlagsResponse]: + json = build_body_dict( + limit=limit, next=next, prev=prev, sort=sort, filter=filter + ) + + return self.post( + "/api/v2/moderation/flags", QueryModerationFlagsResponse, json=json + ) + + def query_moderation_logs( + self, + limit: Optional[int] = None, + next: Optional[str] = None, + prev: Optional[str] = None, + user_id: Optional[str] = None, + sort: Optional[List[SortParamRequest]] = None, + filter: Optional[Dict[str, object]] = None, + user: Optional[UserRequest] = None, + ) -> StreamResponse[QueryModerationLogsResponse]: + json = build_body_dict( + limit=limit, + next=next, + prev=prev, + user_id=user_id, + sort=sort, + filter=filter, + user=user, + ) + + return self.post( + "/api/v2/moderation/logs", QueryModerationLogsResponse, json=json + ) + + def mute( + self, + target_ids: List[str], + timeout: Optional[int] = None, + user_id: Optional[str] = None, + user: Optional[UserRequest] = None, + ) -> StreamResponse[MuteResponse]: + json = build_body_dict( + target_ids=target_ids, timeout=timeout, user_id=user_id, user=user + ) + + return self.post("/api/v2/moderation/mute", MuteResponse, json=json) + + def query_review_queue( + self, + limit: Optional[int] = None, + lock_count: Optional[int] = None, + lock_duration: Optional[int] = None, + lock_items: Optional[bool] = None, + next: Optional[str] = None, + prev: Optional[str] = None, + stats_only: Optional[bool] = None, + user_id: Optional[str] = None, + sort: Optional[List[SortParamRequest]] = None, + filter: Optional[Dict[str, object]] = None, + user: Optional[UserRequest] = None, + ) -> StreamResponse[QueryReviewQueueResponse]: + json = build_body_dict( + limit=limit, + lock_count=lock_count, + lock_duration=lock_duration, + lock_items=lock_items, + next=next, + prev=prev, + stats_only=stats_only, + user_id=user_id, + sort=sort, + filter=filter, + user=user, + ) + + return self.post( + "/api/v2/moderation/review_queue", QueryReviewQueueResponse, json=json + ) + + def get_review_queue_item( + self, id: str + ) -> StreamResponse[GetReviewQueueItemResponse]: + path_params = { + "id": id, + } + + return self.get( + "/api/v2/moderation/review_queue/{id}", + GetReviewQueueItemResponse, + path_params=path_params, + ) + + def submit_action( + self, + action_type: str, + item_id: str, + user_id: Optional[str] = None, + ban: Optional[BanActionRequest] = None, + custom: Optional[CustomActionRequest] = None, + delete_activity: Optional[DeleteActivityRequest] = None, + delete_message: Optional[DeleteMessageRequest] = None, + delete_reaction: Optional[DeleteReactionRequest] = None, + delete_user: Optional[DeleteUserRequest] = None, + mark_reviewed: Optional[MarkReviewedRequest] = None, + unban: Optional[UnbanActionRequest] = None, + user: Optional[UserRequest] = None, + ) -> StreamResponse[SubmitActionResponse]: + json = build_body_dict( + action_type=action_type, + item_id=item_id, + user_id=user_id, + ban=ban, + custom=custom, + delete_activity=delete_activity, + delete_message=delete_message, + delete_reaction=delete_reaction, + delete_user=delete_user, + mark_reviewed=mark_reviewed, + unban=unban, + user=user, + ) + + return self.post( + "/api/v2/moderation/submit_action", SubmitActionResponse, json=json + ) + + def unban( + self, + target_user_id: str, + channel_cid: Optional[str] = None, + created_by: Optional[str] = None, + unbanned_by_id: Optional[str] = None, + unbanned_by: Optional[UserRequest] = None, + ) -> StreamResponse[UnbanResponse]: + query_params = build_query_param( + target_user_id=target_user_id, + channel_cid=channel_cid, + created_by=created_by, + ) + json = build_body_dict(unbanned_by_id=unbanned_by_id, unbanned_by=unbanned_by) + + return self.post( + "/api/v2/moderation/unban", + UnbanResponse, + query_params=query_params, + json=json, + ) + + def unmute( + self, + target_ids: List[str], + user_id: Optional[str] = None, + user: Optional[UserRequest] = None, + ) -> StreamResponse[UnmuteResponse]: + json = build_body_dict(target_ids=target_ids, user_id=user_id, user=user) + + return self.post("/api/v2/moderation/unmute", UnmuteResponse, json=json) diff --git a/uv.lock b/uv.lock index a66eefdd..e4c79726 100644 --- a/uv.lock +++ b/uv.lock @@ -148,7 +148,7 @@ wheels = [ [[package]] name = "getstream" -version = "1.3.1" +version = "2.1.0" source = { editable = "." } dependencies = [ { name = "dataclasses-json" },