reactor-sdk 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,203 @@
1
+ """
2
+ Reactor - Public API for the Reactor SDK.
3
+
4
+ This module defines the Reactor class that users interact with.
5
+ Internal implementation details are hidden in the reactor module.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, Union
11
+
12
+ from aiortc import MediaStreamTrack
13
+
14
+ from reactor_sdk.types import (
15
+ FrameCallback,
16
+ ReactorError,
17
+ ReactorEvent,
18
+ ReactorState,
19
+ ReactorStatus,
20
+ )
21
+
22
+ # Type variable for decorator return types
23
+ F = TypeVar("F", bound=Callable[..., Any])
24
+
25
+ # Type for event handlers
26
+ EventHandler = Callable[..., None]
27
+
28
+ # Default coordinator URL
29
+ PROD_COORDINATOR_URL = "https://api.reactor.inc"
30
+
31
+
32
+ class Reactor:
33
+ """
34
+ Main entry point for the Reactor SDK.
35
+
36
+ Provides real-time AI video streaming via WebRTC.
37
+
38
+ Example:
39
+ from reactor_sdk import Reactor, ReactorStatus
40
+
41
+ reactor = Reactor(model_name="my-model", api_key="your-api-key")
42
+
43
+ @reactor.on_frame
44
+ def handle_frame(frame):
45
+ print(f"Frame shape: {frame.shape}")
46
+
47
+ @reactor.on_status(ReactorStatus.READY)
48
+ def handle_ready(status):
49
+ print("Connected!")
50
+
51
+ await reactor.connect()
52
+ await reactor.send_command("setParameter", {"value": 0.5})
53
+ await reactor.disconnect()
54
+ """
55
+
56
+ def __new__(
57
+ cls,
58
+ model_name: str,
59
+ api_key: Optional[str] = None,
60
+ coordinator_url: str = PROD_COORDINATOR_URL,
61
+ local: bool = False,
62
+ ) -> "Reactor":
63
+ """
64
+ Create a new Reactor instance.
65
+
66
+ Args:
67
+ model_name: Name of the model to connect to.
68
+ api_key: Your Reactor API key. The SDK will automatically fetch
69
+ a JWT token using this key. Required unless local=True.
70
+ coordinator_url: URL of the coordinator API (ignored if local=True).
71
+ local: If True, use local coordinator at localhost:8080.
72
+
73
+ Returns:
74
+ A Reactor instance ready to be connected.
75
+ """
76
+ # Import here to avoid circular imports
77
+ from reactor_sdk.reactor import _ReactorImpl
78
+
79
+ return _ReactorImpl( # type: ignore[return-value]
80
+ model_name=model_name,
81
+ api_key=api_key,
82
+ coordinator_url=coordinator_url,
83
+ local=local,
84
+ )
85
+
86
+ # =========================================================================
87
+ # Event Registration
88
+ # =========================================================================
89
+
90
+ def on(self, event: ReactorEvent, handler: EventHandler) -> None:
91
+ """Register an event handler."""
92
+ ...
93
+
94
+ def off(self, event: ReactorEvent, handler: EventHandler) -> None:
95
+ """Unregister an event handler."""
96
+ ...
97
+
98
+ # =========================================================================
99
+ # Decorators
100
+ # =========================================================================
101
+
102
+ def on_frame(self, func: F) -> F:
103
+ """Decorator to register a frame callback."""
104
+ ...
105
+
106
+ def on_message(self, func: F) -> F:
107
+ """Decorator to register a message handler."""
108
+ ...
109
+
110
+ def on_status(
111
+ self,
112
+ func_or_filter: Union[F, ReactorStatus, list[ReactorStatus], None] = None,
113
+ ) -> Union[F, Callable[[F], F]]:
114
+ """Decorator to register a status change handler (with optional filter)."""
115
+ ...
116
+
117
+ def on_error(self, func: F) -> F:
118
+ """Decorator to register an error handler."""
119
+ ...
120
+
121
+ def on_stream(self, func: F) -> F:
122
+ """Decorator to register a stream/track handler."""
123
+ ...
124
+
125
+ # =========================================================================
126
+ # Connection
127
+ # =========================================================================
128
+
129
+ async def connect(self) -> None:
130
+ """Connect to the coordinator and model."""
131
+ ...
132
+
133
+ async def reconnect(self) -> None:
134
+ """Reconnect to an existing session."""
135
+ ...
136
+
137
+ async def disconnect(self, recoverable: bool = False) -> None:
138
+ """Disconnect from the coordinator and model."""
139
+ ...
140
+
141
+ # =========================================================================
142
+ # Communication
143
+ # =========================================================================
144
+
145
+ async def send_command(self, command: str, data: Any) -> None:
146
+ """Send a command to the model."""
147
+ ...
148
+
149
+ # =========================================================================
150
+ # Track Publishing
151
+ # =========================================================================
152
+
153
+ async def publish_track(self, track: MediaStreamTrack) -> None:
154
+ """Publish a video track to the model."""
155
+ ...
156
+
157
+ async def unpublish_track(self) -> None:
158
+ """Unpublish the currently published track."""
159
+ ...
160
+
161
+ # =========================================================================
162
+ # Frame Callback
163
+ # =========================================================================
164
+
165
+ def set_frame_callback(self, callback: Optional[FrameCallback]) -> None:
166
+ """Set a callback to receive individual video frames."""
167
+ ...
168
+
169
+ # =========================================================================
170
+ # State Accessors
171
+ # =========================================================================
172
+
173
+ def get_remote_track(self) -> Optional[MediaStreamTrack]:
174
+ """Get the remote video track from the model."""
175
+ ...
176
+
177
+ def get_status(self) -> ReactorStatus:
178
+ """Get the current connection status."""
179
+ ...
180
+
181
+ def get_state(self) -> ReactorState:
182
+ """Get the current state including status and error info."""
183
+ ...
184
+
185
+ def get_session_id(self) -> Optional[str]:
186
+ """Get the current session ID."""
187
+ ...
188
+
189
+ def get_last_error(self) -> Optional[ReactorError]:
190
+ """Get the last error that occurred."""
191
+ ...
192
+
193
+ # =========================================================================
194
+ # Context Manager
195
+ # =========================================================================
196
+
197
+ async def __aenter__(self) -> "Reactor":
198
+ """Async context manager entry."""
199
+ ...
200
+
201
+ async def __aexit__(self, *args: object) -> None:
202
+ """Async context manager exit."""
203
+ ...
@@ -0,0 +1,11 @@
1
+ """
2
+ Model client for the Reactor SDK.
3
+
4
+ This module contains the client for WebRTC communication with the model.
5
+ """
6
+
7
+ from reactor_sdk.model.client import ModelClient
8
+
9
+ __all__ = [
10
+ "ModelClient",
11
+ ]