Skip to content

Commit 04e4e96

Browse files
committed
refactor: code for web_server walker
1 parent 0824ead commit 04e4e96

File tree

3 files changed

+70
-25
lines changed

3 files changed

+70
-25
lines changed

pygwalker/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from pygwalker.services.global_var import GlobalVarManager
1111
from pygwalker.services.kaggle import show_tips_user_kaggle as __show_tips_user_kaggle
1212

13-
__version__ = "0.4.9.14"
13+
__version__ = "0.4.9.15"
1414
__hash__ = __rand_str()
1515

1616
from pygwalker.api.adapter import walk, render, table

pygwalker/api/adapter.py

+6
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ def walk(
7777
show_cloud_tool=show_cloud_tool,
7878
kanaries_api_key=kanaries_api_key,
7979
default_tab=default_tab,
80+
auto_open=True,
81+
auto_shutdown=True,
8082
**kwargs
8183
)
8284

@@ -122,6 +124,8 @@ def render(
122124
appearance=appearance,
123125
kernel_computation=kernel_computation,
124126
kanaries_api_key=kanaries_api_key,
127+
auto_open=True,
128+
auto_shutdown=True,
125129
**kwargs
126130
)
127131

@@ -163,5 +167,7 @@ def table(
163167
appearance=appearance,
164168
kernel_computation=kernel_computation,
165169
kanaries_api_key=kanaries_api_key,
170+
auto_open=True,
171+
auto_shutdown=True,
166172
**kwargs
167173
)

pygwalker/api/webserver.py

+63-24
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@
3737

3838

3939
class _GlobalState:
40-
def __init__(self):
40+
def __init__(self, auto_shutdown: bool):
4141
# why +60? If page not auto open, user manually open page, we should give user more time to interact with page.
4242
self.last_health_time = time.time() + 60
43+
self.auto_shutdown = auto_shutdown
4344

4445

4546
class _PygWalkerHandler(http.server.SimpleHTTPRequestHandler):
@@ -59,7 +60,11 @@ def do_GET(self):
5960

6061
props = self._walker._get_props("web_server")
6162
props["communicationUrl"] = "comm"
62-
html = self._walker._get_render_iframe(props) + _SEND_HEALTH_JS_SCRIPT
63+
64+
html = self._walker._get_render_iframe(props)
65+
if self._state.auto_shutdown:
66+
html += _SEND_HEALTH_JS_SCRIPT
67+
6368
self.send_response(200)
6469
self.send_header("Content-type", "text/html")
6570
self.end_headers()
@@ -100,34 +105,51 @@ class CustomPygWalkerHandler(_PygWalkerHandler):
100105
return CustomPygWalkerHandler
101106

102107

103-
def _start_server(walker: PygWalker, port: Optional[int]):
108+
def _open_browser(address: str, delay_ms: int = 1000):
109+
"""Open browser with address"""
110+
time.sleep(delay_ms / 1000)
111+
112+
try:
113+
opened = webbrowser.open(address)
114+
except Exception:
115+
opened = False
116+
117+
if opened:
118+
print(f"Run pygwalker at {address}, close page or press Ctrl+C to end.")
119+
else:
120+
print(f"Auto open browser failed, please open {address} manually, close page or press Ctrl+C to end.")
121+
122+
123+
def _start_server(
124+
walker: PygWalker,
125+
port: Optional[int],
126+
*,
127+
auto_open: bool,
128+
auto_shutdown: bool,
129+
):
104130
"""Start a server with walker"""
105-
state = _GlobalState()
131+
state = _GlobalState(auto_shutdown=auto_shutdown)
106132
walker._init_callback(BaseCommunication(str(walker.gid)))
107133

108134
handler = _create_handler_with_walker(walker, state)
109135
if port is None:
110136
port = find_free_port()
111137
address = f"http://localhost:{port}"
112138

139+
def _listen_shutdown():
140+
while 1:
141+
time.sleep(1)
142+
if time.time() - state.last_health_time > _MAX_HEALTH_TIMEOUT_SECONDS:
143+
httpd.shutdown()
144+
break
145+
113146
try:
114147
with CustomTCPServer(("127.0.0.1", port), handler) as httpd:
115-
threading.Thread(target=httpd.serve_forever, daemon=True).start()
116-
try:
117-
opened = webbrowser.open(address)
118-
except Exception:
119-
opened = False
120-
121-
if opened:
122-
print(f"Run pygwalker at {address}, close page or press Ctrl+C to end.")
123-
else:
124-
print(f"Auto open browser failed, please open {address} manually, close page or press Ctrl+C to end.")
125-
126-
while 1:
127-
time.sleep(1)
128-
if time.time() - state.last_health_time > _MAX_HEALTH_TIMEOUT_SECONDS:
129-
httpd.shutdown()
130-
break
148+
if auto_open:
149+
threading.Thread(target=_open_browser, args=(address,)).start()
150+
if auto_shutdown:
151+
threading.Thread(target=_listen_shutdown).start()
152+
httpd.serve_forever()
131153
except KeyboardInterrupt:
132154
pass
133155

