h2o-wave 1.3.4__py3-none-any.whl → 1.5.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.

Potentially problematic release.


This version of h2o-wave might be problematic. Click here for more details.

h2o_wave/cli.py CHANGED
@@ -178,6 +178,8 @@ def run(app: str, no_reload: bool, no_autostart: bool):
178
178
 
179
179
  if not os.environ.get('H2O_WAVE_WAVED_DIR') and is_auto_started:
180
180
  os.environ['H2O_WAVE_WAVED_DIR'] = sys.exec_prefix
181
+ if not no_reload:
182
+ os.environ['__H2O_WAVE_DEV_MODE'] = '1'
181
183
  reload_exclude = os.environ.get('H2O_WAVE_RELOAD_EXCLUDE', None)
182
184
  if reload_exclude:
183
185
  reload_exclude = reload_exclude.split(os.pathsep)
h2o_wave/core.py CHANGED
@@ -43,6 +43,12 @@ BROADCAST = 'broadcast'
43
43
 
44
44
  def _get_env(key: str, value: Any):
45
45
  return os.environ.get(f'H2O_WAVE_{key}', value)
46
+ def _get_timeout(val: str) -> Optional[int]:
47
+ try:
48
+ num = int(val)
49
+ return num if num >= 0 else None
50
+ except ValueError:
51
+ raise ValueError(f'Timeout must be numeric, got {val}')
46
52
 
47
53
 
48
54
  _base_url = _get_env('BASE_URL', '/')
@@ -60,6 +66,10 @@ class _Config:
60
66
  self.hub_access_key_secret: str = _get_env('ACCESS_KEY_SECRET', 'access_key_secret')
61
67
  self.app_access_key_id: str = _get_env('APP_ACCESS_KEY_ID', None) or secrets.token_urlsafe(16)
62
68
  self.app_access_key_secret: str = _get_env('APP_ACCESS_KEY_SECRET', None) or secrets.token_urlsafe(16)
69
+ self.app_connect_timeout: Optional[int] = _get_timeout(_get_env('APP_CONNECT_TIMEOUT', '5'))
70
+ self.app_read_timeout: Optional[int] = _get_timeout(_get_env('APP_READ_TIMEOUT', '5'))
71
+ self.app_write_timeout: Optional[int] = _get_timeout(_get_env('APP_WRITE_TIMEOUT', '5'))
72
+ self.app_pool_timeout: Optional[int] = _get_timeout(_get_env('APP_POOL_TIMEOUT', '5'))
63
73
 
64
74
 
65
75
  _config = _Config()
@@ -640,9 +650,16 @@ class Site:
640
650
  """
641
651
 
642
652
  def __init__(self):
653
+ timeout = httpx.Timeout(
654
+ connect=_config.app_connect_timeout,
655
+ read=_config.app_read_timeout,
656
+ write=_config.app_write_timeout,
657
+ pool=_config.app_pool_timeout,
658
+ )
643
659
  self._http = httpx.Client(
644
660
  auth=(_config.hub_access_key_id, _config.hub_access_key_secret),
645
661
  verify=False,
662
+ timeout=timeout,
646
663
  )
647
664
  self.cache = _ServerCache(self._http)
648
665
 
@@ -870,9 +887,16 @@ class AsyncSite:
870
887
  """
871
888
 
872
889
  def __init__(self):
890
+ timeout = httpx.Timeout(
891
+ connect=_config.app_connect_timeout,
892
+ read=_config.app_read_timeout,
893
+ write=_config.app_write_timeout,
894
+ pool=_config.app_pool_timeout,
895
+ )
873
896
  self._http = httpx.AsyncClient(
874
897
  auth=(_config.hub_access_key_id, _config.hub_access_key_secret),
875
898
  verify=False,
899
+ timeout=timeout,
876
900
  )
877
901
  self.cache = _AsyncServerCache(self._http)
878
902
 
h2o_wave/server.py CHANGED
@@ -77,7 +77,13 @@ class Auth:
77
77
  if not self.refresh_token:
78
78
  return
79
79
 
