vuer 0.0.30__py3-none-any.whl → 0.0.31rc2__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.

Potentially problematic release.


This version of vuer might be problematic. Click here for more details.

Binary file
Binary file
@@ -1,3 +1,4 @@
1
+ from io import BytesIO
1
2
  from typing import Union, Literal
2
3
 
3
4
  import numpy as np
@@ -214,28 +215,46 @@ class Image(Element):
214
215
  self,
215
216
  data: Union[str, np.ndarray, pil_image.Image] = None,
216
217
  *,
217
- src: str = None,
218
- format: Literal["png", "jpg", "b64png", "b64jpg"] = "png",
218
+ src: Union[str, bytes] = None,
219
+ format: Literal["png", "jpeg", "b64png", "b64jpeg"] = "png",
219
220
  quality: int = None,
220
221
  **kwargs,
221
222
  ):
222
223
  if src is not None:
223
- assert data is None, "data and src can not be truful at the same time"
224
- if data is None:
225
- pass
226
- elif isinstance(data, list) and len(data) == 0:
227
- pass
228
- else:
229
- if isinstance(data, pil_image.Image):
230
- data = data
231
- elif isinstance(data, str):
232
- # convert back to image first from base64
233
- data = pil_image.open(data)
234
- elif isinstance(data, np.ndarray):
235
- if data.dtype == np.uint8:
236
- pass
237
- else:
238
- data = (data * 255).astype(np.uint8)
224
+ assert data is None, "data and src can not be truthy at the same time"
225
+ super().__init__(src=src, **kwargs)
226
+ return
227
+
228
+ elif data is None or isinstance(data, list) and len(data) == 0:
229
+ super().__init__(**kwargs)
230
+ return
231
+
232
+ elif isinstance(data, pil_image.Image):
233
+ buff = BytesIO()
234
+ assert not format.startswith(
235
+ "b64"
236
+ ), "does not support base64 encoding, use binary."
237
+ data.save(buff, format=format)
238
+ binary = buff.getbuffer().tobytes()
239
+ super().__init__(src=binary, **kwargs)
240
+ return
241
+
242
+ elif isinstance(data, str):
243
+ buff = BytesIO()
244
+ img = pil_image.open(data)
245
+ assert not format.startswith(
246
+ "b64"
247
+ ), "does not support base64 encoding, use binary."
248
+ img.save(buff, format=format)
249
+ binary = buff.getbuffer().tobytes()
250
+ super().__init__(src=binary, **kwargs)
251
+ return
252
+
253
+ if isinstance(data, np.ndarray):
254
+ if data.dtype == np.uint8:
255
+ pass
256
+ else:
257
+ data = (data * 255).astype(np.uint8)
239
258
 
240
259
  if quality is not None:
241
260
  src = IMAGE_FORMATS[format](data, quality=quality)
vuer/serdes.py CHANGED
@@ -41,7 +41,7 @@ def serializer(data):
41
41
  # # raise NotImplementedError(f"Cannot serialize {data}")
42
42
 
43
43
 
44
- def jpg(image, quality: int = 90):
44
+ def jpeg(image, quality: int = 90):
45
45
  """
46
46
  base64 encode the image into a string, using JPEG encoding
47
47
 
@@ -65,7 +65,7 @@ def png(image):
65
65
  return buff.getbuffer().tobytes()
66
66
 
67
67
 
68
- def b64jpg(image, quality: int = 90):
68
+ def b64jpeg(image, quality: int = 90):
69
69
  """
70
70
  base64 encode the image into a string, using JPEG encoding
71
71
 
@@ -92,8 +92,8 @@ def b64png(image):
92
92
 
93
93
 
94
94
  IMAGE_FORMATS = {
95
- "jpg": jpg,
95
+ "jpeg": jpeg,
96
96
  "png": png,
97
- "b64jpg": b64jpg,
97
+ "b64jpeg": b64jpeg,
98
98
  "b64png": b64png,
99
99
  }
vuer/server.py CHANGED
@@ -3,7 +3,7 @@ from asyncio import sleep
3
3
  from collections import deque, defaultdict
