From 2fc52179bb6c8f80a28ecdbbe3e446ae6c8218c3 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Thu, 13 Mar 2025 10:10:38 -0700 Subject: [PATCH 01/16] update rust-sdk --- livekit-rtc/rust-sdks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/livekit-rtc/rust-sdks b/livekit-rtc/rust-sdks index 3aeced95..1f3d9a3e 160000 --- a/livekit-rtc/rust-sdks +++ b/livekit-rtc/rust-sdks @@ -1 +1 @@ -Subproject commit 3aeced9522a2b06b1d2e7778a06ed2c8ddfaf76f +Subproject commit 1f3d9a3e5b88daabc3c0a48ebd0fbac8d18578b6 From 9ecf29a52d4af68c0d52b85c78edbd1606a75289 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Thu, 13 Mar 2025 10:33:18 -0700 Subject: [PATCH 02/16] move some rpc functionality to room --- .../livekit/rtc/_proto/audio_frame_pb2.py | 12 +- livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py | 12 +- livekit-rtc/livekit/rtc/_proto/ffi_pb2.py | 12 +- livekit-rtc/livekit/rtc/_proto/handle_pb2.py | 12 +- .../livekit/rtc/_proto/participant_pb2.py | 12 +- livekit-rtc/livekit/rtc/_proto/room_pb2.py | 12 +- livekit-rtc/livekit/rtc/_proto/rpc_pb2.py | 48 +++--- livekit-rtc/livekit/rtc/_proto/rpc_pb2.pyi | 20 +-- livekit-rtc/livekit/rtc/_proto/stats_pb2.py | 12 +- livekit-rtc/livekit/rtc/_proto/track_pb2.py | 12 +- .../rtc/_proto/track_publication_pb2.py | 12 +- .../livekit/rtc/_proto/video_frame_pb2.py | 12 +- livekit-rtc/livekit/rtc/participant.py | 107 ++----------- livekit-rtc/livekit/rtc/room.py | 143 +++++++++++++++++- 14 files changed, 306 insertions(+), 132 deletions(-) diff --git a/livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py b/livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py index b4007e96..4684b024 100644 --- a/livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py @@ -1,12 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: audio_frame.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 5.29.3 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 29, + 3, + '', + 'audio_frame.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py b/livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py index 482deb8a..7db50ccb 100644 --- a/livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py @@ -1,12 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: e2ee.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 5.29.3 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 29, + 3, + '', + 'e2ee.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/ffi_pb2.py b/livekit-rtc/livekit/rtc/_proto/ffi_pb2.py index 659b299b..10590a2f 100644 --- a/livekit-rtc/livekit/rtc/_proto/ffi_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/ffi_pb2.py @@ -1,12 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: ffi.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 5.29.3 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 29, + 3, + '', + 'ffi.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/handle_pb2.py b/livekit-rtc/livekit/rtc/_proto/handle_pb2.py index 98d253b4..ee00e56b 100644 --- a/livekit-rtc/livekit/rtc/_proto/handle_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/handle_pb2.py @@ -1,12 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: handle.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 5.29.3 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 29, + 3, + '', + 'handle.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/participant_pb2.py b/livekit-rtc/livekit/rtc/_proto/participant_pb2.py index b4425bd1..7095e073 100644 --- a/livekit-rtc/livekit/rtc/_proto/participant_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/participant_pb2.py @@ -1,12 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: participant.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 5.29.3 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 29, + 3, + '', + 'participant.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/room_pb2.py b/livekit-rtc/livekit/rtc/_proto/room_pb2.py index 57baa54d..364012c8 100644 --- a/livekit-rtc/livekit/rtc/_proto/room_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/room_pb2.py @@ -1,12 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: room.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 5.29.3 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 29, + 3, + '', + 'room.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/rpc_pb2.py b/livekit-rtc/livekit/rtc/_proto/rpc_pb2.py index 1b6302cd..f7a707c4 100644 --- a/livekit-rtc/livekit/rtc/_proto/rpc_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/rpc_pb2.py @@ -1,12 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: rpc.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 5.29.3 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 29, + 3, + '', + 'rpc.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -14,7 +24,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\trpc.proto\x12\rlivekit.proto\"7\n\x08RpcError\x12\x0c\n\x04\x63ode\x18\x01 \x02(\r\x12\x0f\n\x07message\x18\x02 \x02(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\t\"\x91\x01\n\x11PerformRpcRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x1c\n\x14\x64\x65stination_identity\x18\x02 \x02(\t\x12\x0e\n\x06method\x18\x03 \x02(\t\x12\x0f\n\x07payload\x18\x04 \x02(\t\x12\x1b\n\x13response_timeout_ms\x18\x05 \x01(\r\"L\n\x18RegisterRpcMethodRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x0e\n\x06method\x18\x02 \x02(\t\"N\n\x1aUnregisterRpcMethodRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x0e\n\x06method\x18\x02 \x02(\t\"\x96\x01\n\"RpcMethodInvocationResponseRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x15\n\rinvocation_id\x18\x02 \x02(\x04\x12\x0f\n\x07payload\x18\x03 \x01(\t\x12&\n\x05\x65rror\x18\x04 \x01(\x0b\x32\x17.livekit.proto.RpcError\"&\n\x12PerformRpcResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"\x1b\n\x19RegisterRpcMethodResponse\"\x1d\n\x1bUnregisterRpcMethodResponse\"4\n#RpcMethodInvocationResponseResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\"_\n\x12PerformRpcCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\x0f\n\x07payload\x18\x02 \x01(\t\x12&\n\x05\x65rror\x18\x03 \x01(\x0b\x32\x17.livekit.proto.RpcError\"\xbe\x01\n\x18RpcMethodInvocationEvent\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x15\n\rinvocation_id\x18\x02 \x02(\x04\x12\x0e\n\x06method\x18\x03 \x02(\t\x12\x12\n\nrequest_id\x18\x04 \x02(\t\x12\x17\n\x0f\x63\x61ller_identity\x18\x05 \x02(\t\x12\x0f\n\x07payload\x18\x06 \x02(\t\x12\x1b\n\x13response_timeout_ms\x18\x07 \x02(\rB\x10\xaa\x02\rLiveKit.Proto') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\trpc.proto\x12\rlivekit.proto\"7\n\x08RpcError\x12\x0c\n\x04\x63ode\x18\x01 \x02(\r\x12\x0f\n\x07message\x18\x02 \x02(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\t\"\x91\x01\n\x11PerformRpcRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x1c\n\x14\x64\x65stination_identity\x18\x02 \x02(\t\x12\x0e\n\x06method\x18\x03 \x02(\t\x12\x0f\n\x07payload\x18\x04 \x02(\t\x12\x1b\n\x13response_timeout_ms\x18\x05 \x01(\r\"?\n\x18RegisterRpcMethodRequest\x12\x13\n\x0broom_handle\x18\x01 \x02(\x04\x12\x0e\n\x06method\x18\x02 \x02(\t\"A\n\x1aUnregisterRpcMethodRequest\x12\x13\n\x0broom_handle\x18\x01 \x02(\x04\x12\x0e\n\x06method\x18\x02 \x02(\t\"\x96\x01\n\"RpcMethodInvocationResponseRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x15\n\rinvocation_id\x18\x02 \x02(\x04\x12\x0f\n\x07payload\x18\x03 \x01(\t\x12&\n\x05\x65rror\x18\x04 \x01(\x0b\x32\x17.livekit.proto.RpcError\"&\n\x12PerformRpcResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"\x1b\n\x19RegisterRpcMethodResponse\"\x1d\n\x1bUnregisterRpcMethodResponse\"4\n#RpcMethodInvocationResponseResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\"_\n\x12PerformRpcCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\x0f\n\x07payload\x18\x02 \x01(\t\x12&\n\x05\x65rror\x18\x03 \x01(\x0b\x32\x17.livekit.proto.RpcError\"\xbe\x01\n\x18RpcMethodInvocationEvent\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x15\n\rinvocation_id\x18\x02 \x02(\x04\x12\x0e\n\x06method\x18\x03 \x02(\t\x12\x12\n\nrequest_id\x18\x04 \x02(\t\x12\x17\n\x0f\x63\x61ller_identity\x18\x05 \x02(\t\x12\x0f\n\x07payload\x18\x06 \x02(\t\x12\x1b\n\x13response_timeout_ms\x18\x07 \x02(\rB\x10\xaa\x02\rLiveKit.Proto') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -27,21 +37,21 @@ _globals['_PERFORMRPCREQUEST']._serialized_start=86 _globals['_PERFORMRPCREQUEST']._serialized_end=231 _globals['_REGISTERRPCMETHODREQUEST']._serialized_start=233 - _globals['_REGISTERRPCMETHODREQUEST']._serialized_end=309 - _globals['_UNREGISTERRPCMETHODREQUEST']._serialized_start=311 - _globals['_UNREGISTERRPCMETHODREQUEST']._serialized_end=389 - _globals['_RPCMETHODINVOCATIONRESPONSEREQUEST']._serialized_start=392 - _globals['_RPCMETHODINVOCATIONRESPONSEREQUEST']._serialized_end=542 - _globals['_PERFORMRPCRESPONSE']._serialized_start=544 - _globals['_PERFORMRPCRESPONSE']._serialized_end=582 - _globals['_REGISTERRPCMETHODRESPONSE']._serialized_start=584 - _globals['_REGISTERRPCMETHODRESPONSE']._serialized_end=611 - _globals['_UNREGISTERRPCMETHODRESPONSE']._serialized_start=613 - _globals['_UNREGISTERRPCMETHODRESPONSE']._serialized_end=642 - _globals['_RPCMETHODINVOCATIONRESPONSERESPONSE']._serialized_start=644 - _globals['_RPCMETHODINVOCATIONRESPONSERESPONSE']._serialized_end=696 - _globals['_PERFORMRPCCALLBACK']._serialized_start=698 - _globals['_PERFORMRPCCALLBACK']._serialized_end=793 - _globals['_RPCMETHODINVOCATIONEVENT']._serialized_start=796 - _globals['_RPCMETHODINVOCATIONEVENT']._serialized_end=986 + _globals['_REGISTERRPCMETHODREQUEST']._serialized_end=296 + _globals['_UNREGISTERRPCMETHODREQUEST']._serialized_start=298 + _globals['_UNREGISTERRPCMETHODREQUEST']._serialized_end=363 + _globals['_RPCMETHODINVOCATIONRESPONSEREQUEST']._serialized_start=366 + _globals['_RPCMETHODINVOCATIONRESPONSEREQUEST']._serialized_end=516 + _globals['_PERFORMRPCRESPONSE']._serialized_start=518 + _globals['_PERFORMRPCRESPONSE']._serialized_end=556 + _globals['_REGISTERRPCMETHODRESPONSE']._serialized_start=558 + _globals['_REGISTERRPCMETHODRESPONSE']._serialized_end=585 + _globals['_UNREGISTERRPCMETHODRESPONSE']._serialized_start=587 + _globals['_UNREGISTERRPCMETHODRESPONSE']._serialized_end=616 + _globals['_RPCMETHODINVOCATIONRESPONSERESPONSE']._serialized_start=618 + _globals['_RPCMETHODINVOCATIONRESPONSERESPONSE']._serialized_end=670 + _globals['_PERFORMRPCCALLBACK']._serialized_start=672 + _globals['_PERFORMRPCCALLBACK']._serialized_end=767 + _globals['_RPCMETHODINVOCATIONEVENT']._serialized_start=770 + _globals['_RPCMETHODINVOCATIONEVENT']._serialized_end=960 # @@protoc_insertion_point(module_scope) diff --git a/livekit-rtc/livekit/rtc/_proto/rpc_pb2.pyi b/livekit-rtc/livekit/rtc/_proto/rpc_pb2.pyi index 20330912..9d426942 100644 --- a/livekit-rtc/livekit/rtc/_proto/rpc_pb2.pyi +++ b/livekit-rtc/livekit/rtc/_proto/rpc_pb2.pyi @@ -79,18 +79,18 @@ global___PerformRpcRequest = PerformRpcRequest class RegisterRpcMethodRequest(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor - LOCAL_PARTICIPANT_HANDLE_FIELD_NUMBER: builtins.int + ROOM_HANDLE_FIELD_NUMBER: builtins.int METHOD_FIELD_NUMBER: builtins.int - local_participant_handle: builtins.int + room_handle: builtins.int method: builtins.str def __init__( self, *, - local_participant_handle: builtins.int | None = ..., + room_handle: builtins.int | None = ..., method: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["local_participant_handle", b"local_participant_handle", "method", b"method"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["local_participant_handle", b"local_participant_handle", "method", b"method"]) -> None: ... + def HasField(self, field_name: typing.Literal["method", b"method", "room_handle", b"room_handle"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["method", b"method", "room_handle", b"room_handle"]) -> None: ... global___RegisterRpcMethodRequest = RegisterRpcMethodRequest @@ -98,18 +98,18 @@ global___RegisterRpcMethodRequest = RegisterRpcMethodRequest class UnregisterRpcMethodRequest(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor - LOCAL_PARTICIPANT_HANDLE_FIELD_NUMBER: builtins.int + ROOM_HANDLE_FIELD_NUMBER: builtins.int METHOD_FIELD_NUMBER: builtins.int - local_participant_handle: builtins.int + room_handle: builtins.int method: builtins.str def __init__( self, *, - local_participant_handle: builtins.int | None = ..., + room_handle: builtins.int | None = ..., method: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["local_participant_handle", b"local_participant_handle", "method", b"method"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["local_participant_handle", b"local_participant_handle", "method", b"method"]) -> None: ... + def HasField(self, field_name: typing.Literal["method", b"method", "room_handle", b"room_handle"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["method", b"method", "room_handle", b"room_handle"]) -> None: ... global___UnregisterRpcMethodRequest = UnregisterRpcMethodRequest diff --git a/livekit-rtc/livekit/rtc/_proto/stats_pb2.py b/livekit-rtc/livekit/rtc/_proto/stats_pb2.py index 2cbdb1cd..73119d85 100644 --- a/livekit-rtc/livekit/rtc/_proto/stats_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/stats_pb2.py @@ -1,12 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: stats.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 5.29.3 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 29, + 3, + '', + 'stats.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/track_pb2.py b/livekit-rtc/livekit/rtc/_proto/track_pb2.py index 5e3d1691..f409ed5c 100644 --- a/livekit-rtc/livekit/rtc/_proto/track_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/track_pb2.py @@ -1,12 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: track.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 5.29.3 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 29, + 3, + '', + 'track.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/track_publication_pb2.py b/livekit-rtc/livekit/rtc/_proto/track_publication_pb2.py index 22a19081..a4c61ce3 100644 --- a/livekit-rtc/livekit/rtc/_proto/track_publication_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/track_publication_pb2.py @@ -1,12 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: track_publication.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 5.29.3 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 29, + 3, + '', + 'track_publication.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py b/livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py index bcbd99e9..8ec80f62 100644 --- a/livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py @@ -1,12 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: video_frame.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 5.29.3 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 29, + 3, + '', + 'video_frame.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/participant.py b/livekit-rtc/livekit/rtc/participant.py index cee74375..97319801 100644 --- a/livekit-rtc/livekit/rtc/participant.py +++ b/livekit-rtc/livekit/rtc/participant.py @@ -19,7 +19,8 @@ import os import mimetypes import aiofiles -from typing import List, Union, Callable, Dict, Awaitable, Optional, Mapping, cast +import weakref +from typing import List, Union, Callable, Dict, Awaitable, Optional, Mapping, cast, TYPE_CHECKING from abc import abstractmethod, ABC from ._ffi_client import FfiClient, FfiHandle @@ -53,6 +54,8 @@ ByteStreamInfo, STREAM_CHUNK_SIZE, ) +if TYPE_CHECKING: + from .room import Room class PublishTrackError(Exception): @@ -151,13 +154,12 @@ def __init__( self, room_queue: BroadcastQueue[proto_ffi.FfiEvent], owned_info: proto_participant.OwnedParticipant, + room: Room, ) -> None: super().__init__(owned_info) self._room_queue = room_queue self._track_publications: dict[str, LocalTrackPublication] = {} # type: ignore - self._rpc_handlers: Dict[ - str, Callable[[RpcInvocationData], Union[Awaitable[str], str]] - ] = {} + self._room_ref = weakref.ref(room) @property def track_publications(self) -> Mapping[str, LocalTrackPublication]: @@ -331,6 +333,8 @@ def register_rpc_method( handler: Optional[Callable[[RpcInvocationData], Union[Awaitable[str], str]]] = None, ) -> Union[None, Callable]: """ + Deprecated + Establishes the participant as a receiver for calls of the specified RPC method. Can be used either as a decorator or a regular method. @@ -365,35 +369,22 @@ async def greet_handler(data: RpcInvocationData) -> str: room.local_participant.register_rpc_method('greet', greet_handler) """ - - def register(handler_func): - self._rpc_handlers[method_name] = handler_func - req = proto_ffi.FfiRequest() - req.register_rpc_method.local_participant_handle = self._ffi_handle.handle - req.register_rpc_method.method = method_name - FfiClient.instance.request(req) - - if handler is not None: - register(handler) - return None - else: - # Called as a decorator - return register + room = self.room + if room is not None: + return room.register_rpc_method(method_name, handler) def unregister_rpc_method(self, method: str) -> None: """ + Deprecated + Unregisters a previously registered RPC method. Args: method (str): The name of the RPC method to unregister """ - self._rpc_handlers.pop(method, None) - - req = proto_ffi.FfiRequest() - req.unregister_rpc_method.local_participant_handle = self._ffi_handle.handle - req.unregister_rpc_method.method = method - - FfiClient.instance.request(req) + room = self.room + if room is not None: + room.unregister_rpc_method(method) def set_track_subscription_permissions( self, @@ -417,72 +408,6 @@ def set_track_subscription_permissions( req.set_track_subscription_permissions.permissions.extend(participant_permissions) FfiClient.instance.request(req) - async def _handle_rpc_method_invocation( - self, - invocation_id: int, - method: str, - request_id: str, - caller_identity: str, - payload: str, - response_timeout: float, - ) -> None: - response_error: Optional[RpcError] = None - response_payload: Optional[str] = None - - params = RpcInvocationData(request_id, caller_identity, payload, response_timeout) - - handler = self._rpc_handlers.get(method) - - if not handler: - response_error = RpcError._built_in(RpcError.ErrorCode.UNSUPPORTED_METHOD) - else: - try: - if asyncio.iscoroutinefunction(handler): - async_handler = cast(Callable[[RpcInvocationData], Awaitable[str]], handler) - - async def run_handler(): - try: - return await async_handler(params) - except asyncio.CancelledError: - # This will be caught by the outer try-except if it's due to timeout - raise - - try: - response_payload = await asyncio.wait_for( - run_handler(), timeout=response_timeout - ) - except asyncio.TimeoutError: - raise RpcError._built_in(RpcError.ErrorCode.RESPONSE_TIMEOUT) - except asyncio.CancelledError: - raise RpcError._built_in(RpcError.ErrorCode.RECIPIENT_DISCONNECTED) - else: - sync_handler = cast(Callable[[RpcInvocationData], str], handler) - response_payload = sync_handler(params) - except RpcError as error: - response_error = error - except Exception as error: - logger.exception( - f"Uncaught error returned by RPC handler for {method}. " - "Returning APPLICATION_ERROR instead. " - f"Original error: {error}" - ) - response_error = RpcError._built_in(RpcError.ErrorCode.APPLICATION_ERROR) - - req = proto_ffi.FfiRequest( - rpc_method_invocation_response=RpcMethodInvocationResponseRequest( - local_participant_handle=self._ffi_handle.handle, - invocation_id=invocation_id, - error=response_error._to_proto() if response_error else None, - payload=response_payload, - ) - ) - - res = FfiClient.instance.request(req) - - if res.rpc_method_invocation_response.error: - message = res.rpc_method_invocation_response.error - logger.exception(f"error sending rpc method invocation response: {message}") - async def set_metadata(self, metadata: str) -> None: """ Set the metadata for the local participant. diff --git a/livekit-rtc/livekit/rtc/room.py b/livekit-rtc/livekit/rtc/room.py index 1a6cf622..7b87b13d 100644 --- a/livekit-rtc/livekit/rtc/room.py +++ b/livekit-rtc/livekit/rtc/room.py @@ -141,6 +141,9 @@ def __init__( self._loop = loop or asyncio.get_event_loop() self._room_queue = BroadcastQueue[proto_ffi.FfiEvent]() self._info = proto_room.RoomInfo() + self._rpc_handlers: Dict[ + str, Callable[[RpcInvocationData], Union[Awaitable[str], str]] + ] = {} self._rpc_invocation_tasks: set[asyncio.Task] = set() self._data_stream_tasks: set[asyncio.Task] = set() @@ -394,7 +397,7 @@ def on_participant_connected(participant): self._connection_state = ConnectionState.CONN_CONNECTED self._local_participant = LocalParticipant( - self._room_queue, cb.connect.result.local_participant + self._room_queue, cb.connect.result.local_participant, self ) for pt in cb.connect.result.participants: @@ -449,6 +452,76 @@ async def disconnect(self) -> None: await self._task FfiClient.instance.queue.unsubscribe(self._ffi_queue) + def register_rpc_method( + self, + method_name: str, + handler: Optional[Callable[[RpcInvocationData], Union[Awaitable[str], str]]] = None, + ) -> Union[None, Callable]: + """ + Establishes the participant as a receiver for calls of the specified RPC method. + Can be used either as a decorator or a regular method. + + The handler will receive one argument of type `RpcInvocationData` and should return a string response which will be forwarded back to the caller. + + The handler may be synchronous or asynchronous. + + If unable to respond within `response_timeout`, the caller will hang up and receive an error on their side. + + You may raise errors of type `RpcError` in the handler, and they will be forwarded to the caller. + + Other errors raised in your handler will be caught and forwarded to the caller as "1500 Application Error". + + Args: + method_name (str): The name of the indicated RPC method. + handler (Optional[Callable]): Handler to be invoked whenever an RPC request for this method is received. Omit this argument to use the decorator syntax. + + Returns: + None (when used as a decorator it returns the decorator function) + + Example: + # As a decorator: + @room.register_rpc_method("greet") + async def greet_handler(data: RpcInvocationData) -> str: + print(f"Received greeting from {data.caller_identity}: {data.payload}") + return f"Hello, {data.caller_identity}!" + + # As a regular method: + async def greet_handler(data: RpcInvocationData) -> str: + print(f"Received greeting from {data.caller_identity}: {data.payload}") + return f"Hello, {data.caller_identity}!" + + room.register_rpc_method('greet', greet_handler) + """ + + def register(handler_func): + self._rpc_handlers[method_name] = handler_func + req = proto_ffi.FfiRequest() + req.register_rpc_method.room_handle = self._ffi_handle.handle + req.register_rpc_method.method = method_name + FfiClient.instance.request(req) + + if handler is not None: + register(handler) + return None + else: + # Called as a decorator + return register + + def unregister_rpc_method(self, method: str) -> None: + """ + Unregisters a previously registered RPC method. + + Args: + method (str): The name of the RPC method to unregister + """ + self._rpc_handlers.pop(method, None) + + req = proto_ffi.FfiRequest() + req.unregister_rpc_method.room_handle = self._ffi_handle.handle + req.unregister_rpc_method.method = method + + FfiClient.instance.request(req) + async def _listen_task(self) -> None: # listen to incoming room events while True: @@ -483,7 +556,7 @@ def _on_rpc_method_invocation(self, rpc_invocation: RpcMethodInvocationEvent): if rpc_invocation.local_participant_handle == self._local_participant._ffi_handle.handle: task = self._loop.create_task( - self._local_participant._handle_rpc_method_invocation( + self._handle_rpc_method_invocation( rpc_invocation.invocation_id, rpc_invocation.method, rpc_invocation.request_id, @@ -823,6 +896,72 @@ def _create_remote_participant( self._remote_participants[participant.identity] = participant return participant + async def _handle_rpc_method_invocation( + self, + invocation_id: int, + method: str, + request_id: str, + caller_identity: str, + payload: str, + response_timeout: float, + ) -> None: + response_error: Optional[RpcError] = None + response_payload: Optional[str] = None + + params = RpcInvocationData(request_id, caller_identity, payload, response_timeout) + + handler = self._rpc_handlers.get(method) + + if not handler: + response_error = RpcError._built_in(RpcError.ErrorCode.UNSUPPORTED_METHOD) + else: + try: + if asyncio.iscoroutinefunction(handler): + async_handler = cast(Callable[[RpcInvocationData], Awaitable[str]], handler) + + async def run_handler(): + try: + return await async_handler(params) + except asyncio.CancelledError: + # This will be caught by the outer try-except if it's due to timeout + raise + + try: + response_payload = await asyncio.wait_for( + run_handler(), timeout=response_timeout + ) + except asyncio.TimeoutError: + raise RpcError._built_in(RpcError.ErrorCode.RESPONSE_TIMEOUT) + except asyncio.CancelledError: + raise RpcError._built_in(RpcError.ErrorCode.RECIPIENT_DISCONNECTED) + else: + sync_handler = cast(Callable[[RpcInvocationData], str], handler) + response_payload = sync_handler(params) + except RpcError as error: + response_error = error + except Exception as error: + logger.exception( + f"Uncaught error returned by RPC handler for {method}. " + "Returning APPLICATION_ERROR instead. " + f"Original error: {error}" + ) + response_error = RpcError._built_in(RpcError.ErrorCode.APPLICATION_ERROR) + + req = proto_ffi.FfiRequest( + rpc_method_invocation_response=RpcMethodInvocationResponseRequest( + local_participant_handle=self._ffi_handle.handle, + invocation_id=invocation_id, + error=response_error._to_proto() if response_error else None, + payload=response_payload, + ) + ) + + res = FfiClient.instance.request(req) + + if res.rpc_method_invocation_response.error: + message = res.rpc_method_invocation_response.error + logger.exception(f"error sending rpc method invocation response: {message}") + def __repr__(self) -> str: sid = "unknown" if self._first_sid_future.done(): From 5ae87c7eb7ed876678dc4862eaf4d0c1928bd00e Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Thu, 13 Mar 2025 10:35:14 -0700 Subject: [PATCH 03/16] fmt --- livekit-rtc/livekit/rtc/participant.py | 1 + 1 file changed, 1 insertion(+) diff --git a/livekit-rtc/livekit/rtc/participant.py b/livekit-rtc/livekit/rtc/participant.py index 97319801..496617ae 100644 --- a/livekit-rtc/livekit/rtc/participant.py +++ b/livekit-rtc/livekit/rtc/participant.py @@ -54,6 +54,7 @@ ByteStreamInfo, STREAM_CHUNK_SIZE, ) + if TYPE_CHECKING: from .room import Room From 2c225b4dc42f1b37c7eb91de80f34c183d2d1e0a Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Thu, 13 Mar 2025 10:40:09 -0700 Subject: [PATCH 04/16] fix types --- livekit-rtc/livekit/rtc/participant.py | 5 +---- livekit-rtc/livekit/rtc/room.py | 4 +++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/livekit-rtc/livekit/rtc/participant.py b/livekit-rtc/livekit/rtc/participant.py index 496617ae..9d38dba6 100644 --- a/livekit-rtc/livekit/rtc/participant.py +++ b/livekit-rtc/livekit/rtc/participant.py @@ -15,12 +15,11 @@ from __future__ import annotations import ctypes -import asyncio import os import mimetypes import aiofiles import weakref -from typing import List, Union, Callable, Dict, Awaitable, Optional, Mapping, cast, TYPE_CHECKING +from typing import List, Union, Callable, Dict, Awaitable, Optional, Mapping, TYPE_CHECKING from abc import abstractmethod, ABC from ._ffi_client import FfiClient, FfiHandle @@ -44,8 +43,6 @@ ) from .transcription import Transcription from .rpc import RpcError -from ._proto.rpc_pb2 import RpcMethodInvocationResponseRequest -from .log import logger from .rpc import RpcInvocationData from .data_stream import ( diff --git a/livekit-rtc/livekit/rtc/room.py b/livekit-rtc/livekit/rtc/room.py index 7b87b13d..cf22b71e 100644 --- a/livekit-rtc/livekit/rtc/room.py +++ b/livekit-rtc/livekit/rtc/room.py @@ -17,7 +17,7 @@ import ctypes import logging from dataclasses import dataclass, field -from typing import Callable, Dict, Literal, Optional, cast, Mapping +from typing import Callable, Dict, Literal, Optional, cast, Mapping, Union, Awaitable from .event_emitter import EventEmitter from ._ffi_client import FfiClient, FfiHandle @@ -30,6 +30,7 @@ from ._utils import BroadcastQueue from .e2ee import E2EEManager, E2EEOptions from .participant import LocalParticipant, Participant, RemoteParticipant +from .rpc import RpcInvocationData, RpcError from .track import RemoteAudioTrack, RemoteVideoTrack from .track_publication import RemoteTrackPublication, TrackPublication from .transcription import TranscriptionSegment @@ -39,6 +40,7 @@ TextStreamHandler, ByteStreamHandler, ) +from .log import logger EventTypes = Literal[ From 4a87383adac5fc99e00539b4d62fd937a0d00b40 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Thu, 13 Mar 2025 10:41:29 -0700 Subject: [PATCH 05/16] fix types --- livekit-rtc/livekit/rtc/room.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/livekit-rtc/livekit/rtc/room.py b/livekit-rtc/livekit/rtc/room.py index cf22b71e..ab0cd549 100644 --- a/livekit-rtc/livekit/rtc/room.py +++ b/livekit-rtc/livekit/rtc/room.py @@ -26,7 +26,8 @@ from ._proto import room_pb2 as proto_room from ._proto.room_pb2 import ConnectionState from ._proto.track_pb2 import TrackKind -from ._proto.rpc_pb2 import RpcMethodInvocationEvent +from ._proto.rpc_pb2 import RpcMethodInvocationEvent, RpcMethodInvocationResponseRequest + from ._utils import BroadcastQueue from .e2ee import E2EEManager, E2EEOptions from .participant import LocalParticipant, Participant, RemoteParticipant From 22a4fbe8614b07bacefcdf12be6d4ae0dc4c52fe Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 13 Mar 2025 17:48:57 +0000 Subject: [PATCH 06/16] generated protobuf --- livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py | 12 +----------- livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py | 12 +----------- livekit-rtc/livekit/rtc/_proto/ffi_pb2.py | 12 +----------- livekit-rtc/livekit/rtc/_proto/handle_pb2.py | 12 +----------- livekit-rtc/livekit/rtc/_proto/participant_pb2.py | 12 +----------- livekit-rtc/livekit/rtc/_proto/room_pb2.py | 12 +----------- livekit-rtc/livekit/rtc/_proto/rpc_pb2.py | 12 +----------- livekit-rtc/livekit/rtc/_proto/stats_pb2.py | 12 +----------- livekit-rtc/livekit/rtc/_proto/track_pb2.py | 12 +----------- .../livekit/rtc/_proto/track_publication_pb2.py | 12 +----------- livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py | 12 +----------- 11 files changed, 11 insertions(+), 121 deletions(-) diff --git a/livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py b/livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py index 4684b024..b4007e96 100644 --- a/livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: audio_frame.proto -# Protobuf Python Version: 5.29.3 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 29, - 3, - '', - 'audio_frame.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py b/livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py index 7db50ccb..482deb8a 100644 --- a/livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: e2ee.proto -# Protobuf Python Version: 5.29.3 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 29, - 3, - '', - 'e2ee.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/ffi_pb2.py b/livekit-rtc/livekit/rtc/_proto/ffi_pb2.py index 10590a2f..659b299b 100644 --- a/livekit-rtc/livekit/rtc/_proto/ffi_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/ffi_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: ffi.proto -# Protobuf Python Version: 5.29.3 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 29, - 3, - '', - 'ffi.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/handle_pb2.py b/livekit-rtc/livekit/rtc/_proto/handle_pb2.py index ee00e56b..98d253b4 100644 --- a/livekit-rtc/livekit/rtc/_proto/handle_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/handle_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: handle.proto -# Protobuf Python Version: 5.29.3 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 29, - 3, - '', - 'handle.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/participant_pb2.py b/livekit-rtc/livekit/rtc/_proto/participant_pb2.py index 7095e073..b4425bd1 100644 --- a/livekit-rtc/livekit/rtc/_proto/participant_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/participant_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: participant.proto -# Protobuf Python Version: 5.29.3 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 29, - 3, - '', - 'participant.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/room_pb2.py b/livekit-rtc/livekit/rtc/_proto/room_pb2.py index 364012c8..57baa54d 100644 --- a/livekit-rtc/livekit/rtc/_proto/room_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/room_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: room.proto -# Protobuf Python Version: 5.29.3 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 29, - 3, - '', - 'room.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/rpc_pb2.py b/livekit-rtc/livekit/rtc/_proto/rpc_pb2.py index f7a707c4..ef220fb1 100644 --- a/livekit-rtc/livekit/rtc/_proto/rpc_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/rpc_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: rpc.proto -# Protobuf Python Version: 5.29.3 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 29, - 3, - '', - 'rpc.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/stats_pb2.py b/livekit-rtc/livekit/rtc/_proto/stats_pb2.py index 73119d85..2cbdb1cd 100644 --- a/livekit-rtc/livekit/rtc/_proto/stats_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/stats_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: stats.proto -# Protobuf Python Version: 5.29.3 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 29, - 3, - '', - 'stats.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/track_pb2.py b/livekit-rtc/livekit/rtc/_proto/track_pb2.py index f409ed5c..5e3d1691 100644 --- a/livekit-rtc/livekit/rtc/_proto/track_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/track_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: track.proto -# Protobuf Python Version: 5.29.3 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 29, - 3, - '', - 'track.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/track_publication_pb2.py b/livekit-rtc/livekit/rtc/_proto/track_publication_pb2.py index a4c61ce3..22a19081 100644 --- a/livekit-rtc/livekit/rtc/_proto/track_publication_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/track_publication_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: track_publication.proto -# Protobuf Python Version: 5.29.3 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 29, - 3, - '', - 'track_publication.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py b/livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py index 8ec80f62..bcbd99e9 100644 --- a/livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: video_frame.proto -# Protobuf Python Version: 5.29.3 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 29, - 3, - '', - 'video_frame.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() From a7613915f893fca69ee554ab64c0d240745b05a7 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Thu, 13 Mar 2025 10:48:52 -0700 Subject: [PATCH 07/16] forgot to add this --- livekit-rtc/livekit/rtc/participant.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/livekit-rtc/livekit/rtc/participant.py b/livekit-rtc/livekit/rtc/participant.py index 9d38dba6..953da056 100644 --- a/livekit-rtc/livekit/rtc/participant.py +++ b/livekit-rtc/livekit/rtc/participant.py @@ -159,6 +159,10 @@ def __init__( self._track_publications: dict[str, LocalTrackPublication] = {} # type: ignore self._room_ref = weakref.ref(room) + @property + def room(self) -> Room | None: + return self._room_ref() + @property def track_publications(self) -> Mapping[str, LocalTrackPublication]: """ From ddf8f8e1c4c83b97fc51cf1de1715d90b30b2b33 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Thu, 13 Mar 2025 11:01:10 -0700 Subject: [PATCH 08/16] example --- examples/rpc.py | 8 +- examples/rpc_deprecated.py | 277 ++++++++++++++++++++++++++++++++ livekit-rtc/livekit/rtc/room.py | 2 +- 3 files changed, 282 insertions(+), 5 deletions(-) create mode 100644 examples/rpc_deprecated.py diff --git a/examples/rpc.py b/examples/rpc.py index 005701fa..6aee34ae 100644 --- a/examples/rpc.py +++ b/examples/rpc.py @@ -85,7 +85,7 @@ async def main(): def register_receiver_methods(greeters_room: rtc.Room, math_genius_room: rtc.Room): - @greeters_room.local_participant.register_rpc_method("arrival") + @greeters_room.register_rpc_method("arrival") async def arrival_method( data: RpcInvocationData, ): @@ -93,7 +93,7 @@ async def arrival_method( await asyncio.sleep(2) return "Welcome and have a wonderful day!" - @math_genius_room.local_participant.register_rpc_method("square-root") + @math_genius_room.register_rpc_method("square-root") async def square_root_method( data: RpcInvocationData, ): @@ -110,7 +110,7 @@ async def square_root_method( print(f"[Math Genius] Aha! It's {result}") return json.dumps({"result": result}) - @math_genius_room.local_participant.register_rpc_method("divide") + @math_genius_room.register_rpc_method("divide") async def divide_method( data: RpcInvocationData, ): @@ -122,7 +122,7 @@ async def divide_method( result = dividend / divisor return json.dumps({"result": result}) - @math_genius_room.local_participant.register_rpc_method("long-calculation") + @math_genius_room.register_rpc_method("long-calculation") async def long_calculation_method( data: RpcInvocationData, ): diff --git a/examples/rpc_deprecated.py b/examples/rpc_deprecated.py new file mode 100644 index 00000000..005701fa --- /dev/null +++ b/examples/rpc_deprecated.py @@ -0,0 +1,277 @@ +from livekit import rtc, api +import os +import json +import asyncio +from dotenv import load_dotenv +from livekit.rtc.rpc import RpcInvocationData + +load_dotenv(dotenv_path=".env.local", override=False) +LIVEKIT_API_KEY = os.getenv("LIVEKIT_API_KEY") +LIVEKIT_API_SECRET = os.getenv("LIVEKIT_API_SECRET") +LIVEKIT_URL = os.getenv("LIVEKIT_URL") +if not LIVEKIT_API_KEY or not LIVEKIT_API_SECRET or not LIVEKIT_URL: + raise ValueError("Missing required environment variables. Please check your .env.local file.") + + +async def main(): + rooms = [] # Keep track of all rooms for cleanup + try: + room_name = f"rpc-test-{os.urandom(4).hex()}" + print(f"Connecting participants to room: {room_name}") + + callers_room, greeters_room, math_genius_room = await asyncio.gather( + connect_participant("caller", room_name), + connect_participant("greeter", room_name), + connect_participant("math-genius", room_name), + ) + rooms = [callers_room, greeters_room, math_genius_room] + + register_receiver_methods(greeters_room, math_genius_room) + + try: + print("\n\nRunning greeting example...") + await asyncio.gather(perform_greeting(callers_room)) + except Exception as error: + print("Error:", error) + + try: + print("\n\nRunning error handling example...") + await perform_divide(callers_room) + except Exception as error: + print("Error:", error) + + try: + print("\n\nRunning math example...") + await perform_square_root(callers_room) + await asyncio.sleep(2) + await perform_quantum_hypergeometric_series(callers_room) + except Exception as error: + print("Error:", error) + + try: + print("\n\nRunning long calculation with timeout...") + await asyncio.create_task(perform_long_calculation(callers_room)) + except Exception as error: + print("Error:", error) + + try: + print("\n\nRunning long calculation with disconnect...") + # Start the long calculation + long_calc_task = asyncio.create_task(perform_long_calculation(callers_room)) + # Wait a bit then disconnect the math genius + await asyncio.sleep(5) + print("\nDisconnecting math genius early...") + await math_genius_room.disconnect() + # Wait for the calculation to fail + await long_calc_task + except Exception as error: + print("Error:", error) + + print("\n\nParticipants done, disconnecting remaining participants...") + await callers_room.disconnect() + await greeters_room.disconnect() + + print("Participants disconnected. Example completed.") + + except KeyboardInterrupt: + print("\nReceived interrupt signal, cleaning up...") + except Exception as e: + print(f"Unexpected error: {e}") + finally: + # Clean up all rooms + print("Disconnecting all participants...") + await asyncio.gather(*(room.disconnect() for room in rooms), return_exceptions=True) + print("Cleanup complete") + + +def register_receiver_methods(greeters_room: rtc.Room, math_genius_room: rtc.Room): + @greeters_room.local_participant.register_rpc_method("arrival") + async def arrival_method( + data: RpcInvocationData, + ): + print(f'[Greeter] Oh {data.caller_identity} arrived and said "{data.payload}"') + await asyncio.sleep(2) + return "Welcome and have a wonderful day!" + + @math_genius_room.local_participant.register_rpc_method("square-root") + async def square_root_method( + data: RpcInvocationData, + ): + json_data = json.loads(data.payload) + number = json_data["number"] + print( + f"[Math Genius] I guess {data.caller_identity} wants the square root of {number}. I've only got {data.response_timeout} seconds to respond but I think I can pull it off." + ) + + print("[Math Genius] *doing math*…") + await asyncio.sleep(2) + + result = number**0.5 + print(f"[Math Genius] Aha! It's {result}") + return json.dumps({"result": result}) + + @math_genius_room.local_participant.register_rpc_method("divide") + async def divide_method( + data: RpcInvocationData, + ): + json_data = json.loads(data.payload) + dividend = json_data["dividend"] + divisor = json_data["divisor"] + print(f"[Math Genius] {data.caller_identity} wants to divide {dividend} by {divisor}.") + + result = dividend / divisor + return json.dumps({"result": result}) + + @math_genius_room.local_participant.register_rpc_method("long-calculation") + async def long_calculation_method( + data: RpcInvocationData, + ): + print(f"[Math Genius] Starting a very long calculation for {data.caller_identity}") + print( + f"[Math Genius] This will take 30 seconds even though you're only giving me {data.response_timeout} seconds" + ) + await asyncio.sleep(30) + return json.dumps({"result": "Calculation complete!"}) + + +async def perform_greeting(room: rtc.Room): + print("[Caller] Letting the greeter know that I've arrived") + try: + response = await room.local_participant.perform_rpc( + destination_identity="greeter", method="arrival", payload="Hello" + ) + print(f'[Caller] That\'s nice, the greeter said: "{response}"') + except Exception as error: + print(f"[Caller] RPC call failed: {error}") + raise + + +async def perform_square_root(room: rtc.Room): + print("[Caller] What's the square root of 16?") + try: + response = await room.local_participant.perform_rpc( + destination_identity="math-genius", + method="square-root", + payload=json.dumps({"number": 16}), + ) + parsed_response = json.loads(response) + print(f"[Caller] Nice, the answer was {parsed_response['result']}") + except Exception as error: + print(f"[Caller] RPC call failed: {error}") + raise + + +async def perform_quantum_hypergeometric_series(room: rtc.Room): + print("[Caller] What's the quantum hypergeometric series of 42?") + try: + response = await room.local_participant.perform_rpc( + destination_identity="math-genius", + method="quantum-hypergeometric-series", + payload=json.dumps({"number": 42}), + ) + parsed_response = json.loads(response) + print(f"[Caller] genius says {parsed_response['result']}!") + except rtc.RpcError as error: + if error.code == rtc.RpcError.ErrorCode.UNSUPPORTED_METHOD: + print("[Caller] Aww looks like the genius doesn't know that one.") + return + print("[Caller] Unexpected error:", error) + raise + except Exception as error: + print("[Caller] Unexpected error:", error) + raise + + +async def perform_divide(room: rtc.Room): + print("[Caller] Let's divide 10 by 0.") + try: + response = await room.local_participant.perform_rpc( + destination_identity="math-genius", + method="divide", + payload=json.dumps({"dividend": 10, "divisor": 0}), + ) + parsed_response = json.loads(response) + print(f"[Caller] The result is {parsed_response['result']}") + except rtc.RpcError as error: + if error.code == rtc.RpcError.ErrorCode.APPLICATION_ERROR: + print("[Caller] Aww something went wrong with that one, lets try something else.") + else: + print(f"[Caller] RPC call failed with unexpected RpcError: {error}") + except Exception as error: + print(f"[Caller] RPC call failed with unexpected error: {error}") + + +async def perform_long_calculation(room: rtc.Room): + print("[Caller] Giving the math genius 10s to complete a long calculation") + try: + response = await room.local_participant.perform_rpc( + destination_identity="math-genius", + method="long-calculation", + payload=json.dumps({}), + response_timeout=10, + ) + parsed_response = json.loads(response) + print(f"[Caller] Result: {parsed_response['result']}") + except rtc.RpcError as error: + if error.code == rtc.RpcError.ErrorCode.RESPONSE_TIMEOUT: + print("[Caller] Math genius took too long to respond") + elif error.code == rtc.RpcError.ErrorCode.RECIPIENT_DISCONNECTED: + print("[Caller] Math genius disconnected before response was received") + else: + print(f"[Caller] Unexpected RPC error: {error}") + except Exception as error: + print(f"[Caller] Unexpected error: {error}") + + +def create_token(identity: str, room_name: str): + token = ( + api.AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET) + .with_identity(identity) + .with_grants( + api.VideoGrants( + room=room_name, + room_join=True, + can_publish=True, + can_subscribe=True, + ) + ) + ) + return token.to_jwt() + + +async def connect_participant(identity: str, room_name: str) -> rtc.Room: + room = rtc.Room() + token = create_token(identity, room_name) + + def on_disconnected(reason: str): + print(f"[{identity}] Disconnected from room: {reason}") + + room.on("disconnected", on_disconnected) + + await room.connect(LIVEKIT_URL, token) + + async def wait_for_participants(): + if room.remote_participants: + return + participant_connected = asyncio.Event() + + def _on_participant_connected(participant: rtc.RemoteParticipant): + room.off("participant_connected", _on_participant_connected) + participant_connected.set() + + room.on("participant_connected", _on_participant_connected) + await participant_connected.wait() + + try: + await asyncio.wait_for(wait_for_participants(), timeout=5.0) + except asyncio.TimeoutError: + raise TimeoutError("Timed out waiting for participants") + + return room + + +if __name__ == "__main__": + try: + asyncio.run(main()) + except KeyboardInterrupt: + print("\nProgram terminated by user") diff --git a/livekit-rtc/livekit/rtc/room.py b/livekit-rtc/livekit/rtc/room.py index ab0cd549..887d44bf 100644 --- a/livekit-rtc/livekit/rtc/room.py +++ b/livekit-rtc/livekit/rtc/room.py @@ -952,7 +952,7 @@ async def run_handler(): req = proto_ffi.FfiRequest( rpc_method_invocation_response=RpcMethodInvocationResponseRequest( - local_participant_handle=self._ffi_handle.handle, + local_participant_handle=self._local_participant._ffi_handle.handle, invocation_id=invocation_id, error=response_error._to_proto() if response_error else None, payload=response_payload, From 0a6be2dd119a7bbc0bf564cf3971e895db362c57 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Thu, 13 Mar 2025 11:12:22 -0700 Subject: [PATCH 09/16] type check --- livekit-rtc/livekit/rtc/participant.py | 1 + livekit-rtc/livekit/rtc/room.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/livekit-rtc/livekit/rtc/participant.py b/livekit-rtc/livekit/rtc/participant.py index 953da056..0159d866 100644 --- a/livekit-rtc/livekit/rtc/participant.py +++ b/livekit-rtc/livekit/rtc/participant.py @@ -374,6 +374,7 @@ async def greet_handler(data: RpcInvocationData) -> str: room = self.room if room is not None: return room.register_rpc_method(method_name, handler) + return None def unregister_rpc_method(self, method: str) -> None: """ diff --git a/livekit-rtc/livekit/rtc/room.py b/livekit-rtc/livekit/rtc/room.py index 887d44bf..59b946de 100644 --- a/livekit-rtc/livekit/rtc/room.py +++ b/livekit-rtc/livekit/rtc/room.py @@ -497,6 +497,8 @@ async def greet_handler(data: RpcInvocationData) -> str: """ def register(handler_func): + if self._ffi_handle is None: + raise Exception("cannot register RPC method before room is connected") self._rpc_handlers[method_name] = handler_func req = proto_ffi.FfiRequest() req.register_rpc_method.room_handle = self._ffi_handle.handle @@ -517,6 +519,9 @@ def unregister_rpc_method(self, method: str) -> None: Args: method (str): The name of the RPC method to unregister """ + if self._ffi_handle is None: + raise Exception("cannot unregister RPC method before room is connected") + self._rpc_handlers.pop(method, None) req = proto_ffi.FfiRequest() From 81ad61c50a258f7b8fe76b656c69fdaed6e4e7e3 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Thu, 13 Mar 2025 11:15:43 -0700 Subject: [PATCH 10/16] type check --- livekit-rtc/livekit/rtc/room.py | 1 + 1 file changed, 1 insertion(+) diff --git a/livekit-rtc/livekit/rtc/room.py b/livekit-rtc/livekit/rtc/room.py index 59b946de..876621fa 100644 --- a/livekit-rtc/livekit/rtc/room.py +++ b/livekit-rtc/livekit/rtc/room.py @@ -955,6 +955,7 @@ async def run_handler(): ) response_error = RpcError._built_in(RpcError.ErrorCode.APPLICATION_ERROR) + assert self._local_participant is not None req = proto_ffi.FfiRequest( rpc_method_invocation_response=RpcMethodInvocationResponseRequest( local_participant_handle=self._local_participant._ffi_handle.handle, From 92a2b7c2e6668e43558c9cdd7d00df4541f724cf Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Thu, 13 Mar 2025 11:16:34 -0700 Subject: [PATCH 11/16] add a comment --- livekit-rtc/livekit/rtc/room.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/livekit-rtc/livekit/rtc/room.py b/livekit-rtc/livekit/rtc/room.py index 876621fa..269f7797 100644 --- a/livekit-rtc/livekit/rtc/room.py +++ b/livekit-rtc/livekit/rtc/room.py @@ -955,7 +955,7 @@ async def run_handler(): ) response_error = RpcError._built_in(RpcError.ErrorCode.APPLICATION_ERROR) - assert self._local_participant is not None + assert self._local_participant is not None # _local_participant is guaranteed to be set after connect() req = proto_ffi.FfiRequest( rpc_method_invocation_response=RpcMethodInvocationResponseRequest( local_participant_handle=self._local_participant._ffi_handle.handle, From a8dc08f30cda3fb169ae91462d28882c63ee6e22 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Thu, 13 Mar 2025 11:19:13 -0700 Subject: [PATCH 12/16] fmt --- livekit-rtc/livekit/rtc/room.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/livekit-rtc/livekit/rtc/room.py b/livekit-rtc/livekit/rtc/room.py index 269f7797..81382d12 100644 --- a/livekit-rtc/livekit/rtc/room.py +++ b/livekit-rtc/livekit/rtc/room.py @@ -955,7 +955,8 @@ async def run_handler(): ) response_error = RpcError._built_in(RpcError.ErrorCode.APPLICATION_ERROR) - assert self._local_participant is not None # _local_participant is guaranteed to be set after connect() + # _local_participant is guaranteed to be set after connect() + assert self._local_participant is not None req = proto_ffi.FfiRequest( rpc_method_invocation_response=RpcMethodInvocationResponseRequest( local_participant_handle=self._local_participant._ffi_handle.handle, From b772e5d79d5a0bb6dc14c345076bab20eb943372 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Fri, 14 Mar 2025 09:37:53 -0700 Subject: [PATCH 13/16] remove deprecated example --- examples/rpc_deprecated.py | 277 ------------------------------------- 1 file changed, 277 deletions(-) delete mode 100644 examples/rpc_deprecated.py diff --git a/examples/rpc_deprecated.py b/examples/rpc_deprecated.py deleted file mode 100644 index 005701fa..00000000 --- a/examples/rpc_deprecated.py +++ /dev/null @@ -1,277 +0,0 @@ -from livekit import rtc, api -import os -import json -import asyncio -from dotenv import load_dotenv -from livekit.rtc.rpc import RpcInvocationData - -load_dotenv(dotenv_path=".env.local", override=False) -LIVEKIT_API_KEY = os.getenv("LIVEKIT_API_KEY") -LIVEKIT_API_SECRET = os.getenv("LIVEKIT_API_SECRET") -LIVEKIT_URL = os.getenv("LIVEKIT_URL") -if not LIVEKIT_API_KEY or not LIVEKIT_API_SECRET or not LIVEKIT_URL: - raise ValueError("Missing required environment variables. Please check your .env.local file.") - - -async def main(): - rooms = [] # Keep track of all rooms for cleanup - try: - room_name = f"rpc-test-{os.urandom(4).hex()}" - print(f"Connecting participants to room: {room_name}") - - callers_room, greeters_room, math_genius_room = await asyncio.gather( - connect_participant("caller", room_name), - connect_participant("greeter", room_name), - connect_participant("math-genius", room_name), - ) - rooms = [callers_room, greeters_room, math_genius_room] - - register_receiver_methods(greeters_room, math_genius_room) - - try: - print("\n\nRunning greeting example...") - await asyncio.gather(perform_greeting(callers_room)) - except Exception as error: - print("Error:", error) - - try: - print("\n\nRunning error handling example...") - await perform_divide(callers_room) - except Exception as error: - print("Error:", error) - - try: - print("\n\nRunning math example...") - await perform_square_root(callers_room) - await asyncio.sleep(2) - await perform_quantum_hypergeometric_series(callers_room) - except Exception as error: - print("Error:", error) - - try: - print("\n\nRunning long calculation with timeout...") - await asyncio.create_task(perform_long_calculation(callers_room)) - except Exception as error: - print("Error:", error) - - try: - print("\n\nRunning long calculation with disconnect...") - # Start the long calculation - long_calc_task = asyncio.create_task(perform_long_calculation(callers_room)) - # Wait a bit then disconnect the math genius - await asyncio.sleep(5) - print("\nDisconnecting math genius early...") - await math_genius_room.disconnect() - # Wait for the calculation to fail - await long_calc_task - except Exception as error: - print("Error:", error) - - print("\n\nParticipants done, disconnecting remaining participants...") - await callers_room.disconnect() - await greeters_room.disconnect() - - print("Participants disconnected. Example completed.") - - except KeyboardInterrupt: - print("\nReceived interrupt signal, cleaning up...") - except Exception as e: - print(f"Unexpected error: {e}") - finally: - # Clean up all rooms - print("Disconnecting all participants...") - await asyncio.gather(*(room.disconnect() for room in rooms), return_exceptions=True) - print("Cleanup complete") - - -def register_receiver_methods(greeters_room: rtc.Room, math_genius_room: rtc.Room): - @greeters_room.local_participant.register_rpc_method("arrival") - async def arrival_method( - data: RpcInvocationData, - ): - print(f'[Greeter] Oh {data.caller_identity} arrived and said "{data.payload}"') - await asyncio.sleep(2) - return "Welcome and have a wonderful day!" - - @math_genius_room.local_participant.register_rpc_method("square-root") - async def square_root_method( - data: RpcInvocationData, - ): - json_data = json.loads(data.payload) - number = json_data["number"] - print( - f"[Math Genius] I guess {data.caller_identity} wants the square root of {number}. I've only got {data.response_timeout} seconds to respond but I think I can pull it off." - ) - - print("[Math Genius] *doing math*…") - await asyncio.sleep(2) - - result = number**0.5 - print(f"[Math Genius] Aha! It's {result}") - return json.dumps({"result": result}) - - @math_genius_room.local_participant.register_rpc_method("divide") - async def divide_method( - data: RpcInvocationData, - ): - json_data = json.loads(data.payload) - dividend = json_data["dividend"] - divisor = json_data["divisor"] - print(f"[Math Genius] {data.caller_identity} wants to divide {dividend} by {divisor}.") - - result = dividend / divisor - return json.dumps({"result": result}) - - @math_genius_room.local_participant.register_rpc_method("long-calculation") - async def long_calculation_method( - data: RpcInvocationData, - ): - print(f"[Math Genius] Starting a very long calculation for {data.caller_identity}") - print( - f"[Math Genius] This will take 30 seconds even though you're only giving me {data.response_timeout} seconds" - ) - await asyncio.sleep(30) - return json.dumps({"result": "Calculation complete!"}) - - -async def perform_greeting(room: rtc.Room): - print("[Caller] Letting the greeter know that I've arrived") - try: - response = await room.local_participant.perform_rpc( - destination_identity="greeter", method="arrival", payload="Hello" - ) - print(f'[Caller] That\'s nice, the greeter said: "{response}"') - except Exception as error: - print(f"[Caller] RPC call failed: {error}") - raise - - -async def perform_square_root(room: rtc.Room): - print("[Caller] What's the square root of 16?") - try: - response = await room.local_participant.perform_rpc( - destination_identity="math-genius", - method="square-root", - payload=json.dumps({"number": 16}), - ) - parsed_response = json.loads(response) - print(f"[Caller] Nice, the answer was {parsed_response['result']}") - except Exception as error: - print(f"[Caller] RPC call failed: {error}") - raise - - -async def perform_quantum_hypergeometric_series(room: rtc.Room): - print("[Caller] What's the quantum hypergeometric series of 42?") - try: - response = await room.local_participant.perform_rpc( - destination_identity="math-genius", - method="quantum-hypergeometric-series", - payload=json.dumps({"number": 42}), - ) - parsed_response = json.loads(response) - print(f"[Caller] genius says {parsed_response['result']}!") - except rtc.RpcError as error: - if error.code == rtc.RpcError.ErrorCode.UNSUPPORTED_METHOD: - print("[Caller] Aww looks like the genius doesn't know that one.") - return - print("[Caller] Unexpected error:", error) - raise - except Exception as error: - print("[Caller] Unexpected error:", error) - raise - - -async def perform_divide(room: rtc.Room): - print("[Caller] Let's divide 10 by 0.") - try: - response = await room.local_participant.perform_rpc( - destination_identity="math-genius", - method="divide", - payload=json.dumps({"dividend": 10, "divisor": 0}), - ) - parsed_response = json.loads(response) - print(f"[Caller] The result is {parsed_response['result']}") - except rtc.RpcError as error: - if error.code == rtc.RpcError.ErrorCode.APPLICATION_ERROR: - print("[Caller] Aww something went wrong with that one, lets try something else.") - else: - print(f"[Caller] RPC call failed with unexpected RpcError: {error}") - except Exception as error: - print(f"[Caller] RPC call failed with unexpected error: {error}") - - -async def perform_long_calculation(room: rtc.Room): - print("[Caller] Giving the math genius 10s to complete a long calculation") - try: - response = await room.local_participant.perform_rpc( - destination_identity="math-genius", - method="long-calculation", - payload=json.dumps({}), - response_timeout=10, - ) - parsed_response = json.loads(response) - print(f"[Caller] Result: {parsed_response['result']}") - except rtc.RpcError as error: - if error.code == rtc.RpcError.ErrorCode.RESPONSE_TIMEOUT: - print("[Caller] Math genius took too long to respond") - elif error.code == rtc.RpcError.ErrorCode.RECIPIENT_DISCONNECTED: - print("[Caller] Math genius disconnected before response was received") - else: - print(f"[Caller] Unexpected RPC error: {error}") - except Exception as error: - print(f"[Caller] Unexpected error: {error}") - - -def create_token(identity: str, room_name: str): - token = ( - api.AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET) - .with_identity(identity) - .with_grants( - api.VideoGrants( - room=room_name, - room_join=True, - can_publish=True, - can_subscribe=True, - ) - ) - ) - return token.to_jwt() - - -async def connect_participant(identity: str, room_name: str) -> rtc.Room: - room = rtc.Room() - token = create_token(identity, room_name) - - def on_disconnected(reason: str): - print(f"[{identity}] Disconnected from room: {reason}") - - room.on("disconnected", on_disconnected) - - await room.connect(LIVEKIT_URL, token) - - async def wait_for_participants(): - if room.remote_participants: - return - participant_connected = asyncio.Event() - - def _on_participant_connected(participant: rtc.RemoteParticipant): - room.off("participant_connected", _on_participant_connected) - participant_connected.set() - - room.on("participant_connected", _on_participant_connected) - await participant_connected.wait() - - try: - await asyncio.wait_for(wait_for_participants(), timeout=5.0) - except asyncio.TimeoutError: - raise TimeoutError("Timed out waiting for participants") - - return room - - -if __name__ == "__main__": - try: - asyncio.run(main()) - except KeyboardInterrupt: - print("\nProgram terminated by user") From 12c063e9218395641516734e567f19844022a4d5 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 14 Mar 2025 16:38:30 +0000 Subject: [PATCH 14/16] generated protobuf --- livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py | 6 +++--- livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py | 6 +++--- livekit-rtc/livekit/rtc/_proto/ffi_pb2.py | 6 +++--- livekit-rtc/livekit/rtc/_proto/handle_pb2.py | 6 +++--- livekit-rtc/livekit/rtc/_proto/participant_pb2.py | 8 ++++---- livekit-rtc/livekit/rtc/_proto/room_pb2.py | 12 ++++++------ livekit-rtc/livekit/rtc/_proto/rpc_pb2.py | 6 +++--- livekit-rtc/livekit/rtc/_proto/stats_pb2.py | 8 ++++---- livekit-rtc/livekit/rtc/_proto/track_pb2.py | 6 +++--- .../livekit/rtc/_proto/track_publication_pb2.py | 6 +++--- livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py | 6 +++--- 11 files changed, 38 insertions(+), 38 deletions(-) diff --git a/livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py b/livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py index b4007e96..8b11da4c 100644 --- a/livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/audio_frame_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: audio_frame.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -21,8 +21,8 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'audio_frame_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\252\002\rLiveKit.Proto' _globals['_SOXRESAMPLERDATATYPE']._serialized_start=4262 _globals['_SOXRESAMPLERDATATYPE']._serialized_end=4336 diff --git a/livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py b/livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py index 482deb8a..0b5f8554 100644 --- a/livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/e2ee_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: e2ee.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -19,8 +19,8 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'e2ee_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\252\002\rLiveKit.Proto' _globals['_ENCRYPTIONTYPE']._serialized_start=2856 _globals['_ENCRYPTIONTYPE']._serialized_end=2903 diff --git a/livekit-rtc/livekit/rtc/_proto/ffi_pb2.py b/livekit-rtc/livekit/rtc/_proto/ffi_pb2.py index 659b299b..0b009bbc 100644 --- a/livekit-rtc/livekit/rtc/_proto/ffi_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/ffi_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: ffi.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -26,8 +26,8 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'ffi_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\252\002\rLiveKit.Proto' _globals['_LOGLEVEL']._serialized_start=9392 _globals['_LOGLEVEL']._serialized_end=9475 diff --git a/livekit-rtc/livekit/rtc/_proto/handle_pb2.py b/livekit-rtc/livekit/rtc/_proto/handle_pb2.py index 98d253b4..2ae2db78 100644 --- a/livekit-rtc/livekit/rtc/_proto/handle_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/handle_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: handle.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -19,8 +19,8 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'handle_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\252\002\rLiveKit.Proto' _globals['_FFIOWNEDHANDLE']._serialized_start=31 _globals['_FFIOWNEDHANDLE']._serialized_end=59 diff --git a/livekit-rtc/livekit/rtc/_proto/participant_pb2.py b/livekit-rtc/livekit/rtc/_proto/participant_pb2.py index b4425bd1..4a2ef4ed 100644 --- a/livekit-rtc/livekit/rtc/_proto/participant_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/participant_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: participant.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -20,10 +20,10 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'participant_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\252\002\rLiveKit.Proto' - _globals['_PARTICIPANTINFO_ATTRIBUTESENTRY']._loaded_options = None + _globals['_PARTICIPANTINFO_ATTRIBUTESENTRY']._options = None _globals['_PARTICIPANTINFO_ATTRIBUTESENTRY']._serialized_options = b'8\001' _globals['_PARTICIPANTKIND']._serialized_start=472 _globals['_PARTICIPANTKIND']._serialized_end=633 diff --git a/livekit-rtc/livekit/rtc/_proto/room_pb2.py b/livekit-rtc/livekit/rtc/_proto/room_pb2.py index 57baa54d..bf34ff21 100644 --- a/livekit-rtc/livekit/rtc/_proto/room_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/room_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: room.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -25,14 +25,14 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'room_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\252\002\rLiveKit.Proto' - _globals['_PUBLISHDATAREQUEST'].fields_by_name['destination_sids']._loaded_options = None + _globals['_PUBLISHDATAREQUEST'].fields_by_name['destination_sids']._options = None _globals['_PUBLISHDATAREQUEST'].fields_by_name['destination_sids']._serialized_options = b'\030\001' - _globals['_DATASTREAM_HEADER_ATTRIBUTESENTRY']._loaded_options = None + _globals['_DATASTREAM_HEADER_ATTRIBUTESENTRY']._options = None _globals['_DATASTREAM_HEADER_ATTRIBUTESENTRY']._serialized_options = b'8\001' - _globals['_DATASTREAM_TRAILER_ATTRIBUTESENTRY']._loaded_options = None + _globals['_DATASTREAM_TRAILER_ATTRIBUTESENTRY']._options = None _globals['_DATASTREAM_TRAILER_ATTRIBUTESENTRY']._serialized_options = b'8\001' _globals['_ICETRANSPORTTYPE']._serialized_start=12048 _globals['_ICETRANSPORTTYPE']._serialized_end=12128 diff --git a/livekit-rtc/livekit/rtc/_proto/rpc_pb2.py b/livekit-rtc/livekit/rtc/_proto/rpc_pb2.py index ef220fb1..14fc4e24 100644 --- a/livekit-rtc/livekit/rtc/_proto/rpc_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/rpc_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: rpc.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -19,8 +19,8 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'rpc_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\252\002\rLiveKit.Proto' _globals['_RPCERROR']._serialized_start=28 _globals['_RPCERROR']._serialized_end=83 diff --git a/livekit-rtc/livekit/rtc/_proto/stats_pb2.py b/livekit-rtc/livekit/rtc/_proto/stats_pb2.py index 2cbdb1cd..ce7b411c 100644 --- a/livekit-rtc/livekit/rtc/_proto/stats_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/stats_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: stats.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -19,10 +19,10 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'stats_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\252\002\rLiveKit.Proto' - _globals['_OUTBOUNDRTPSTREAMSTATS_QUALITYLIMITATIONDURATIONSENTRY']._loaded_options = None + _globals['_OUTBOUNDRTPSTREAMSTATS_QUALITYLIMITATIONDURATIONSENTRY']._options = None _globals['_OUTBOUNDRTPSTREAMSTATS_QUALITYLIMITATIONDURATIONSENTRY']._serialized_options = b'8\001' _globals['_DATACHANNELSTATE']._serialized_start=9282 _globals['_DATACHANNELSTATE']._serialized_end=9363 diff --git a/livekit-rtc/livekit/rtc/_proto/track_pb2.py b/livekit-rtc/livekit/rtc/_proto/track_pb2.py index 5e3d1691..1fc2984b 100644 --- a/livekit-rtc/livekit/rtc/_proto/track_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/track_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: track.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -22,8 +22,8 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'track_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\252\002\rLiveKit.Proto' _globals['_TRACKKIND']._serialized_start=1743 _globals['_TRACKKIND']._serialized_end=1804 diff --git a/livekit-rtc/livekit/rtc/_proto/track_publication_pb2.py b/livekit-rtc/livekit/rtc/_proto/track_publication_pb2.py index 22a19081..32d23be6 100644 --- a/livekit-rtc/livekit/rtc/_proto/track_publication_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/track_publication_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: track_publication.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -19,8 +19,8 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'track_publication_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\252\002\rLiveKit.Proto' _globals['_ENABLEREMOTETRACKPUBLICATIONREQUEST']._serialized_start=42 _globals['_ENABLEREMOTETRACKPUBLICATIONREQUEST']._serialized_end=130 diff --git a/livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py b/livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py index bcbd99e9..8dbc3805 100644 --- a/livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/video_frame_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: video_frame.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -21,8 +21,8 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'video_frame_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'\252\002\rLiveKit.Proto' _globals['_VIDEOCODEC']._serialized_start=2452 _globals['_VIDEOCODEC']._serialized_end=2501 From 04e5e0644a6143aca8a639c5cca5b4251db4a80b Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Fri, 14 Mar 2025 09:42:58 -0700 Subject: [PATCH 15/16] use deprecated module --- livekit-rtc/livekit/rtc/participant.py | 3 +++ livekit-rtc/setup.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/livekit-rtc/livekit/rtc/participant.py b/livekit-rtc/livekit/rtc/participant.py index 0159d866..e2e4519d 100644 --- a/livekit-rtc/livekit/rtc/participant.py +++ b/livekit-rtc/livekit/rtc/participant.py @@ -21,6 +21,7 @@ import weakref from typing import List, Union, Callable, Dict, Awaitable, Optional, Mapping, TYPE_CHECKING from abc import abstractmethod, ABC +from deprecated import deprecated from ._ffi_client import FfiClient, FfiHandle from ._proto import ffi_pb2 as proto_ffi @@ -329,6 +330,7 @@ async def perform_rpc( return cb.perform_rpc.payload + @deprecated(reason="Use room.register_rpc_method instead.") def register_rpc_method( self, method_name: str, @@ -376,6 +378,7 @@ async def greet_handler(data: RpcInvocationData) -> str: return room.register_rpc_method(method_name, handler) return None + @deprecated(reason="Use room.unregister_rpc_method instead.") def unregister_rpc_method(self, method: str) -> None: """ Deprecated diff --git a/livekit-rtc/setup.py b/livekit-rtc/setup.py index 71ec85f4..df63c9b6 100644 --- a/livekit-rtc/setup.py +++ b/livekit-rtc/setup.py @@ -58,7 +58,7 @@ def finalize_options(self): license="Apache-2.0", packages=setuptools.find_namespace_packages(include=["livekit.*"]), python_requires=">=3.9.0", - install_requires=["protobuf>=5.26.1", "types-protobuf>=3", "aiofiles>=24"], + install_requires=["protobuf>=5.26.1", "types-protobuf>=3", "aiofiles>=24", "deprecated>=1.2.18"], package_data={ "livekit.rtc": ["_proto/*.py", "py.typed", "*.pyi", "**/*.pyi"], "livekit.rtc.resources": ["*.so", "*.dylib", "*.dll", "LICENSE.md", "*.h"], From 0dfb13b7f1d409e062603047136a7ae7f1a48c63 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Fri, 14 Mar 2025 09:49:49 -0700 Subject: [PATCH 16/16] ruff --- livekit-rtc/setup.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/livekit-rtc/setup.py b/livekit-rtc/setup.py index 30b58e00..3795c79e 100644 --- a/livekit-rtc/setup.py +++ b/livekit-rtc/setup.py @@ -58,7 +58,12 @@ def finalize_options(self): license="Apache-2.0", packages=setuptools.find_namespace_packages(include=["livekit.*"]), python_requires=">=3.9.0", - install_requires=["protobuf>=4.25.0", "types-protobuf>=3", "aiofiles>=24", "deprecated>=1.2.18"], + install_requires=[ + "protobuf>=4.25.0", + "types-protobuf>=3", + "aiofiles>=24", + "deprecated>=1.2.18", + ], package_data={ "livekit.rtc": ["_proto/*.py", "py.typed", "*.pyi", "**/*.pyi"], "livekit.rtc.resources": ["*.so", "*.dylib", "*.dll", "LICENSE.md", "*.h"],