80
- async with httpx.AsyncClient(auth=(_config.hub_access_key_id, _config.hub_access_key_secret), verify=False) as http:
80
+ timeout = httpx.Timeout(
81
+ connect=_config.app_connect_timeout,
82
+ read=_config.app_read_timeout,
83
+ write=_config.app_write_timeout,
84
+ pool=_config.app_pool_timeout,
85
+ )
86
+ async with httpx.AsyncClient(auth=(_config.hub_access_key_id, _config.hub_access_key_secret), verify=False, timeout=timeout) as http:
81
87
  res = await http.get(_config.hub_address + '_auth/refresh', headers={'Wave-Session-ID': self._session_id})
82
88
  return self.__extract_tokens(res.headers)
83
89
 
@@ -89,7 +95,13 @@ class Auth:
89
95
  if not self.refresh_token:
90
96
  return
91
97
 
92
- with httpx.Client(auth=(_config.hub_access_key_id, _config.hub_access_key_secret), verify=False) as http:
98
+ timeout = httpx.Timeout(
99
+ connect=_config.app_connect_timeout,
100
+ read=_config.app_read_timeout,
101
+ write=_config.app_write_timeout,
102
+ pool=_config.app_pool_timeout,
103
+ )
104
+ with httpx.Client(auth=(_config.hub_access_key_id, _config.hub_access_key_secret), verify=False, timeout=timeout) as http:
93
105
  res = http.get(_config.hub_address + '_auth/refresh', headers={'Wave-Session-ID': self._session_id})
94
106
  return self.__extract_tokens(res.headers)
95
107
 
@@ -215,9 +227,16 @@ WebAppState = Tuple[Expando, Dict[str, Expando], Dict[str, Expando]]
215
227
 
216
228
  class _Wave:
217
229
  def __init__(self):
230
+ timeout = httpx.Timeout(
231
+ connect=_config.app_connect_timeout,
232
+ read=_config.app_read_timeout,
233
+ write=_config.app_write_timeout,
234
+ pool=_config.app_pool_timeout,
235
+ )
218
236
  self._http = httpx.AsyncClient(
219
237
  auth=(_config.hub_access_key_id, _config.hub_access_key_secret),
220
238
  verify=False,
239
+ timeout=timeout,
221
240
  )
222
241
 
223
242
  async def call(self, method: str, **kwargs):
@@ -378,6 +397,9 @@ class _App:
378
397
 
379
398
 
380
399
  def _is_req_authorized(req: Request) -> bool:
400
+ if os.environ.get('__H2O_WAVE_DEV_MODE') == '1':
401
+ return True
402
+
381
403
  basic_auth = req.headers.get("Authorization")
382
404
  if basic_auth is None:
383
405
  return False
h2o_wave/types.py CHANGED
@@ -8467,6 +8467,7 @@ class ChatbotCard:
8467
8467
  generating: Optional[bool] = None,
8468
8468
  suggestions: Optional[List[ChatSuggestion]] = None,
8469
8469
  disabled: Optional[bool] = None,
8470
+ value: Optional[str] = None,
8470
8471
  commands: Optional[List[Command]] = None,
8471
8472
  ):
8472
8473
  _guard_scalar('ChatbotCard.box', box, (str,), False, False, False)
@@ -8476,6 +8477,7 @@ class ChatbotCard:
8476
8477
  _guard_scalar('ChatbotCard.generating', generating, (bool,), False, True, False)
8477
8478
  _guard_vector('ChatbotCard.suggestions', suggestions, (ChatSuggestion,), False, True, False)
8478
8479
  _guard_scalar('ChatbotCard.disabled', disabled, (bool,), False, True, False)
8480
+ _guard_scalar('ChatbotCard.value', value, (str,), False, True, False)
8479
8481
  _guard_vector('ChatbotCard.commands', commands, (Command,), False, True, False)
8480
8482
  self.box = box
8481
8483
  """A string indicating how to place this component on the page."""
@@ -8493,6 +8495,8 @@ class ChatbotCard:
8493
8495
  """Clickable prompt suggestions shown below the last response."""
8494
8496
  self.disabled = disabled
8495
8497
  """True if the user input should be disabled."""
8498
+ self.value = value
8499
+ """Value of the user input."""
8496
8500
  self.commands = commands