4
4
  from functools import partial
5
5
  from pathlib import Path
6
- from typing import cast, Callable, Coroutine, Dict
6
+ from typing import cast, Callable, Dict, Union
7
7
  from uuid import uuid4
8
8
 
9
9
  from aiohttp.hdrs import UPGRADE
@@ -11,7 +11,7 @@ from aiohttp.web_request import Request, BaseRequest
11
11
  from aiohttp.web_response import Response
12
12
  from aiohttp.web_ws import WebSocketResponse
13
13
  from msgpack import packb, unpackb
14
- from params_proto import Proto, PrefixProto
14
+ from params_proto import Proto, PrefixProto, Flag
15
15
  from websockets import ConnectionClosedError
16
16
 
17
17
  from vuer.base import Server, handle_file_request, websocket_handler
@@ -89,7 +89,9 @@ class VuerSession:
89
89
  :return: dqueue
90
90
  """
91
91
  assert isinstance(event, ServerEvent), "msg must be a ServerEvent type object."
92
- assert not isinstance(event, Frame), "Frame event is only used in vuer.bind method."
92
+ assert not isinstance(
93
+ event, Frame
94
+ ), "Frame event is only used in vuer.bind method."
93
95
  assert self.CURRENT_WS_ID in self.vuer.ws, "Websocket session is missing."
94
96
 
95
97
  event_obj = event.serialize()
@@ -106,7 +108,9 @@ class VuerSession:
106
108
  :param subsample: The subsample of the render.
107
109
  :param ttl: The time to live for the handler. If the handler is not called within the time it gets removed from the handler list.
108
110
  """
109
- assert self.CURRENT_WS_ID is not None, "Websocket session is missing. CURRENT_WS_ID is None."
111
+ assert (
112
+ self.CURRENT_WS_ID is not None
113
+ ), "Websocket session is missing. CURRENT_WS_ID is None."
110
114
 
111
115
  event = GrabRender(**kwargs)
112
116
 
@@ -242,7 +246,7 @@ class VuerSession:
242
246
  return None
243
247
 
244
248
  def clear(self):
245
- "clears all client messages"
249
+ """clears all client messages"""
246
250
  self.downlink_queue.clear()
247
251
 
248
252
  def stream(self):
@@ -285,22 +289,28 @@ class Vuer(PrefixProto, Server):
285
289
  .. automethod:: run
286
290
  """
287
291
 
288
- name = "vuer"
289
- domain = "https://vuer.ai"
290
- port = DEFAULT_PORT
291
- free_port = True
292
- static_root = "."
293
- queue_len = 100 # use a max length to avoid the memory from blowing up.
294
- cors = "https://vuer.ai,https://dash.ml,http://localhost:8000,http://127.0.0.1:8000,*"
295
- queries = Proto({}, help="query parameters to pass")
296
-
297
- cert = Proto(None, dtype=str, help="the path to the SSL certificate")
298
- key = Proto(None, dtype=str, help="the path to the SSL key")
299
- ca_cert = Proto(None, dtype=str, help="the trusted root CA certificates")
300
-
301
- client_root = Path(__file__).parent / "client_build"
302
-
303
- device = "cuda"
292
+ domain = Proto("https://vuer.ai", help="default url of web client")
293
+ host = Proto("localhost", help="set to 0.0.0.0 to enable remote connections")
294
+ port = Proto(DEFAULT_PORT, help="port to use")
295
+ free_port: bool = Flag("Kill what is running on the requested port if True.")
296
+ static_root: str = Proto(".", help="root for file serving")
297
+ """todo: we want to support multiple paths."""
298
+ queue_len: int = Proto(
299
+ 100, help="use a max length to avoid the memory from blowing up."
300
+ )
301
+ cors = Proto(
302
+ "https://vuer.ai,https://dash.ml,http://localhost:8000,http://127.0.0.1:8000,*",
303
+ help="domains that are allowed for cross origin requests.",
304
+ )
305
+ queries: Dict = Proto({}, help="query parameters to pass")
306
+
307
+ cert: str = Proto(None, dtype=str, help="the path to the SSL certificate")
308
+ key: str = Proto(None, dtype=str, help="the path to the SSL key")
309
+ ca_cert: str = Proto(None, dtype=str, help="the trusted root CA certificates")
310
+
311
+ client_root: Path = Path(__file__).parent / "client_build"
312
+
313
+ verbose = Flag("Print the settings if True.")
304
314
 
305
315
  def _proxy(self, ws_id) -> "VuerSession":
306
316
  """This is a proxy object that allows us to use the @ notation
