diff --git a/getstream/models/__init__.py b/getstream/models/__init__.py index 6dae38d8..b8326130 100644 --- a/getstream/models/__init__.py +++ b/getstream/models/__init__.py @@ -870,6 +870,14 @@ class BroadcastSettingsResponse(DataClassJsonMixin): rtmp: "RTMPSettingsResponse" = dc_field(metadata=dc_config(field_name="rtmp")) +@dataclass +class BrowserDataResponse(DataClassJsonMixin): + name: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="name")) + version: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="version") + ) + + @dataclass class CallAcceptedEvent(DataClassJsonMixin): call_cid: str = dc_field(metadata=dc_config(field_name="call_cid")) @@ -3478,6 +3486,17 @@ class CheckSQSResponse(DataClassJsonMixin): ) +@dataclass +class ClientOSDataResponse(DataClassJsonMixin): + architecture: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="architecture") + ) + name: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="name")) + version: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="version") + ) + + @dataclass class ClosedCaptionEvent(DataClassJsonMixin): call_cid: str = dc_field(metadata=dc_config(field_name="call_cid")) @@ -4375,6 +4394,14 @@ class Device(DataClassJsonMixin): voip: Optional[bool] = dc_field(default=None, metadata=dc_config(field_name="voip")) +@dataclass +class DeviceDataResponse(DataClassJsonMixin): + name: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="name")) + version: Optional[str] = dc_field( + default=None, metadata=dc_config(field_name="version") + ) + + @dataclass class DeviceErrorInfo(DataClassJsonMixin): error_message: str = dc_field(metadata=dc_config(field_name="error_message")) @@ -5355,6 +5382,13 @@ class GetBlockedUsersResponse(DataClassJsonMixin): ) +@dataclass +class GetCallReportResponse(DataClassJsonMixin): + duration: str = dc_field(metadata=dc_config(field_name="duration")) + session_id: str = dc_field(metadata=dc_config(field_name="session_id")) + report: "ReportResponse" = dc_field(metadata=dc_config(field_name="report")) + + @dataclass class GetCallResponse(DataClassJsonMixin): duration: str = dc_field(metadata=dc_config(field_name="duration")) @@ -5365,13 +5399,6 @@ class GetCallResponse(DataClassJsonMixin): call: "CallResponse" = dc_field(metadata=dc_config(field_name="call")) -@dataclass -class GetCallReportResponse(DataClassJsonMixin): - duration: str = dc_field(metadata=dc_config(field_name="duration")) - session_id: str = dc_field(metadata=dc_config(field_name="session_id")) - report: "ReportResponse" = dc_field(metadata=dc_config(field_name="report")) - - @dataclass class GetCallStatsResponse(DataClassJsonMixin): call_duration_seconds: int = dc_field( @@ -7975,6 +8002,13 @@ class PinResponse(DataClassJsonMixin): duration: str = dc_field(metadata=dc_config(field_name="duration")) +@dataclass +class PlatformDataResponse(DataClassJsonMixin): + browser: "BrowserDataResponse" = dc_field(metadata=dc_config(field_name="browser")) + device: "DeviceDataResponse" = dc_field(metadata=dc_config(field_name="device")) + os: "ClientOSDataResponse" = dc_field(metadata=dc_config(field_name="os")) + + @dataclass class Policy(DataClassJsonMixin): action: int = dc_field(metadata=dc_config(field_name="action")) @@ -9187,6 +9221,31 @@ class QueryUsageStatsResponse(DataClassJsonMixin): prev: Optional[str] = dc_field(default=None, metadata=dc_config(field_name="prev")) +@dataclass +class QueryUserFeedbackRequest(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[SortParamRequest]]" = dc_field( + default=None, metadata=dc_config(field_name="sort") + ) + filter_conditions: Optional[Dict[str, object]] = dc_field( + default=None, metadata=dc_config(field_name="filter_conditions") + ) + + +@dataclass +class QueryUserFeedbackResponse(DataClassJsonMixin): + duration: str = dc_field(metadata=dc_config(field_name="duration")) + user_feedback: "List[UserFeedbackResponse]" = dc_field( + metadata=dc_config(field_name="user_feedback") + ) + 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 QueryUsersPayload(DataClassJsonMixin): filter_conditions: Dict[str, object] = dc_field( @@ -12270,6 +12329,23 @@ class UserFeedbackReportResponse(DataClassJsonMixin): ) +@dataclass +class UserFeedbackResponse(DataClassJsonMixin): + cid: str = dc_field(metadata=dc_config(field_name="cid")) + rating: int = dc_field(metadata=dc_config(field_name="rating")) + reason: str = dc_field(metadata=dc_config(field_name="reason")) + sdk: str = dc_field(metadata=dc_config(field_name="sdk")) + sdk_version: str = dc_field(metadata=dc_config(field_name="sdk_version")) + session_id: str = dc_field(metadata=dc_config(field_name="session_id")) + user_id: str = dc_field(metadata=dc_config(field_name="user_id")) + platform: "PlatformDataResponse" = dc_field( + metadata=dc_config(field_name="platform") + ) + custom: Optional[Dict[str, object]] = dc_field( + default=None, metadata=dc_config(field_name="custom") + ) + + @dataclass class UserFlaggedEvent(DataClassJsonMixin): created_at: datetime = dc_field( @@ -12393,6 +12469,12 @@ class UserMutedEvent(DataClassJsonMixin): ) +@dataclass +class UserRatingReportResponse(DataClassJsonMixin): + average: float = dc_field(metadata=dc_config(field_name="average")) + count: int = dc_field(metadata=dc_config(field_name="count")) + + @dataclass class UserReactivatedEvent(DataClassJsonMixin): created_at: datetime = dc_field( @@ -12411,12 +12493,6 @@ class UserReactivatedEvent(DataClassJsonMixin): ) -@dataclass -class UserRatingReportResponse(DataClassJsonMixin): - average: float = dc_field(metadata=dc_config(field_name="average")) - count: int = dc_field(metadata=dc_config(field_name="count")) - - @dataclass class UserRequest(DataClassJsonMixin): id: str = dc_field(metadata=dc_config(field_name="id")) diff --git a/getstream/video/call.py b/getstream/video/call.py index 5d2cb034..98e72988 100644 --- a/getstream/video/call.py +++ b/getstream/video/call.py @@ -199,6 +199,15 @@ def list_recordings(self) -> StreamResponse[ListRecordingsResponse]: self._sync_from_response(response.data) return response + def get_call_report( + self, session_id: Optional[str] = None + ) -> StreamResponse[GetCallReportResponse]: + response = self.client.get_call_report( + type=self.call_type, id=self.id, session_id=session_id + ) + self._sync_from_response(response.data) + return response + def start_rtmp_broadcasts( self, broadcasts: List[RTMPBroadcastRequest] ) -> StreamResponse[StartRTMPBroadcastsResponse]: diff --git a/getstream/video/rest_client.py b/getstream/video/rest_client.py index 2dca8fcb..7b215f40 100644 --- a/getstream/video/rest_client.py +++ b/getstream/video/rest_client.py @@ -21,6 +21,31 @@ def __init__(self, api_key: str, base_url: str, timeout: float, token: str): token=token, ) + def query_user_feedback( + self, + full: Optional[bool] = None, + limit: Optional[int] = None, + next: Optional[str] = None, + prev: Optional[str] = None, + sort: Optional[List[SortParamRequest]] = None, + filter_conditions: Optional[Dict[str, object]] = None, + ) -> StreamResponse[QueryUserFeedbackResponse]: + query_params = build_query_param(full=full) + json = build_body_dict( + limit=limit, + next=next, + prev=prev, + sort=sort, + filter_conditions=filter_conditions, + ) + + return self.post( + "/api/v2/video/call/feedback", + QueryUserFeedbackResponse, + query_params=query_params, + json=json, + ) + def query_call_members( self, id: str, diff --git a/tests/test_video_examples.py b/tests/test_video_examples.py index 6673f7b5..de7e07a3 100644 --- a/tests/test_video_examples.py +++ b/tests/test_video_examples.py @@ -7,7 +7,8 @@ ScreensharingSettingsRequest, OwnCapability, LimitsSettingsRequest, - BackstageSettingsRequest, SessionSettingsRequest, + BackstageSettingsRequest, + SessionSettingsRequest, ) from getstream.video.call import Call from datetime import datetime, timezone, timedelta @@ -305,7 +306,6 @@ def test_create_call_with_custom_session_inactivity_timeout(call: Call): def test_create_call_type_with_custom_session_inactivity_timeout(client: Stream): - # create a call type with a session inactivity timeout of 5 minutes response = client.video.create_call_type( name="long_inactivity_timeout_" + str(uuid.uuid4()), @@ -316,4 +316,4 @@ def test_create_call_type_with_custom_session_inactivity_timeout(client: Stream) ), ) - assert response.data.settings.session.inactivity_timeout_seconds == 300 \ No newline at end of file + assert response.data.settings.session.inactivity_timeout_seconds == 300