8497
8501
  """Contextual menu commands for this component."""
8498
8502
 
@@ -8505,6 +8509,7 @@ class ChatbotCard:
8505
8509
  _guard_scalar('ChatbotCard.generating', self.generating, (bool,), False, True, False)
8506
8510
  _guard_vector('ChatbotCard.suggestions', self.suggestions, (ChatSuggestion,), False, True, False)
8507
8511
  _guard_scalar('ChatbotCard.disabled', self.disabled, (bool,), False, True, False)
8512
+ _guard_scalar('ChatbotCard.value', self.value, (str,), False, True, False)
8508
8513
  _guard_vector('ChatbotCard.commands', self.commands, (Command,), False, True, False)
8509
8514
  return _dump(
8510
8515
  view='chatbot',
@@ -8516,6 +8521,7 @@ class ChatbotCard:
8516
8521
  generating=self.generating,
8517
8522
  suggestions=None if self.suggestions is None else [__e.dump() for __e in self.suggestions],
8518
8523
  disabled=self.disabled,
8524
+ value=self.value,
8519
8525
  commands=None if self.commands is None else [__e.dump() for __e in self.commands],
8520
8526
  )
8521
8527
 
@@ -8537,6 +8543,8 @@ class ChatbotCard:
8537
8543
  _guard_vector('ChatbotCard.suggestions', __d_suggestions, (dict,), False, True, False)
8538
8544
  __d_disabled: Any = __d.get('disabled')
8539
8545
  _guard_scalar('ChatbotCard.disabled', __d_disabled, (bool,), False, True, False)
8546
+ __d_value: Any = __d.get('value')
8547
+ _guard_scalar('ChatbotCard.value', __d_value, (str,), False, True, False)
8540
8548
  __d_commands: Any = __d.get('commands')
8541
8549
  _guard_vector('ChatbotCard.commands', __d_commands, (dict,), False, True, False)
8542
8550
  box: str = __d_box
@@ -8547,6 +8555,7 @@ class ChatbotCard:
8547
8555
  generating: Optional[bool] = __d_generating
8548
8556
  suggestions: Optional[List[ChatSuggestion]] = None if __d_suggestions is None else [ChatSuggestion.load(__e) for __e in __d_suggestions]
8549
8557
  disabled: Optional[bool] = __d_disabled
8558
+ value: Optional[str] = __d_value
8550
8559
  commands: Optional[List[Command]] = None if __d_commands is None else [Command.load(__e) for __e in __d_commands]
8551
8560
  return ChatbotCard(
8552
8561
  box,
@@ -8557,6 +8566,7 @@ class ChatbotCard:
8557
8566
  generating,
8558
8567
  suggestions,
8559
8568
  disabled,
8569
+ value,
8560
8570
  commands,
8561
8571
  )
8562
8572
 
@@ -8984,12 +8994,18 @@ class GraphicsCard:
8984
8994
  scene: Optional[PackedData] = None,
8985
8995
  width: Optional[str] = None,
8986
8996
  height: Optional[str] = None,
8997
+ image: Optional[str] = None,
8998
+ image_path: Optional[str] = None,
8999
+ image_type: Optional[str] = None,
8987
9000
  commands: Optional[List[Command]] = None,
8988
9001
  ):
8989
9002
  _guard_scalar('GraphicsCard.box', box, (str,), False, False, False)
8990
9003
  _guard_scalar('GraphicsCard.view_box', view_box, (str,), False, False, False)
8991
9004
  _guard_scalar('GraphicsCard.width', width, (str,), False, True, False)
8992
9005
  _guard_scalar('GraphicsCard.height', height, (str,), False, True, False)
9006
+ _guard_scalar('GraphicsCard.image', image, (str,), False, True, False)
9007
+ _guard_scalar('GraphicsCard.image_path', image_path, (str,), False, True, False)
9008
+ _guard_scalar('GraphicsCard.image_type', image_type, (str,), False, True, False)
8993
9009
  _guard_vector('GraphicsCard.commands', commands, (Command,), False, True, False)
8994
9010
  self.box = box
8995
9011
  """A string indicating how to place this component on the page."""