@@ -146,9 +168,12 @@ def walk(
146168
kanaries_api_key: str = "",
147169
default_tab: Literal["data", "vis"] = "vis",
148170
port: Optional[int] = None,
171+
auto_shutdown: bool = False,
172+
auto_open: bool = False,
149173
**kwargs
150174
):
151-
"""Walk through pandas.DataFrame df with Graphic Walker
175+
"""Walk through pandas.DataFrame df with Graphic Walker.
176+
This function was originally designed solely to launch Pygwalker in script mode.
152177
153178
Args:
154179
- dataset (pl.DataFrame | pd.DataFrame | Connector, optional): dataframe.
@@ -164,6 +189,8 @@ def walk(
164189
- default_tab (Literal["data", "vis"]): default tab to show. Default to "vis"
165190
- cloud_computation(bool): Whether to use cloud compute for datas, it upload your data to kanaries cloud. Default to False.
166191
- port (int): port to use for the server. Default to None, which means a random port will be used.
192+
- auto_shutdown (bool): Whether to shutdown the server when the page is closed. Default to False.
193+
- auto_open (bool): Whether to open the browser automatically. Default to False.
167194
"""
168195
check_expired_params(kwargs)
169196

@@ -189,7 +216,7 @@ def walk(
189216
cloud_computation=cloud_computation,
190217
**kwargs
191218
)
192-
_start_server(walker, port)
219+
_start_server(walker, port, auto_open=auto_open, auto_shutdown=auto_shutdown)
193220

194221

195222
def render(
@@ -201,9 +228,13 @@ def render(
201228
kernel_computation: Optional[bool] = None,
202229
kanaries_api_key: str = "",
203230
port: Optional[int] = None,
231+
auto_shutdown: bool = False,
232+
auto_open: bool = False,
204233
**kwargs
205234
):
206235
"""
236+
This function was originally designed solely to launch Pygwalker in script mode.
237+
207238
Args:
208239
- dataset (pl.DataFrame | pd.DataFrame | Connector, optional): dataframe.
209240
- spec (str): chart config data. config id, json, remote file url
@@ -214,6 +245,8 @@ def render(
214245
- kernel_computation(bool): Whether to use kernel compute for datas, Default to None.
215246
- kanaries_api_key (str): kanaries api key, Default to "".
216247
- port (int): port to use for the server. Default to None, which means a random port will be used.
248+
- auto_shutdown (bool): Whether to shutdown the server when the page is closed. Default to False.
249+
- auto_open (bool): Whether to open the browser automatically. Default to False.
217250
"""
218251

219252
walker = PygWalker(
@@ -235,7 +268,7 @@ def render(
235268
cloud_computation=False,
236269
**kwargs
237270
)
238-
_start_server(walker, port)
271+
_start_server(walker, port, auto_open=auto_open, auto_shutdown=auto_shutdown)
239272

240273

241274
def table(
@@ -246,9 +279,13 @@ def table(
246279
kernel_computation: Optional[bool] = None,
247280
kanaries_api_key: str = "",
248281
port: Optional[int] = None,
282+
auto_shutdown: bool = False,
283+
auto_open: bool = False,
249284
**kwargs
250285
):
251286
"""
287+
This function was originally designed solely to launch Pygwalker in script mode.
288+
252289
Args:
253290
- dataset (pl.DataFrame | pd.DataFrame | Connector, optional): dataframe.
254291
@@ -258,6 +295,8 @@ def table(
258295
- kernel_computation(bool): Whether to use kernel compute for datas, Default to None.
259296
- kanaries_api_key (str): kanaries api key, Default to "".
260297
- port (int): port to use for the server. Default to None, which means a random port will be used.
298+
- auto_shutdown (bool): Whether to shutdown the server when the page is closed. Default to False.
299+
- auto_open (bool): Whether to open the browser automatically. Default to False.
261300
"""
262301
walker = PygWalker(
263302
gid=None,
@@ -278,4 +317,4 @@ def table(
278317
cloud_computation=False,
279318
**kwargs
280319
)
281-
_start_server(walker, port)
320+
_start_server(walker, port, auto_open=auto_open, auto_shutdown=auto_shutdown)

0 commit comments

Comments
 (0)