@@ -316,6 +326,13 @@ class Vuer(PrefixProto, Server):
316
326
 
317
327
  def __post_init__(self):
318
328
  # todo: what is this?
329
+
330
+ if self.verbose:
331
+ print("========= Arguments =========")
332
+ for k, v in vars(self).items():
333
+ print(f" {k} = {v},")
334
+ print("-----------------------------")
335
+
319
336
  Server.__post_init__(self)
320
337
 
321
338
  self.handlers = defaultdict(dict)
@@ -348,15 +365,17 @@ class Vuer(PrefixProto, Server):
348
365
  return Response(400)
349
366
  elif session_id in self.ws:
350
367
  self.send(ws_id=session_id, event_bytes=bytes)
368
+
351
369
  return Response(status=200)
352
- elif session_id == "all":
370
+ elif session_id == "*":
353
371
  # print broadcast
354
372
  for ws_id in self.ws:
355
373
  try:
356
374
  self.send(ws_id=ws_id, event_bytes=bytes)
357
375
  except Exception as e:
358
376
  print("Exception: ", e)
359
- pass
377
+ return Response(status=502, text=str(e))
378
+
360
379
  return Response(status=200)
361
380
  else:
362
381
  return Response(status=400)
@@ -460,7 +479,9 @@ class Vuer(PrefixProto, Server):
460
479
  ws = self.ws[ws_id]
461
480
 
462
481
  if event_bytes is None:
463
- assert isinstance(event, ServerEvent), "event must be a ServerEvent type object."
482
+ assert isinstance(
483
+ event, ServerEvent
484
+ ), "event must be a ServerEvent type object."
464
485
  event_obj = event.serialize()
465
486
  event_bytes = packb(event_obj, use_single_float=True, use_bin_type=True)
466
487
  else:
@@ -468,7 +489,7 @@ class Vuer(PrefixProto, Server):
468
489
 
469
490
  return await ws.send_bytes(event_bytes)
470
491
 
471
- async def rpc(self, ws_id, event: ServerRPC, ttl=2.0) -> ClientEvent:
492
+ async def rpc(self, ws_id, event: ServerRPC, ttl=2.0) -> Union[ClientEvent, None]:
472
493
  """RPC only takes a single response. For multi-response streaming,
473
494
  we need to build a new one
474
495
 
@@ -484,7 +505,9 @@ class Vuer(PrefixProto, Server):
484
505
  rpc_event = asyncio.Event()
485
506
  response = None
486
507
 
487
- async def response_handler(response_event: ClientEvent, _: "VuerSession") -> Coroutine:
508
+ async def response_handler(
509
+ response_event: ClientEvent, _: "VuerSession"
510
+ ) -> None:
488
511
  nonlocal response
489
512
 
490
513
  response = response_event
@@ -510,7 +533,7 @@ class Vuer(PrefixProto, Server):
510
533
  raise NotImplementedError("This is not implemented yet.")
511
534
 
512
535
  async def close_ws(self, ws_id):
513
- # uplink is moved to the proxy object. Clearned by garbage collection.
536
+ # uplink is moved to the proxy object. Cleaned by garbage collection.
514
537
  # self.uplink_queue.pop(ws_id)
515
538
  try:
516
539
  ws = self.ws.pop(ws_id)
@@ -625,10 +648,10 @@ class Vuer(PrefixProto, Server):
625
648
  await self.close_ws(ws_id)
626
649
 
627
650
  def add_handler(
628
- self,
629
- event_type: str,
630
- fn: EventHandler = None,
631
- once: bool = False,
651
+ self,
652
+ event_type: str,
653
+ fn: EventHandler = None,
654
+ once: bool = False,
632
655
  ) -> Callable[[], None]:
633
656
  """Adding event handlers to the vuer server.