@@ -9003,6 +9019,12 @@ class GraphicsCard:
9003
9019
  """The displayed width of the rectangular viewport. (Not the width of its coordinate system.)"""
9004
9020
  self.height = height
9005
9021
  """The displayed height of the rectangular viewport. (Not the height of its coordinate system.)"""
9022
+ self.image = image
9023
+ """Background image data, base64-encoded."""
9024
+ self.image_path = image_path
9025
+ """The path or URL or data URL of the background image, e.g. `/foo.png` or `http://example.com/foo.png` or `data:image/png;base64,???`."""
9026
+ self.image_type = image_type
9027
+ """The background image MIME subtype. One of `apng`, `bmp`, `gif`, `x-icon`, `jpeg`, `png`, `webp`. Required only if `image` is set."""
9006
9028
  self.commands = commands
9007
9029
  """Contextual menu commands for this component."""
9008
9030
 
@@ -9012,6 +9034,9 @@ class GraphicsCard:
9012
9034
  _guard_scalar('GraphicsCard.view_box', self.view_box, (str,), False, False, False)
9013
9035
  _guard_scalar('GraphicsCard.width', self.width, (str,), False, True, False)
9014
9036
  _guard_scalar('GraphicsCard.height', self.height, (str,), False, True, False)
9037
+ _guard_scalar('GraphicsCard.image', self.image, (str,), False, True, False)
9038
+ _guard_scalar('GraphicsCard.image_path', self.image_path, (str,), False, True, False)
9039
+ _guard_scalar('GraphicsCard.image_type', self.image_type, (str,), False, True, False)
9015
9040
  _guard_vector('GraphicsCard.commands', self.commands, (Command,), False, True, False)
9016
9041
  return _dump(
9017
9042
  view='graphics',
@@ -9021,6 +9046,9 @@ class GraphicsCard:
9021
9046
  scene=self.scene,
9022
9047
  width=self.width,
9023
9048
  height=self.height,
9049
+ image=self.image,
9050
+ image_path=self.image_path,
9051
+ image_type=self.image_type,
9024
9052
  commands=None if self.commands is None else [__e.dump() for __e in self.commands],
9025
9053
  )
9026
9054
 
@@ -9037,6 +9065,12 @@ class GraphicsCard:
9037
9065
  _guard_scalar('GraphicsCard.width', __d_width, (str,), False, True, False)
9038
9066
  __d_height: Any = __d.get('height')
9039
9067
  _guard_scalar('GraphicsCard.height', __d_height, (str,), False, True, False)
9068
+ __d_image: Any = __d.get('image')
9069
+ _guard_scalar('GraphicsCard.image', __d_image, (str,), False, True, False)
9070
+ __d_image_path: Any = __d.get('image_path')
9071
+ _guard_scalar('GraphicsCard.image_path', __d_image_path, (str,), False, True, False)
9072
+ __d_image_type: Any = __d.get('image_type')
9073
+ _guard_scalar('GraphicsCard.image_type', __d_image_type, (str,), False, True, False)
9040
9074
  __d_commands: Any = __d.get('commands')
9041
9075
  _guard_vector('GraphicsCard.commands', __d_commands, (dict,), False, True, False)
9042
9076
  box: str = __d_box
@@ -9045,6 +9079,9 @@ class GraphicsCard:
9045
9079
  scene: Optional[PackedData] = __d_scene
9046
9080
  width: Optional[str] = __d_width
9047
9081
  height: Optional[str] = __d_height
9082
+ image: Optional[str] = __d_image
9083
+ image_path: Optional[str] = __d_image_path
9084
+ image_type: Optional[str] = __d_image_type
9048
9085
  commands: Optional[List[Command]] = None if __d_commands is None else [Command.load(__e) for __e in __d_commands]
9049
9086
  return GraphicsCard(
9050
9087
  box,
@@ -9053,6 +9090,9 @@ class GraphicsCard:
9053
9090
  scene,
9054
9091
  width,
9055
9092
  height,
9093
+ image,
9094
+ image_path,
9095
+ image_type,
9056
9096
  commands,
9057
9097
  )
9058
9098
 
