Skip to content

Commit 8a42147

Browse files
committed
params
1 parent fe07bd4 commit 8a42147

File tree

3 files changed

+47
-50
lines changed

3 files changed

+47
-50
lines changed

examples/rpc.py

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import json
44
import asyncio
55
from dotenv import load_dotenv
6-
import time
7-
6+
from livekit.rtc.rpc import RpcHandlerParams
87
load_dotenv(dotenv_path=".env.local", override=False)
98
LIVEKIT_API_KEY = os.getenv("LIVEKIT_API_KEY")
109
LIVEKIT_API_SECRET = os.getenv("LIVEKIT_API_SECRET")
@@ -91,26 +90,20 @@ async def main():
9190
def register_receiver_methods(greeters_room: rtc.Room, math_genius_room: rtc.Room):
9291
@greeters_room.local_participant.rpc_method("arrival")
9392
async def arrival_method(
94-
request_id: str,
95-
caller_identity: str,
96-
payload: str,
97-
response_timeout: float,
93+
params: RpcHandlerParams,
9894
):
99-
print(f'[Greeter] Oh {caller_identity} arrived and said "{payload}"')
95+
print(f'[Greeter] Oh {params.caller_identity} arrived and said "{params.payload}"')
10096
await asyncio.sleep(2)
10197
return "Welcome and have a wonderful day!"
10298

10399
@math_genius_room.local_participant.rpc_method("square-root")
104100
async def square_root_method(
105-
request_id: str,
106-
caller_identity: str,
107-
payload: str,
108-
response_timeout: float,
101+
params: RpcHandlerParams,
109102
):
110-
json_data = json.loads(payload)
103+
json_data = json.loads(params.payload)
111104
number = json_data["number"]
112105
print(
113-
f"[Math Genius] I guess {caller_identity} wants the square root of {number}. I've only got {response_timeout} seconds to respond but I think I can pull it off."
106+
f"[Math Genius] I guess {params.caller_identity} wants the square root of {number}. I've only got {params.response_timeout} seconds to respond but I think I can pull it off."
114107
)
115108