634
657
 
@@ -706,7 +729,9 @@ class Vuer(PrefixProto, Server):
706
729
  """
707
730
  headers = request.headers
708
731
  if "websocket" != headers.get(UPGRADE, "").lower().strip():
709
- return await handle_file_request(request, self.client_root, filename="index.html")
732
+ return await handle_file_request(
733
+ request, self.client_root, filename="index.html"
734
+ )
710
735
  else:
711
736
  return await websocket_handler(request, self.downlink)
712
737
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vuer
3
- Version: 0.0.30
3
+ Version: 0.0.31rc2
4
4
  Home-page: https://github.com/geyang/vuer
5
5
  Author: Ge Yang<ge.ike.yang@gmail.com>
6
6
  Author-email: ge.ike.yang@gmail.com
@@ -2,15 +2,15 @@ vuer/__init__.py,sha256=kbjORSc64WWVHcx3eJB1wnCzhIF76eX5g-JAXYEDM4Q,519
2
2
  vuer/base.py,sha256=wzJoR57hjRreMBPR2zCqARhap2NF_dnizGouKaOMiog,4224
3
3
  vuer/events.py,sha256=8AAzkfbm5jHkeMh17Z57n8YTxF4mheWC3Qbya4XkQSc,7291
4
4
  vuer/schemas.py,sha256=aZOocE02gO43SLLfeYSxxac0x38TmyTcfs_iFh5hsJ4,18152
5
- vuer/serdes.py,sha256=gD2iA9Yypu1QjocneOT3Nc0y6q_mdHn9zW1ko5j3I7c,2600
6
- vuer/server.py,sha256=YWinzsS62ezlWzZwnvMHeFa44xZ5_C11dzTg6tQmPIE,22717
5
+ vuer/serdes.py,sha256=GcUTcNwFj2rd-H9Konnud3w1hs7_ACdKzhDuHbnOaB0,2606
6
+ vuer/server.py,sha256=d1MgXCcs7WCG87uTUcFezW4UKxQp3nTMzWeDrONHjg4,23553
7
7
  vuer/types.py,sha256=N2KLa0fl6z8Jm6cJwZoD8Vqrins_AayG5BCGk1p3Eek,1279
8
8
  vuer/__pycache__/__init__.cpython-38.pyc,sha256=5iTFXy2ivwedwlehtJwBje7Bh3j86bu9TZh_waR8kvs,644
9
9
  vuer/__pycache__/base.cpython-38.pyc,sha256=0U6qDasrEqc8tsLvlmw5grPX_htqPxbmQpZ5R760Rso,4768
10
10
  vuer/__pycache__/events.cpython-38.pyc,sha256=zx3bXeJixqOyCFe2nA7qpq6jiCJ49kRaXO-xONGUyeQ,9616
11
11
  vuer/__pycache__/schemas.cpython-38.pyc,sha256=hvY9Aak8zE-zKcWiwuNe6DghOw9qH_zSe_FtkBOAPPk,23234
12
- vuer/__pycache__/serdes.cpython-38.pyc,sha256=GncycLg8qwrlKR-X5el9txThHkY_zqejmZlpQKAeJnA,2253
13
- vuer/__pycache__/server.cpython-38.pyc,sha256=O0T1VObw7tLIUev1LIN_B8x8E6SmpokJXBIFHhQFWNc,20771
12
+ vuer/__pycache__/serdes.cpython-38.pyc,sha256=_mtV9NhQ05aE9_QVH-oPd0TPyu5rLf9WpxhjUB_Uo1E,2255
13
+ vuer/__pycache__/server.cpython-38.pyc,sha256=rlfXkgvQGNT04X_p_s1oZPIsSauNVA66eL9NRjWOMJQ,21559
14
14
  vuer/__pycache__/types.cpython-38.pyc,sha256=IhlXtkT-XWM0V1420FDuoqIYnpvRvekYVkGqEK7fAV8,1819
15
15
  vuer/addons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  vuer/addons/nerf_vuer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -111,15 +111,15 @@ vuer/client_build/hands/index.html,sha256=E18xQ0UCKT2KP3w6O11UB0VUiTWbd6Og4ibXNr
111
111
  vuer/client_build/hands/index.pageContext.json,sha256=nRC_8Jo3t6gqQUHn2FDfo6cPOJPMonkkWWBfoBG1wzI,276
112
112
  vuer/schemas/__init__.py,sha256=ZI6UyeLZXqJbHmp6LiE3Q3mHvt1zeV-SJmmcqq-wBZE,94
113
113
  vuer/schemas/drei_components.py,sha256=U9svEOnNprhZaobLagaFnqEtZxo5hiriSqjDnvQutoA,6989
114
- vuer/schemas/html_components.py,sha256=KGvRo8b-34Kch81cTNPffRLKuU8oa5SX_0xZ1lkJhxY,6134
114
+ vuer/schemas/html_components.py,sha256=28KuxiSoLi0W7LLK81QqyZbBQ6IsK5HyQqWN86ZlUuo,6759
115
115
  vuer/schemas/scene_components.py,sha256=-4EqZSpDbv_EOCZarPgqSwxR1cAnjLKX3rP8f1Db1X0,18902
116
116
  vuer/schemas/__pycache__/__init__.cpython-38.pyc,sha256=NRnVrpIDBKne93xOUY1-WpavCG7vwYiqU3VDTEEwuUE,221
117
117
  vuer/schemas/__pycache__/drei_components.cpython-38.pyc,sha256=g_ufcKxf-XKfZLdUV-HqKnjIrgxGWFv51aHLWQgH-ws,7712
118
- vuer/schemas/__pycache__/html_components.cpython-38.pyc,sha256=sk2gDqu_zNQMS-PC8d3L90bvjFjTBb8-UKK9Ka5aoAw,8348
118
+ vuer/schemas/__pycache__/html_components.cpython-38.pyc,sha256=xJFawDLPt9TkpYDw5mL8RQwy-0RQ0ZxyLlBGoPkdWoQ,8745
119
119
  vuer/schemas/__pycache__/scene_components.cpython-38.pyc,sha256=FCBjSZs-lX5YvhcL3K0s_T_oz2Fm8NAdd-XsPoXQc9s,22109
120
- vuer-0.0.30.dist-info/LICENSE,sha256=MGF-inVBUaGe2mEjqT0g6XsHIXwoNXgNHqD7Z1MzR0k,1063
121
- vuer-0.0.30.dist-info/METADATA,sha256=QI0N5iV0PDd6cCEjrZ-7Qj_59RO5mV63W2omo8Tk2Lg,5346
122
- vuer-0.0.30.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
123
- vuer-0.0.30.dist-info/entry_points.txt,sha256=J_NM6fbpipmD9oP7cdxd1UyBR8mVEQVx0xjlE_56yss,41
124
- vuer-0.0.30.dist-info/top_level.txt,sha256=ermmVkwvGFAK4gfSgDIwOmKpxwpqNt-oo7gVQQUSHok,5
125
- vuer-0.0.30.dist-info/RECORD,,
120
+ vuer-0.0.31rc2.dist-info/LICENSE,sha256=MGF-inVBUaGe2mEjqT0g6XsHIXwoNXgNHqD7Z1MzR0k,1063
121
+ vuer-0.0.31rc2.dist-info/METADATA,sha256=SFzCxh8YAa74V2Sgz_rQsqriwDT80fMzjNdMYo_m86c,5349
122
+ vuer-0.0.31rc2.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
123
+ vuer-0.0.31rc2.dist-info/entry_points.txt,sha256=J_NM6fbpipmD9oP7cdxd1UyBR8mVEQVx0xjlE_56yss,41
124
+ vuer-0.0.31rc2.dist-info/top_level.txt,sha256=ermmVkwvGFAK4gfSgDIwOmKpxwpqNt-oo7gVQQUSHok,5
125
+ vuer-0.0.31rc2.dist-info/RECORD,,