diff --git a/py/examples/background_progress.py b/py/examples/background_progress.py index dd9fc07a23..77c09ad917 100644 --- a/py/examples/background_progress.py +++ b/py/examples/background_progress.py @@ -26,7 +26,7 @@ def blocking_function(q: Q, loop: asyncio.AbstractEventLoop): # If future is not done yet, skip the update to keep the correct order. if not future or future.done(): # Assume you are able to emit some kind of progress. - future = asyncio.ensure_future(update_ui(q, count / total), loop=loop) + future = asyncio.ensure_future(update_ui(q, round(count / total)), loop=loop) async def show_cancel(q: Q): diff --git a/py/examples/db_todo.py b/py/examples/db_todo.py index 4af3ff8135..361e05e9f6 100644 --- a/py/examples/db_todo.py +++ b/py/examples/db_todo.py @@ -67,7 +67,11 @@ async def show_todos(q: Q): rows, err = await db.exec('select id, label, done from todo where user=?', q.auth.subject) if err: raise RuntimeError(f'Failed fetching todos: {err}') - todos = [TodoItem(id, label, done) for id, label, done in rows] + + if rows is not None: + todos = [TodoItem(id, label, done) for id, label, done in rows] + else: + todos = [] # Create done/not-done checkboxes. done = [ui.checkbox(name=f'todo_{todo.id}', label=todo.label, value=True, trigger=True) for todo in todos if @@ -85,6 +89,7 @@ async def show_todos(q: Q): await q.page.save() + async def add_todo(q: Q): # Insert a new item db: WaveDB = q.app.db diff --git a/py/examples/form.py b/py/examples/form.py index eeabb695de..a0ff9b489a 100644 --- a/py/examples/form.py +++ b/py/examples/form.py @@ -1,7 +1,7 @@ # Form # Use a #form to collect data or show textual information. # --- -from .synth import FakeCategoricalSeries +from .synth import FakeCategoricalSeries # type: ignore from h2o_wave import main, app, Q, ui, pack, data import random diff --git a/py/examples/graphics_spline.py b/py/examples/graphics_spline.py index 4b218ce7f1..bc47b2f835 100644 --- a/py/examples/graphics_spline.py +++ b/py/examples/graphics_spline.py @@ -1,10 +1,10 @@ -# Graphics / Spline -# Use the #graphics module to render splines. -# --- - import random from h2o_wave import site, ui, graphics as g +# Define a function to convert a list of values to float +def to_float(lst): # for example, [1, 2, 3] -> [1.0, 2.0, 3.0] + return [float(v) for v in lst] + x = [i * 20 for i in range(50)] y = [ 88, 100, 116, 128, 126, 128, 118, 108, 121, 120, 99, 113, 117, 103, 98, 90, 104, 98, 82, 102, 104, 89, 87, 69, @@ -17,43 +17,41 @@ splines = [ # Lines - g.spline(x=x, y=y, **line_style), # same as curve='linear' - g.spline(x=x, y=y, curve='basis', **line_style), - g.spline(x=x, y=y, curve='basis-closed', **line_style), - g.spline(x=x, y=y, curve='basis-open', **line_style), - g.spline(x=x, y=y, curve='cardinal', **line_style), - g.spline(x=x, y=y, curve='cardinal-closed', **line_style), - g.spline(x=x, y=y, curve='cardinal-open', **line_style), - g.spline(x=x, y=y, curve='smooth', **line_style), - g.spline(x=x, y=y, curve='smooth-closed', **line_style), - g.spline(x=x, y=y, curve='smooth-open', **line_style), - g.spline(x=x, y=y, curve='linear', **line_style), - g.spline(x=x, y=y, curve='linear-closed', **line_style), - g.spline(x=x, y=y, curve='monotone-x', **line_style), - g.spline(x=x, y=y, curve='monotone-y', **line_style), - g.spline(x=x, y=y, curve='natural', **line_style), - g.spline(x=x, y=y, curve='step', **line_style), - g.spline(x=x, y=y, curve='step-after', **line_style), - g.spline(x=x, y=y, curve='step-before', **line_style), + g.spline(x=to_float(x), y=to_float(y), curve='basis', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='basis-closed', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='basis-open', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='cardinal', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='cardinal-closed', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='cardinal-open', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='smooth', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='smooth-closed', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='smooth-open', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='linear-closed', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='monotone-x', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='monotone-y', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='natural', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='step', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='step-after', style=line_style), + g.spline(x=to_float(x), y=to_float(y), curve='step-before', style=line_style), # Areas - g.spline(x=x, y=y, y0=y0, **area_style), # same as curve='linear' - g.spline(x=x, y=y, y0=y0, curve='basis', **area_style), - g.spline(x=x, y=y, y0=[], curve='basis', **area_style), - g.spline(x=x, y=y, y0=y0, curve='basis-open', **area_style), - g.spline(x=x, y=y, y0=y0, curve='cardinal', **area_style), - g.spline(x=x, y=y, y0=[], curve='cardinal', **area_style), - g.spline(x=x, y=y, y0=y0, curve='cardinal-open', **area_style), - g.spline(x=x, y=y, y0=y0, curve='smooth', **area_style), - g.spline(x=x, y=y, y0=[], curve='smooth', **area_style), - g.spline(x=x, y=y, y0=y0, curve='smooth-open', **area_style), - g.spline(x=x, y=y, y0=y0, curve='linear', **area_style), - g.spline(x=x, y=y, y0=[], curve='linear', **area_style), - g.spline(x=x, y=y, y0=y0, curve='monotone-x', **area_style), - g.spline(x=x, y=y, y0=y0, curve='monotone-y', **area_style), - g.spline(x=x, y=y, y0=y0, curve='natural', **area_style), - g.spline(x=x, y=y, y0=y0, curve='step', **area_style), - g.spline(x=x, y=y, y0=y0, curve='step-after', **area_style), - g.spline(x=x, y=y, y0=y0, curve='step-before', **area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='linear', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='basis', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=[], curve='basis', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='basis-open', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='cardinal', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=[], curve='cardinal', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='cardinal-open', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='smooth', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=[], curve='smooth', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='smooth-open', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='linear', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=[], curve='linear', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='monotone-x', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='monotone-y', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='natural', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='step', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='step-after', style=area_style), + g.spline(x=to_float(x), y=to_float(y), y0=to_float(y0), curve='step-before', style=area_style), ] page = site['/demo'] diff --git a/py/examples/graphics_turtle.py b/py/examples/graphics_turtle.py index 5e304f5761..87ccb9d088 100644 --- a/py/examples/graphics_turtle.py +++ b/py/examples/graphics_turtle.py @@ -7,7 +7,7 @@ t = g.turtle().f(100).r(90).pd() for _ in range(36): t.f(200).l(170) -spirograph = t.pu(1).path(stroke='red', fill='yellow') +spirograph = t.pu(close=True).path(stroke='red', fill='yellow') page = site['/demo'] page['example'] = ui.graphics_card( diff --git a/py/examples/image.py b/py/examples/image.py index 5d3d6177af..1f750ebd84 100644 --- a/py/examples/image.py +++ b/py/examples/image.py @@ -26,11 +26,11 @@ 0.76648938, 0.89679732, 0.77222302, 0.92717429, 0.61465203, 0.60906377, 0.68468487, 0.25101297, 0.83783764, 0.11861562, 0.79723474, 0.94900427, 0.14806288])) ** 2, - c=[0.90687198, 0.78837333, 0.76840584, 0.59849648, 0.44214562, 0.72303802, - 0.41661825, 0.2268104, 0.45422734, 0.84794375, 0.93665595, 0.95603618, - 0.39209432, 0.70832467, 0.12951583, 0.35379639, 0.40427152, 0.6485339, - 0.03307097, 0.53800936, 0.13171312, 0.52093493, 0.10248479, 0.15798038, - 0.92002965], + c=[0.90687198, 0.78837333, 0.76840584, 0.59849648, 0.44214562, 0.72303802, # type: ignore + 0.41661825, 0.2268104, 0.45422734, 0.84794375, 0.93665595, 0.95603618, # type: ignore + 0.39209432, 0.70832467, 0.12951583, 0.35379639, 0.40427152, 0.6485339, # type: ignore + 0.03307097, 0.53800936, 0.13171312, 0.52093493, 0.10248479, 0.15798038, # type: ignore + 0.92002965], # type: ignore alpha=0.5, ) diff --git a/py/examples/plot_altair.py b/py/examples/plot_altair.py index 6a34386281..5a2ae117bc 100644 --- a/py/examples/plot_altair.py +++ b/py/examples/plot_altair.py @@ -1,8 +1,8 @@ # Plot / Altair # Use #Altair to create #plot specifications for the #Vega card. # --- -import altair -from vega_datasets import data +import altair # type: ignore +from vega_datasets import data # type: ignore from h2o_wave import site, ui spec = altair.Chart(data.cars()).mark_circle(size=60).encode( diff --git a/py/examples/plot_app.py b/py/examples/plot_app.py index 6f73a281fa..6f3ed52a06 100644 --- a/py/examples/plot_app.py +++ b/py/examples/plot_app.py @@ -1,7 +1,7 @@ # Plot / App # Make a #plot from an app. # --- -from .synth import FakeMultiCategoricalSeries as F +from .synth import FakeMultiCategoricalSeries as F # type: ignore from h2o_wave import main, app, data, Q, ui n = 10 diff --git a/py/examples/plot_bokeh_callbacks.py b/py/examples/plot_bokeh_callbacks.py index 7175291ed7..671fd2890f 100644 --- a/py/examples/plot_bokeh_callbacks.py +++ b/py/examples/plot_bokeh_callbacks.py @@ -6,6 +6,8 @@ import json from random import random + +from bokeh.core.types import ID from h2o_wave import main, app, Q, ui from bokeh.resources import CDN from bokeh.layouts import row @@ -31,7 +33,7 @@ async def serve(q: Q): p2 = figure(width=250, height=300, x_range=(0, 1), y_range=(0, 1), tools="", title="Watch Here") p2.circle('x', 'y', source=s2, alpha=0.6) - s1.selected.js_on_change( + s1.selected.js_on_change( # type: ignore 'indices', CustomJS( args=dict(s1=s1, s2=s2), @@ -68,7 +70,7 @@ async def serve(q: Q): # Serialize the plot as JSON. # See https://docs.bokeh.org/en/latest/docs/user_guide/embed.html#json-items plot_id = 'my_plot' - plot_data = json.dumps(json_item(layout, plot_id)) + plot_data = json.dumps(json_item(layout, ID(plot_id))) q.page['meta'] = ui.meta_card( box='', diff --git a/py/examples/plot_bokeh_script.py b/py/examples/plot_bokeh_script.py index 046abb78ac..356a7f6488 100644 --- a/py/examples/plot_bokeh_script.py +++ b/py/examples/plot_bokeh_script.py @@ -3,6 +3,8 @@ # --- import json + +from bokeh.core.types import ID from h2o_wave import site, ui from bokeh.resources import CDN from bokeh.plotting import figure @@ -21,7 +23,8 @@ # Serialize the plot as JSON. # See https://docs.bokeh.org/en/latest/docs/user_guide/embed.html#json-items plot_id = 'my_plot' -plot_data = json.dumps(json_item(plot, plot_id)) +plot_data = json.dumps(json_item(plot, ID(plot_id))) + page = site['/demo'] diff --git a/py/examples/plot_events_routing.py b/py/examples/plot_events_routing.py index ddbd2fd51c..2584c15d20 100644 --- a/py/examples/plot_events_routing.py +++ b/py/examples/plot_events_routing.py @@ -2,10 +2,10 @@ # Handle #events on a #plot card using routing. # --- from h2o_wave import main, app, on, run_on, Q, ui, data - +import typing @on('pricing.select_marks') -async def show_selected_marks(q: Q, marks: any): +async def show_selected_marks(q: Q, marks: typing.Any): q.page['details'].content = f'You selected {marks}' await q.page.save() diff --git a/py/examples/plot_matplotlib.py b/py/examples/plot_matplotlib.py index 0e33113eaa..6e6bd42671 100644 --- a/py/examples/plot_matplotlib.py +++ b/py/examples/plot_matplotlib.py @@ -39,10 +39,12 @@ async def serve(q: Q): # Render plot plt.figure(figsize=(2, 2)) + # Generate random RGB colors for each point + colors = [(float(r), float(g), float(b)) for r, g, b in np.random.rand(n, 3)] plt.scatter( np.random.rand(n), np.random.rand(n), s=(30 * np.random.rand(n)) ** 2, - c=np.random.rand(n), + c=colors, alpha=q.client.alpha / 100.0 ) image_filename = f'{str(uuid.uuid4())}.png' diff --git a/py/examples/plot_plotly.py b/py/examples/plot_plotly.py index 81865ecb46..62636613a3 100644 --- a/py/examples/plot_plotly.py +++ b/py/examples/plot_plotly.py @@ -4,7 +4,7 @@ # --- import numpy as np -from plotly import graph_objects as go +from plotly import graph_objects as go # type: ignore from plotly import io as pio from h2o_wave import ui, main, app, Q diff --git a/py/examples/plot_theme.py b/py/examples/plot_theme.py index 227090b88a..bd75361835 100644 --- a/py/examples/plot_theme.py +++ b/py/examples/plot_theme.py @@ -3,7 +3,7 @@ # --- import random -from .synth import FakeTimeSeries, FakeMultiTimeSeries, FakeCategoricalSeries, FakeMultiCategoricalSeries, FakeScatter +from .synth import FakeTimeSeries, FakeMultiTimeSeries, FakeCategoricalSeries, FakeMultiCategoricalSeries, FakeScatter # type: ignore from h2o_wave import main, app, data, Q, ui diff --git a/py/examples/site_async.py b/py/examples/site_async.py index ec06df899b..0e30688b12 100644 --- a/py/examples/site_async.py +++ b/py/examples/site_async.py @@ -2,7 +2,7 @@ # Update any page on a site from within an app using an `AsyncSite` instance. # #site # --- -from .synth import FakePercent +from .synth import FakePercent # type: ignore from h2o_wave import Q, app, main, ui, AsyncSite site = AsyncSite() diff --git a/py/examples/synth.py b/py/examples/synth.py index dad29b6e28..d3f4fcbcee 100644 --- a/py/examples/synth.py +++ b/py/examples/synth.py @@ -1,9 +1,10 @@ import datetime import random +from typing import Optional class FakeSeries: - def __init__(self, min=0.0, max=100.0, variation=10.0, start: int = None): + def __init__(self, min=0.0, max=100.0, variation=10.0, start: Optional[int] = None): self.min = min self.max = max self.variation = variation @@ -21,7 +22,7 @@ def next(self): class FakeTimeSeries: - def __init__(self, min=0.0, max=100.0, variation=10.0, start: int = None, delta_days=1): + def __init__(self, min=0.0, max=100.0, variation=10.0, start: Optional[int] = None, delta_days=1): self.series = FakeSeries(min, max, variation, start) self.delta_days = delta_days self.date = datetime.datetime.utcnow() - datetime.timedelta(days=10 * 365) @@ -33,7 +34,7 @@ def next(self): class FakeMultiTimeSeries: - def __init__(self, min=0.0, max=100.0, variation=10.0, start: int = None, delta_days=1, groups=5): + def __init__(self, min=0.0, max=100.0, variation=10.0, start: Optional[int] = None, delta_days=1, groups=5): self.series = [(f'G{c + 1}', FakeTimeSeries(min, max, variation, start, delta_days)) for c in range(groups)] def next(self): @@ -45,7 +46,7 @@ def next(self): class FakeCategoricalSeries: - def __init__(self, min=0.0, max=100.0, variation=10.0, start: int = None): + def __init__(self, min=0.0, max=100.0, variation=10.0, start: Optional[int] = None): self.series = FakeSeries(min, max, variation, start) self.i = 0 @@ -56,7 +57,7 @@ def next(self): class FakeMultiCategoricalSeries: - def __init__(self, min=0.0, max=100.0, variation=10.0, start: int = None, groups=5): + def __init__(self, min=0.0, max=100.0, variation=10.0, start: Optional[int] = None, groups=5): self.series = [(f'G{c + 1}', FakeCategoricalSeries(min, max, variation, start)) for c in range(groups)] def next(self): @@ -68,7 +69,7 @@ def next(self): class FakeScatter: - def __init__(self, min=0.0, max=100.0, variation=10.0, start: int = None): + def __init__(self, min=0.0, max=100.0, variation=10.0, start: Optional[int] = None): self.x = FakeSeries(min, max, variation, start) self.y = FakeSeries(min, max, variation, start) diff --git a/py/examples/table_filter_backend.py b/py/examples/table_filter_backend.py index 4c93237e7c..480e365893 100644 --- a/py/examples/table_filter_backend.py +++ b/py/examples/table_filter_backend.py @@ -28,8 +28,9 @@ def df_to_rows(df: pd.DataFrame): def search_df(df: pd.DataFrame, term: str): - str_cols = df.select_dtypes(include=[object]) - return df[str_cols.apply(lambda column: column.str.contains(term, case=False, na=False)).any(axis=1)] + str_cols = df.select_dtypes(include=['object']).columns + return df[df[str_cols].apply(lambda column: column.str.contains(term, case=False, na=False)).any(axis=1)] + @app('/demo') diff --git a/py/examples/table_markdown_pandas.py b/py/examples/table_markdown_pandas.py index 3b879c68c0..60bcec9f95 100644 --- a/py/examples/table_markdown_pandas.py +++ b/py/examples/table_markdown_pandas.py @@ -3,11 +3,13 @@ # --- from h2o_wave import site, ui import pandas as pd +import numpy as np + df = pd.DataFrame({'A': 1., 'B': pd.Timestamp('20130102'), 'C': pd.Series(1, index=list(range(4)), dtype='float32'), - 'D': pd.np.array([3] * 4, dtype='int32'), + 'D': np.array([3] * 4, dtype='int32'), 'E': pd.Categorical(["test", "train", "test", "train"]), 'F': 'foo'}) diff --git a/py/examples/table_pagination.py b/py/examples/table_pagination.py index e036809c1f..464cae444d 100644 --- a/py/examples/table_pagination.py +++ b/py/examples/table_pagination.py @@ -4,7 +4,7 @@ # --- import os -from typing import Dict, List +from typing import Optional, Dict, List from h2o_wave import main, app, Q, ui from copy import deepcopy import csv @@ -17,12 +17,12 @@ def __init__(self, text: str, status: str): self.status = status -all_rows = [Issue(text=i + 1, status=('Closed' if i % 2 == 0 else 'Open')) for i in range(100)] +all_rows = [Issue(text=str(i + 1), status=('Closed' if i % 2 == 0 else 'Open')) for i in range(100)] rows_per_page = 10 total_rows = len(all_rows) -def get_rows(base: List, sort: Dict[str, bool] = None, search: Dict = None, filters: Dict[str, List[str]] = None) -> List: +def get_rows(base: List, sort: Optional[Dict[str, bool]] = None, search: Optional[Dict] = None, filters: Optional[Dict[str, List[str]]] = None) -> List: # Make a deep copy in order to not mutate the original `all_issues` which serves as our baseline. rows = deepcopy(base) @@ -37,7 +37,7 @@ def get_rows(base: List, sort: Dict[str, bool] = None, search: Dict = None, filt rows = [row for row in rows if any(search_val in str(getattr(row, col)).lower() for col in cols)] # Filter out rows that do not contain filtered column value. if filters: - for col, filters in filters.items(): + for col, filters in filters.items(): # type: ignore rows = [row for row in rows if not filters or any(f in getattr(row, col) for f in filters)] return rows diff --git a/py/examples/table_pagination_h2o3.py b/py/examples/table_pagination_h2o3.py index 7300784208..dfb724cd35 100644 --- a/py/examples/table_pagination_h2o3.py +++ b/py/examples/table_pagination_h2o3.py @@ -6,7 +6,7 @@ import os from time import time -import h2o +import h2o # type: ignore from h2o_wave import Q, app, main, ui from loguru import logger diff --git a/py/examples/table_pagination_pandas.py b/py/examples/table_pagination_pandas.py index 0b1e4e747d..fafb9f19c1 100644 --- a/py/examples/table_pagination_pandas.py +++ b/py/examples/table_pagination_pandas.py @@ -4,11 +4,10 @@ # --- import os -from typing import Dict, List +from typing import Optional, Dict, List from h2o_wave import main, app, Q, ui import pandas as pd - all_issues_df = pd.DataFrame( [[i + 1, 'Closed' if i % 2 == 0 else 'Open'] for i in range(100)], columns=['text', 'status'] @@ -21,7 +20,8 @@ def df_to_table_rows(df: pd.DataFrame) -> List[ui.TableRow]: return [ui.table_row(name=str(r[0]), cells=[str(r[0]), r[1]]) for r in df.itertuples(index=False)] -def get_df(base: pd.DataFrame, sort: Dict[str, bool] = None, search: Dict = None, filters: Dict[str, List[str]] = None) -> pd.DataFrame: +def get_df(base: pd.DataFrame, sort: Optional[Dict[str, bool]] = None, search: Optional[Dict] = None, + filters: Optional[Dict[str, List[str]]] = None) -> pd.DataFrame: # Make a deep copy in order to not mutate the original df which serves as our baseline. df = base.copy() @@ -32,8 +32,13 @@ def get_df(base: pd.DataFrame, sort: Dict[str, bool] = None, search: Dict = None # Filter out all rows that do not contain searched string in `text` cell. if search: search_val = search['value'].lower() - # Filter dataframe by search value case insensitive. - df = df[df.apply(lambda r: any(search_val in str(r[col]).lower() for col in search['cols']), axis=1)] + + # Type hint for the lambda function + def filter_func(r: pd.Series) -> bool: + return any(search_val in str(r[col]).lower() for col in search['cols']) + + # Filter the DataFrame + df = df[df.apply(filter_func, axis=1)] # Filter out rows that do not contain filtered column value. if filters: # We want only rows that have no filters applied or their col value matches active filters. diff --git a/py/examples/table_pagination_sort.py b/py/examples/table_pagination_sort.py index 30105ce1b3..2acb843925 100644 --- a/py/examples/table_pagination_sort.py +++ b/py/examples/table_pagination_sort.py @@ -12,7 +12,7 @@ def __init__(self, text: str): self.text = text -issues = [Issue(i + 1) for i in range(100)] +issues = [Issue(str(i + 1)) for i in range(100)] rows_per_page = 10 diff --git a/py/examples/tour.py b/py/examples/tour.py index c242b798da..6becd17324 100644 --- a/py/examples/tour.py +++ b/py/examples/tour.py @@ -397,7 +397,7 @@ async def client_disconnect(q: Q): async def serve(q: Q): if not q.app.initialized: q.app.app_port = 10102 - q.app.tour_assets, = await q.site.upload_dir(os.path.join(example_dir, 'tour-assets')) + q.app.tour_assets, = await q.site.upload_dir(os.path.join(example_dir, 'tour-assets')) #type: ignore base_snippets_path = os.path.join(example_dir, 'base-snippets.json') component_snippets_path = os.path.join(example_dir, 'component-snippets.json') # Prod.