116109
print("[Math Genius] *doing math*…")
@@ -121,32 +114,26 @@ async def square_root_method(
121114
return json.dumps({"result": result})
122115

123116
@math_genius_room.local_participant.rpc_method("divide")
124-
def divide_method(
125-
request_id: str,
126-
caller_identity: str,
127-
payload: str,
128-
response_timeout: float,
117+
async def divide_method(
118+
params: RpcHandlerParams,
129119
):
130-
json_data = json.loads(payload)
120+
json_data = json.loads(params.payload)
131121
dividend = json_data["dividend"]
132122
divisor = json_data["divisor"]
133123
print(
134-
f"[Math Genius] {caller_identity} wants to divide {dividend} by {divisor}."
124+
f"[Math Genius] {params.caller_identity} wants to divide {dividend} by {divisor}."
135125
)
136126

137127
result = dividend / divisor
138128
return json.dumps({"result": result})
139129

140130
@math_genius_room.local_participant.rpc_method("long-calculation")
141131
async def long_calculation_method(
142-
request_id: str,
143-
caller_identity: str,
144-
payload: str,
145-
response_timeout: float,
132+
params: RpcHandlerParams,
146133
):
147-
print(f"[Math Genius] Starting a very long calculation for {caller_identity}")
134+
print(f"[Math Genius] Starting a very long calculation for {params.caller_identity}")
148135
print(
149-
f"[Math Genius] This will take 30 seconds even though you're only giving me {response_timeout} seconds"
136+
f"[Math Genius] This will take 30 seconds even though you're only giving me {params.response_timeout} seconds"
150137
)
151138
await asyncio.sleep(30)
152139
return json.dumps({"result": "Calculation complete!"})

livekit-rtc/livekit/rtc/participant.py

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from .log import logger
4141
import asyncio
4242

43+
from .rpc import RpcHandlerParams
4344

4445
class PublishTrackError(Exception):
4546
def __init__(self, message: str) -> None:
@@ -118,7 +119,7 @@ def __init__(
118119
self._room_queue = room_queue
119120
self._track_publications: dict[str, LocalTrackPublication] = {} # type: ignore
120121
self._rpc_handlers: Dict[
121-
str, Callable[[str, str, str, float], Union[Awaitable[str], str]]
122+
str, Callable[[RpcHandlerParams], Union[Awaitable[str], str]]
122123
] = {}
123124

124125
@property
@@ -291,7 +292,7 @@ async def perform_rpc(
291292
def register_rpc_method(
292293
self,
293294
method: str,
294-
handler: Callable[[str, str, str, float], Union[Awaitable[str], str]],
295+
handler: Callable[[RpcHandlerParams], Union[Awaitable[str], str]],
295296
) -> None:
296297
"""
297298
Establishes the participant as a receiver for calls of the specified RPC method.
@@ -308,20 +309,15 @@ def register_rpc_method(
308309
RpcError: On failure. Details in `message`.
309310
310311
Example:
311-
async def greet_handler(request_id: str, caller_identity: str, payload: str, response_timeout: float) -> str:
312-
print(f"Received greeting from {caller_identity}: {payload}")
313-
return f"Hello, {caller_identity}!"
312+
async def greet_handler(params: RpcHandlerParams) -> str:
313+
print(f"Received greeting from {params.caller_identity}: {params.payload}")
314+
return f"Hello, {params.caller_identity}!"
314315
315316
await room.local_participant.register_rpc_method('greet', greet_handler)
316317
317-
The handler receives the following parameters:
318-
- `request_id`: A unique identifier for this RPC request
319-
- `caller_identity`: The identity of the RemoteParticipant who initiated the RPC call
320-
- `payload`: The data sent by the caller (as a string)
321-
- `response_timeout`: The maximum time available to return a response
322-
323318
The handler should return a string or a coroutine that resolves to a string.
324-
If unable to respond within `response_timeout`, the request will result in an error on the caller's side.
319+
320+
If unable to respond within `response_timeout`, the caller will hang up and receive an error on their side.
325321
326322
You may raise errors of type `RpcError` with a string `message` in the handler,
327323
and they will be received on the caller's side with the message intact.
@@ -344,16 +340,16 @@ def rpc_method(self, method: str):
344340
345341
Example:
346342
@local_participant.rpc_method("greet")
347-
async def greet_handler(request_id: str, caller_identity: str, payload: str, response_timeout: float) -> str:
348-
print(f"Received greeting from {caller_identity}: {payload}")
349-
return f"Hello, {caller_identity}!"
343+
async def greet_handler(params: RpcHandlerParams) -> str:
344+
print(f"Received greeting from {params.caller_identity}: {params.payload}")
345+
return f"Hello, {params.caller_identity}!"
350346
351347
See Also:
352348
`register_rpc_method` for more details
353349
"""
354350

355351
def decorator(
356-
handler: Callable[[str, str, str, float], Union[Awaitable[str], str]],
352+
handler: Callable[[RpcHandlerParams], Union[Awaitable[str], str]],
357353
):
358354
self.register_rpc_method(method, handler)
359355
return handler
@@ -386,6 +382,8 @@ async def _handle_rpc_method_invocation(
386382
) -> None:
387383
response_error: Optional[RpcError] = None
388384
response_payload: Optional[str] = None
385+
386+
params = RpcHandlerParams(request_id, caller_identity, payload, response_timeout)
389387

390388
handler = self._rpc_handlers.get(method)
391389

@@ -394,13 +392,11 @@ async def _handle_rpc_method_invocation(
394392
else:
395393
try:
396394
if asyncio.iscoroutinefunction(handler):
397-
async_handler = handler # type: Callable[[str, str, str, float], Awaitable[str]]
395+
async_handler = handler # type: Callable[[RpcHandlerParams], Awaitable[str]]
398396

399397
async def run_handler():
400398
try:
401-
return await async_handler(
402-
request_id, caller_identity, payload, response_timeout
403-
)
399+
return await async_handler(params)
404400
except asyncio.CancelledError:
405401
# This will be caught by the outer try-except if it's due to timeout
406402
raise
@@ -416,10 +412,8 @@ async def run_handler():
416412
RpcError.ErrorCode.RECIPIENT_DISCONNECTED
417413
)
418414
else:
419-
sync_handler = handler # type: Callable[[str, str, str, float], str]
420-
response_payload = sync_handler(
421-
request_id, caller_identity, payload, response_timeout
422-
)
415+
sync_handler = handler # type: Callable[[RpcHandlerParams], str]
416+
response_payload = sync_handler(params)
423417
except RpcError as error:
424418
response_error = error
425419
except Exception as error:

livekit-rtc/livekit/rtc/rpc.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@
1515
from typing import Optional, Dict, Union, ClassVar
1616
from enum import IntEnum
1717
from ._proto import rpc_pb2 as proto_rpc
18+
from dataclasses import dataclass
19+
20+
@dataclass
21+
class RpcHandlerParams:
22+
"""Parameters passed to method handler for incoming RPC invocations
23+
24+
Attributes:
25+
request_id (str): The unique request ID. Will match at both sides of the call, useful for debugging or logging.
26+
caller_identity (str): The unique participant identity of the caller.
27+
payload (str): The payload of the request. User-definable format, typically JSON.
28+
response_timeout (float): The maximum time the caller will wait for a response.
29+
"""
30+
request_id: str
31+
caller_identity: str
32+
payload: str
33+
response_timeout: float
1834

1935

2036
class RpcError(Exception):

0 commit comments

Comments
 (0)