hypha-rpc 0.20.88__tar.gz → 0.20.90__tar.gz

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.
Files changed (34) hide show
  1. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/PKG-INFO +1 -1
  2. hypha_rpc-0.20.90/hypha_rpc/VERSION +3 -0
  3. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/http_client.py +78 -1
  4. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc.egg-info/PKG-INFO +1 -1
  5. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/pyproject.toml +1 -1
  6. hypha_rpc-0.20.88/hypha_rpc/VERSION +0 -3
  7. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/MANIFEST.in +0 -0
  8. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/README.md +0 -0
  9. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/__init__.py +0 -0
  10. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/client.py +0 -0
  11. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/pyodide_sse.py +0 -0
  12. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/pyodide_websocket.py +0 -0
  13. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/rpc.py +0 -0
  14. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/sync.py +0 -0
  15. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/utils/__init__.py +0 -0
  16. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/utils/launch.py +0 -0
  17. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/utils/mcp.py +0 -0
  18. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/utils/pydantic.py +0 -0
  19. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/utils/schema.py +0 -0
  20. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/utils/serve.py +0 -0
  21. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/webrtc_client.py +0 -0
  22. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc/websocket_client.py +0 -0
  23. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc.egg-info/SOURCES.txt +0 -0
  24. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc.egg-info/dependency_links.txt +0 -0
  25. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc.egg-info/requires.txt +0 -0
  26. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/hypha_rpc.egg-info/top_level.txt +0 -0
  27. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/setup.cfg +0 -0
  28. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/tests/test_mcp.py +0 -0
  29. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/tests/test_reconnection_runner.py +0 -0
  30. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/tests/test_reconnection_stability.py +0 -0
  31. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/tests/test_schema.py +0 -0
  32. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/tests/test_server_compatibility.py +0 -0
  33. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/tests/test_utils.py +0 -0
  34. {hypha_rpc-0.20.88 → hypha_rpc-0.20.90}/tests/test_websocket_rpc.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hypha_rpc
3
- Version: 0.20.88
3
+ Version: 0.20.90
4
4
  Summary: Hypha RPC client for connecting to Hypha server for data management and AI model serving
5
5
  Author-email: Wei Ouyang <oeway007@gmail.com>
6
6
  Requires-Python: >=3.9
@@ -0,0 +1,3 @@
1
+ {
2
+ "version": "0.20.90"
3
+ }
@@ -89,6 +89,7 @@ class HTTPStreamingRPCConnection:
89
89
  self._closed = False
90
90
  self._enable_reconnect = False
91
91
  self._stream_task: Optional[asyncio.Task] = None
92
+ self._refresh_token_task: Optional[asyncio.Task] = None
92
93
  self._http_client: Optional[httpx.AsyncClient] = None
93
94
 
94
95
  self.connection_info = None
@@ -108,6 +109,41 @@ class HTTPStreamingRPCConnection:
108
109
  self._handle_connected = handler
109
110
  assert inspect.iscoroutinefunction(handler), "Handler must be async"
110
111
 
112
+ async def _send_refresh_token(self, token_refresh_interval: float):
113
+ """Send refresh token request at regular intervals.
114
+
115
+ Similar to WebSocket, this periodically requests a new reconnection token
116
+ to keep the session alive and allow reconnection with a fresh token.
117
+ """
118
+ try:
119
+ await asyncio.sleep(2) # Initial delay
120
+ while not self._closed and self._http_client:
121
+ try:
122
+ # Send refresh token request via POST
123
+ workspace = self._workspace or "public"
124
+ url = f"{self._server_url}/{workspace}/rpc"
125
+ params = {"client_id": self._client_id}
126
+
127
+ refresh_message = msgpack.packb({"type": "refresh_token"})
128
+ response = await self._http_client.post(
129
+ url,
130
+ content=refresh_message,
131
+ params=params,
132
+ headers=self._get_headers(),
133
+ )
134
+ if response.status_code == 200:
135
+ logger.debug("Token refresh requested successfully")
136
+ else:
137
+ logger.warning(f"Token refresh request failed: {response.status_code}")
138
+ except Exception as e:
139
+ logger.warning(f"Failed to send refresh token request: {e}")
140
+
141
+ await asyncio.sleep(token_refresh_interval)
142
+ except asyncio.CancelledError:
143
+ logger.debug("Token refresh task was cancelled")
144
+ except Exception as e:
145
+ logger.error(f"Error in token refresh task: {e}")
146
+
111
147
  def _get_headers(self, for_stream: bool = False) -> dict:
112
148
  """Get HTTP headers with authentication.
113
149
 
@@ -127,7 +163,11 @@ class HTTPStreamingRPCConnection:
127
163
  return headers
128
164
 
129
165
  async def _create_http_client(self) -> httpx.AsyncClient:
130
- """Create configured HTTP client."""
166
+ """Create configured HTTP client with connection pooling.
167
+
168
+ Connection pooling improves performance by reusing TCP connections
169
+ for multiple requests, reducing connection overhead.
170
+ """
131
171
  verify = True
132
172
  if self._ssl is False:
133
173
  verify = False
@@ -137,6 +177,12 @@ class HTTPStreamingRPCConnection:
137
177
  return httpx.AsyncClient(
138
178
  timeout=httpx.Timeout(self._timeout, connect=30.0),
139
179
  verify=verify,
180
+ # Connection pooling for better performance with many requests
181
+ limits=httpx.Limits(
182
+ max_connections=100, # Max total connections
183
+ max_keepalive_connections=20, # Keep-alive connections for reuse
184
+ keepalive_expiry=30.0, # Keep connections alive for 30 seconds
185
+ ),
140
186
  )
141
187
 
142
188
  async def open(self):
@@ -153,6 +199,11 @@ class HTTPStreamingRPCConnection:
153
199
  if self._format == "msgpack":
154
200
  params["format"] = "msgpack"
155
201
 
202
+ # Add reconnection token if available (for reconnection)
203
+ if self._reconnection_token:
204
+ params["reconnection_token"] = self._reconnection_token
205
+ logger.info(f"Using reconnection token for HTTP streaming connection")
206
+
156
207
  try:
157
208
  # Start streaming in background task
158
209
  self._stream_task = asyncio.create_task(
@@ -180,11 +231,27 @@ class HTTPStreamingRPCConnection:
180
231
  if "reconnection_token" in self.connection_info:
181
232
  self._reconnection_token = self.connection_info["reconnection_token"]
182
233
 
234
+ # Adjust token refresh interval based on server's token lifetime
235
+ if "reconnection_token_life_time" in self.connection_info:
236
+ token_life_time = self.connection_info["reconnection_token_life_time"]
237
+ if self._token_refresh_interval > token_life_time / 1.5:
238
+ logger.warning(
239
+ f"Token refresh interval ({self._token_refresh_interval}s) is too long, "
240
+ f"adjusting to {token_life_time / 1.5:.0f}s based on token lifetime"
241
+ )
242
+ self._token_refresh_interval = token_life_time / 1.5
243
+
183
244
  logger.info(
184
245
  f"HTTP streaming connected to workspace: {self._workspace}, "
185
246
  f"manager_id: {self.manager_id}"
186
247
  )
187
248
 
249
+ # Start token refresh task
250
+ if self._token_refresh_interval > 0:
251
+ self._refresh_token_task = asyncio.create_task(
252
+ self._send_refresh_token(self._token_refresh_interval)
253
+ )
254
+
188
255
  if self._handle_connected:
189
256
  await self._handle_connected(self.connection_info)
190
257
 
@@ -390,6 +457,16 @@ class HTTPStreamingRPCConnection:
390
457
 
391
458
  async def _cleanup(self):
392
459
  """Cleanup resources."""
460
+ # Cancel token refresh task
461
+ if self._refresh_token_task and not self._refresh_token_task.done():
462
+ self._refresh_token_task.cancel()
463
+ try:
464
+ await asyncio.wait_for(self._refresh_token_task, timeout=1.0)
465
+ except (asyncio.CancelledError, asyncio.TimeoutError):
466
+ pass
467
+ self._refresh_token_task = None
468
+
469
+ # Cancel stream task
393
470
  if self._stream_task and not self._stream_task.done():
394
471
  self._stream_task.cancel()
395
472
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hypha_rpc
3
- Version: 0.20.88
3
+ Version: 0.20.90
4
4
  Summary: Hypha RPC client for connecting to Hypha server for data management and AI model serving
5
5
  Author-email: Wei Ouyang <oeway007@gmail.com>
6
6
  Requires-Python: >=3.9
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hypha_rpc"
7
- version = "0.20.88"
7
+ version = "0.20.90"
8
8
  description = "Hypha RPC client for connecting to Hypha server for data management and AI model serving"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,3 +0,0 @@
1
- {
2
- "version": "0.20.88"
3
- }
File without changes
File without changes
File without changes