Skip to content

Commit 39df43e

Browse files
authored
fix: resolve plotly rendering issue by using ipython html for job pro… (#134)
…gress messages Fixes bug that was preventing plotly rendering to show after the progress bar. Original ipywidgets implementation isn't necessary for basic opening of urls Screen recording: https://togithub.com/googleapis/python-bigquery-dataframes/assets/15842009/5225ce05-117a-4808-9ff0-cb2c3aaf3a40 Internal bug: b/297062404
1 parent 3afd4a3 commit 39df43e

File tree

2 files changed

+53
-54
lines changed

2 files changed

+53
-54
lines changed

bigframes/formatting_helpers.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# TODO(orrbradford): cleanup up typings and documenttion in this file
1717

1818
import datetime
19+
import random
1920
from typing import Any, Optional, Union
2021

2122
import google.api_core.exceptions as api_core_exceptions
@@ -57,9 +58,9 @@ def repr_query_job_html(query_job: Optional[bigquery.QueryJob]):
5758
Pywidget html table.
5859
"""
5960
if query_job is None:
60-
return widgets.HTML("No job information available")
61+
return display.HTML("No job information available")
6162
if query_job.dry_run:
62-
return widgets.HTML(
63+
return display.HTML(
6364
f"Computation deferred. Computation will process {get_formatted_bytes(query_job.total_bytes_processed)}"
6465
)
6566
table_html = "<style> td {text-align: left;}</style>"
@@ -125,16 +126,20 @@ def wait_for_query_job(
125126
Returns:
126127
A row iterator over the query results.
127128
"""
128-
loading_bar = widgets.HTML(get_query_job_loading_html(query_job))
129129
if progress_bar == "auto":
130130
progress_bar = "notebook" if in_ipython() else "terminal"
131131

132132
try:
133133
if progress_bar == "notebook":
134-
display.display(loading_bar)
134+
display_id = str(random.random())
135+
loading_bar = display.HTML(get_query_job_loading_html(query_job))
136+
display.display(loading_bar, display_id=display_id)
135137
query_result = query_job.result(max_results=max_results)
136138
query_job.reload()
137-
loading_bar.value = get_query_job_loading_html(query_job)
139+
display.update_display(
140+
display.HTML(get_query_job_loading_html(query_job)),
141+
display_id=display_id,
142+
)
138143
elif progress_bar == "terminal":
139144
initial_loading_bar = get_query_job_loading_string(query_job)
140145
print(initial_loading_bar)
@@ -171,16 +176,19 @@ def wait_for_job(job: GenericJob, progress_bar: Optional[str] = None):
171176
progress_bar (str, Optional):
172177
Which progress bar to show.
173178
"""
174-
loading_bar = widgets.HTML(get_base_job_loading_html(job))
175179
if progress_bar == "auto":
176180
progress_bar = "notebook" if in_ipython() else "terminal"
177181

178182
try:
179183
if progress_bar == "notebook":
180-
display.display(loading_bar)
184+
display_id = str(random.random())
185+
loading_bar = display.HTML(get_base_job_loading_html(job))
186+
display.display(loading_bar, display_id=display_id)
181187
job.result()
182188
job.reload()
183-
loading_bar.value = get_base_job_loading_html(job)
189+
display.update_display(
190+
display.HTML(get_base_job_loading_html(job)), display_id=display_id
191+
)
184192
elif progress_bar == "terminal":
185193
inital_loading_bar = get_base_job_loading_string(job)
186194
print(inital_loading_bar)

tests/system/small/test_progress_bar.py

Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,101 +12,92 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import re
1516
import tempfile
1617

1718
import pandas as pd
1819

1920
import bigframes as bf
2021
import bigframes.formatting_helpers as formatting_helpers
2122

23+
job_load_message_regex = r"\w+ job [\w-]+ is \w+\."
24+
2225

2326
def test_progress_bar_dataframe(
2427
penguins_df_default_index: bf.dataframe.DataFrame, capsys
2528
):
26-
bf.options.display.progress_bar = "notebook"
29+
bf.options.display.progress_bar = "terminal"
30+
capsys.readouterr() # clear output
2731
penguins_df_default_index.to_pandas()
28-
html_check = "HTML(value="
29-
open_job_check = "Open Job"
30-
lines = capsys.readouterr().out.split("\n")
31-
lines = [line for line in lines if len(line) > 0]
32-
assert len(lines) > 0
32+
33+
assert_loading_msg_exist(capsys.readouterr().out)
3334
assert penguins_df_default_index.query_job is not None
34-
for line in lines:
35-
assert html_check in line and open_job_check in line
3635

3736

3837
def test_progress_bar_series(penguins_df_default_index: bf.dataframe.DataFrame, capsys):
39-
bf.options.display.progress_bar = "notebook"
38+
bf.options.display.progress_bar = "terminal"
4039
series = penguins_df_default_index["body_mass_g"].head(10)
40+
capsys.readouterr() # clear output
4141
series.to_pandas()
42-
html_check = "HTML(value="
43-
open_job_check = "Open Job"
44-
lines = capsys.readouterr().out.split("\n")
45-
lines = [line for line in lines if len(line) > 0]
46-
assert len(lines) > 0
42+
43+
assert_loading_msg_exist(capsys.readouterr().out)
4744
assert series.query_job is not None
48-
for line in lines:
49-
assert html_check in line and open_job_check in line
5045

5146

5247
def test_progress_bar_scalar(penguins_df_default_index: bf.dataframe.DataFrame, capsys):
53-
bf.options.display.progress_bar = "notebook"
48+
bf.options.display.progress_bar = "terminal"
49+
capsys.readouterr() # clear output
5450
penguins_df_default_index["body_mass_g"].head(10).mean()
55-
html_check = "HTML(value="
56-
open_job_check = "Open Job"
57-
lines = capsys.readouterr().out.split("\n")
58-
lines = [line for line in lines if len(line) > 0]
59-
assert len(lines) > 0
60-
for line in lines:
61-
assert html_check in line and open_job_check in line
51+
52+
assert_loading_msg_exist(capsys.readouterr().out)
6253

6354

6455
def test_progress_bar_read_gbq(session: bf.Session, penguins_table_id: str, capsys):
65-
bf.options.display.progress_bar = "notebook"
56+
bf.options.display.progress_bar = "terminal"
57+
capsys.readouterr() # clear output
6658
session.read_gbq(penguins_table_id)
67-
html_check = "HTML(value="
68-
open_job_check = "Open Job"
69-
lines = capsys.readouterr().out.split("\n")
70-
lines = [line for line in lines if len(line) > 0]
71-
assert len(lines) > 0
72-
for line in lines:
73-
assert html_check in line and open_job_check in line
59+
60+
assert_loading_msg_exist(capsys.readouterr().out)
7461

7562

7663
def test_progress_bar_extract_jobs(
7764
penguins_df_default_index: bf.dataframe.DataFrame, gcs_folder, capsys
7865
):
79-
bf.options.display.progress_bar = "notebook"
66+
bf.options.display.progress_bar = "terminal"
8067
path = gcs_folder + "test_read_csv_progress_bar*.csv"
68+
capsys.readouterr() # clear output
8169
penguins_df_default_index.to_csv(path)
82-
html_check = "HTML(value="
83-
open_job_check = "Open Job"
84-
lines = capsys.readouterr().out.split("\n")
85-
lines = [line for line in lines if len(line) > 0]
86-
assert len(lines) > 0
87-
for line in lines:
88-
assert html_check in line and open_job_check in line
70+
71+
assert_loading_msg_exist(capsys.readouterr().out)
8972

9073

9174
def test_progress_bar_load_jobs(
9275
session: bf.Session, penguins_pandas_df_default_index: pd.DataFrame, capsys
9376
):
94-
bf.options.display.progress_bar = "notebook"
77+
bf.options.display.progress_bar = "terminal"
9578
with tempfile.TemporaryDirectory() as dir:
9679
path = dir + "/test_read_csv_progress_bar*.csv"
9780
penguins_pandas_df_default_index.to_csv(path, index=False)
81+
capsys.readouterr() # clear output
9882
session.read_csv(path)
99-
html_check = "HTML(value="
100-
open_job_check = "Open Job"
101-
lines = capsys.readouterr().out.split("\n")
83+
84+
assert_loading_msg_exist(capsys.readouterr().out)
85+
86+
87+
def assert_loading_msg_exist(capystOut: str, pattern=job_load_message_regex):
88+
numLoadingMsg = 0
89+
lines = capystOut.split("\n")
10290
lines = [line for line in lines if len(line) > 0]
91+
10392
assert len(lines) > 0
10493
for line in lines:
105-
assert html_check in line and open_job_check in line
94+
if re.match(pattern, line) is not None:
95+
numLoadingMsg += 1
96+
assert numLoadingMsg > 0
10697

10798

10899
def test_query_job_repr_html(penguins_df_default_index: bf.dataframe.DataFrame):
109-
bf.options.display.progress_bar = "notebook"
100+
bf.options.display.progress_bar = "terminal"
110101
penguins_df_default_index._block._expr._session.bqclient.default_query_job_config.use_query_cache = (
111102
False
112103
)

0 commit comments

Comments
 (0)