h2o_wave/ui.py CHANGED
@@ -2938,6 +2938,7 @@ def chatbot_card(
2938
2938
  generating: Optional[bool] = None,
2939
2939
  suggestions: Optional[List[ChatSuggestion]] = None,
2940
2940
  disabled: Optional[bool] = None,
2941
+ value: Optional[str] = None,
2941
2942
  commands: Optional[List[Command]] = None,
2942
2943
  ) -> ChatbotCard:
2943
2944
  """Create a chatbot card to allow getting prompts from users and providing them with LLM generated answers.
@@ -2951,6 +2952,7 @@ def chatbot_card(
2951
2952
  generating: True to show a button to stop the text generation. Defaults to False.
2952
2953
  suggestions: Clickable prompt suggestions shown below the last response.
2953
2954
  disabled: True if the user input should be disabled.
2955
+ value: Value of the user input.
2954
2956
  commands: Contextual menu commands for this component.
2955
2957
  Returns:
2956
2958
  A `h2o_wave.types.ChatbotCard` instance.
@@ -2964,6 +2966,7 @@ def chatbot_card(
2964
2966
  generating,
2965
2967
  suggestions,
2966
2968
  disabled,
2969
+ value,
2967
2970
  commands,
2968
2971
  )
2969
2972
 
@@ -3121,6 +3124,9 @@ def graphics_card(
3121
3124
  scene: Optional[PackedData] = None,
3122
3125
  width: Optional[str] = None,
3123
3126
  height: Optional[str] = None,
3127
+ image: Optional[str] = None,
3128
+ image_path: Optional[str] = None,
3129
+ image_type: Optional[str] = None,
3124
3130
  commands: Optional[List[Command]] = None,
3125
3131
  ) -> GraphicsCard:
3126
3132
  """Create a card for displaying vector graphics.
@@ -3132,6 +3138,9 @@ def graphics_card(
3132
3138
  scene: Foreground layer for rendering dynamic SVG elements.
3133
3139
  width: The displayed width of the rectangular viewport. (Not the width of its coordinate system.)
3134
3140
  height: The displayed height of the rectangular viewport. (Not the height of its coordinate system.)
3141
+ image: Background image data, base64-encoded.
3142
+ image_path: The path or URL or data URL of the background image, e.g. `/foo.png` or `http://example.com/foo.png` or `data:image/png;base64,???`.
3143
+ image_type: The background image MIME subtype. One of `apng`, `bmp`, `gif`, `x-icon`, `jpeg`, `png`, `webp`. Required only if `image` is set.
3135
3144
  commands: Contextual menu commands for this component.
3136
3145
  Returns:
3137
3146
  A `h2o_wave.types.GraphicsCard` instance.
@@ -3143,6 +3152,9 @@ def graphics_card(
3143
3152
  scene,
3144
3153
  width,
3145
3154
  height,
3155
+ image,
3156
+ image_path,
3157
+ image_type,
3146
3158
  commands,
3147
3159
  )
3148
3160
 
h2o_wave/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '1.3.4'
1
+ __version__ = '1.5.0'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: h2o-wave
3
- Version: 1.3.4
3
+ Version: 1.5.0
4
4
  Summary: Python driver for H2O Wave Realtime Apps
5
5
  Project-URL: Homepage, https://wave.h2o.ai/
6
6
  Project-URL: Documentation, https://wave.h2o.ai/
@@ -1,22 +1,22 @@
1
1
  h2o_wave/__init__.py,sha256=XIclw-HLtXgr0wNf5eQpkh6ZiqD9QAoiS-vZhp3IR5k,1674
2
2
  h2o_wave/__main__.py,sha256=MoNOW43ppIqCdY3iq0n25Q3SKLyk8Igg5fD_sSROK4c,638
3
- h2o_wave/cli.py,sha256=XZVNSF5vPq3EVhZs_Q0Jq1t8stTF4BdbTvZIQmEIsgE,13603
4
- h2o_wave/core.py,sha256=whFb-Z2wokNXe_39I8aL3i7JOx6eczRfWOkn5wb_YwM,39087
3
+ h2o_wave/cli.py,sha256=5pIWZe-lRNmE1QUc94mk4XLLaQquvnCWwSs4qMgO3p4,13681
4
+ h2o_wave/core.py,sha256=dKUZOPDL8W-MCDLtC3A1TTuGNGO9cjAtbaQ8dfjceUA,40184
5
5
  h2o_wave/db.py,sha256=H3W_EyMfnwr4UjqPVoAsE19O2QzY1ptIYGMOqU0YUQo,7489
6
6
  h2o_wave/graphics.py,sha256=HLYrX-lwsMKbyLmy2ClG5L46DA2_hSCEPTsv0gPVoyg,25866
7
7
  h2o_wave/ide.py,sha256=wAJjfEI1ekQrL455FGRVeNi3KiH6ELgsG3qm31Q-kRs,6810
8
8
  h2o_wave/metadata.py,sha256=d8FrJ-nQhBIvntA2W9VVZ0-lxEE_uy85ShxCC_FFDEs,82
9
9
  h2o_wave/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  h2o_wave/routing.py,sha256=de8GVfUAb6bwFXtsWj6NXmjMVGELknlZb03F-R4ManY,10592
11
- h2o_wave/server.py,sha256=u80Jma83mMKqmTitVDFO703SrcC4Y29DQM2letSVNyA,17900
11
+ h2o_wave/server.py,sha256=eAVP8E_fqpeAwYtZjk9cGKSy7cLwGbh0Zj_WBrB1j5M,18706
12
12
  h2o_wave/share.py,sha256=2zgywet8540O6xM-JD3po1glyP2PBJ3lIxaWBJbQvtQ,1164
13
13
  h2o_wave/test.py,sha256=hF_fS5e25bACnzENjpDrikv7nPOs0iENh4MuXX9BaVA,2738
14
- h2o_wave/types.py,sha256=8VCKbNBGmEQRc_dZjY73LUl416CEqEteq1jkmRuptZo,657819
15
- h2o_wave/ui.py,sha256=d4ndxFHdm37lIYqcy_8KZ_p-e7FhPN-iD_4e9ck-Nwo,171748
14
+ h2o_wave/types.py,sha256=9aW8RCgA4I8Euddm_20UxMm8JsQJVebIOs9TLcck0fM,660143
15
+ h2o_wave/ui.py,sha256=SFGRSfR_TWSLVRnIqKBxNqqHg4gcpXcRwM2JZwmxZbw,172373
16
16
  h2o_wave/ui_ext.py,sha256=zx_2Ec2-p_ztm8brfVaVF0fTQWVDrb_YxcGfVb-wA10,2325
17
- h2o_wave/version.py,sha256=znOUWqTRUyFzytrxffOUq80wt0j_tYutMKHTUCSPrAo,22
18
- h2o_wave-1.3.4.dist-info/METADATA,sha256=GbaT9pnM2vxn17vty0aNMArbhtY8brDlvVNV0Mrr5so,2907
19
- h2o_wave-1.3.4.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
20
- h2o_wave-1.3.4.dist-info/entry_points.txt,sha256=kFeXNqSZlW1_H7YcRdSOhz5V00F4vhDQ0NuDuvRwLGw,43
21
- h2o_wave-1.3.4.dist-info/licenses/LICENSE,sha256=hpuFayniDwysSKD0tHGELH2KJDVyhUrKS29torRIpqY,53
22
- h2o_wave-1.3.4.dist-info/RECORD,,
17
+ h2o_wave/version.py,sha256=wShy9YfBfroz0HjRH_aNNehkEu1_PLsd_GjTU5aCDPk,22
18
+ h2o_wave-1.5.0.dist-info/METADATA,sha256=LAkPfHQX9Lq3733Cs3c2BHwF1kQ5y4YY-SJSzEX52Pg,2907
19
+ h2o_wave-1.5.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
20
+ h2o_wave-1.5.0.dist-info/entry_points.txt,sha256=kFeXNqSZlW1_H7YcRdSOhz5V00F4vhDQ0NuDuvRwLGw,43
21
+ h2o_wave-1.5.0.dist-info/licenses/LICENSE,sha256=hpuFayniDwysSKD0tHGELH2KJDVyhUrKS29torRIpqY,53
22
+ h2o_wave-1.5.0.dist-info/RECORD,,