From d5e944ec7586b7472b760fa5a0560d891f8c59e2 Mon Sep 17 00:00:00 2001 From: Chuck McCallum Date: Tue, 6 May 2025 09:57:52 -0400 Subject: [PATCH 1/5] rm vestigial initial_public_csv_path --- dp_wizard/shiny/__init__.py | 1 - dp_wizard/shiny/dataset_panel.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/dp_wizard/shiny/__init__.py b/dp_wizard/shiny/__init__.py index 385d548..be68475 100644 --- a/dp_wizard/shiny/__init__.py +++ b/dp_wizard/shiny/__init__.py @@ -123,7 +123,6 @@ def server(input: Inputs, output: Outputs, session: Session): # pragma: no cove session, is_demo=cli_info.is_demo, in_cloud=cli_info.in_cloud, - initial_public_csv_path="", initial_private_csv_path=str(initial_private_csv_path), public_csv_path=public_csv_path, private_csv_path=private_csv_path, diff --git a/dp_wizard/shiny/dataset_panel.py b/dp_wizard/shiny/dataset_panel.py index 008b6a5..e709e16 100644 --- a/dp_wizard/shiny/dataset_panel.py +++ b/dp_wizard/shiny/dataset_panel.py @@ -51,7 +51,6 @@ def dataset_server( session: Session, is_demo: bool, in_cloud: bool, - initial_public_csv_path: str, initial_private_csv_path: str, public_csv_path: reactive.Value[str], private_csv_path: reactive.Value[str], @@ -161,7 +160,6 @@ def input_files_ui(): "public_csv_path", "Choose Public CSV", accept=[".csv"], - placeholder=Path(initial_public_csv_path).name, ), ui.input_file( "private_csv_path", From 5880eadc0af22cd02203cf3c2d05507e68bc7b7b Mon Sep 17 00:00:00 2001 From: Chuck McCallum Date: Tue, 6 May 2025 13:22:31 -0400 Subject: [PATCH 2/5] checkpoint: Not working! --- dp_wizard/shiny/__init__.py | 2 +- dp_wizard/shiny/components/inputs.py | 8 ++++++++ dp_wizard/shiny/dataset_panel.py | 29 +++++++++++++++++----------- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/dp_wizard/shiny/__init__.py b/dp_wizard/shiny/__init__.py index be68475..7211d5c 100644 --- a/dp_wizard/shiny/__init__.py +++ b/dp_wizard/shiny/__init__.py @@ -103,7 +103,7 @@ def server(input: Inputs, output: Outputs, session: Session): # pragma: no cove private_csv_path = reactive.value(str(initial_private_csv_path)) column_names = reactive.value(initial_column_names) - public_csv_path = reactive.value("") + public_csv_path = reactive.value(None) analysis_types = reactive.value({}) lower_bounds = reactive.value({}) upper_bounds = reactive.value({}) diff --git a/dp_wizard/shiny/components/inputs.py b/dp_wizard/shiny/components/inputs.py index 20272c6..151df4c 100644 --- a/dp_wizard/shiny/components/inputs.py +++ b/dp_wizard/shiny/components/inputs.py @@ -1,7 +1,15 @@ +from pathlib import Path from math import log10 from shiny import ui +def file_selector(id: str, label: str, cwd: Path): + choices = [None, "../"] + sorted( + path.name + ("/" if path.is_dir() else "") for path in cwd.iterdir() + ) + return ui.input_select(id, label, choices, selected=None) + + def log_slider(id: str, lower_bound: float, upper_bound: float): # Rather than engineer a new widget, hide the numbers we don't want, # and insert the log values via CSS. diff --git a/dp_wizard/shiny/dataset_panel.py b/dp_wizard/shiny/dataset_panel.py index e709e16..17bd211 100644 --- a/dp_wizard/shiny/dataset_panel.py +++ b/dp_wizard/shiny/dataset_panel.py @@ -9,6 +9,7 @@ PUBLIC_PRIVATE_TEXT, ) from dp_wizard.utils.csv_helper import get_csv_names_mismatch +from dp_wizard.shiny.components.inputs import file_selector from dp_wizard.shiny.components.outputs import ( output_code_sample, demo_tooltip, @@ -52,17 +53,27 @@ def dataset_server( is_demo: bool, in_cloud: bool, initial_private_csv_path: str, - public_csv_path: reactive.Value[str], + public_csv_path: reactive.Value[Path | None], private_csv_path: reactive.Value[str], column_names: reactive.Value[list[str]], contributions: reactive.Value[int], ): # pragma: no cover + public_csv_dir = reactive.value(Path.cwd()) + @reactive.effect - @reactive.event(input.public_csv_path) - def _on_public_csv_path_change(): - path = input.public_csv_path()[0]["datapath"] - public_csv_path.set(path) - column_names.set(read_csv_names(Path(path))) + @reactive.event(input.public_csv_name) + def _on_public_csv_name_change(): + name = input.public_csv_name() + if name == "..": + public_csv_dir.set(public_csv_dir().parent) + public_csv_path.set(None) + elif name.endswith("/"): + public_csv_dir.set(public_csv_dir() / name) + public_csv_path.set(None) + else: + new_path = public_csv_dir() / name + public_csv_path.set(new_path) + column_names.set(read_csv_names(new_path)) @reactive.effect @reactive.event(input.private_csv_path) @@ -156,11 +167,7 @@ def input_files_ui(): # - After file upload, the internal copy of the file # is renamed to something like "0.csv". return ui.row( - ui.input_file( - "public_csv_path", - "Choose Public CSV", - accept=[".csv"], - ), + file_selector("public_csv_name", "Choose Public CSV", Path.cwd()), ui.input_file( "private_csv_path", [ From d89e5cba7ee1572490d4523bf1e1ccde96b798fc Mon Sep 17 00:00:00 2001 From: Chuck McCallum Date: Tue, 6 May 2025 16:37:40 -0400 Subject: [PATCH 3/5] closer to working --- dp_wizard/shiny/components/inputs.py | 18 +++++++++++++++--- dp_wizard/shiny/dataset_panel.py | 22 ++++++++++++++++++---- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/dp_wizard/shiny/components/inputs.py b/dp_wizard/shiny/components/inputs.py index 151df4c..b5e816b 100644 --- a/dp_wizard/shiny/components/inputs.py +++ b/dp_wizard/shiny/components/inputs.py @@ -3,11 +3,23 @@ from shiny import ui -def file_selector(id: str, label: str, cwd: Path): - choices = [None, "../"] + sorted( +parent_name = "../" + + +def get_file_selector_choices(cwd: Path): + return [None, parent_name] + sorted( path.name + ("/" if path.is_dir() else "") for path in cwd.iterdir() ) - return ui.input_select(id, label, choices, selected=None) + + +def file_selector(id: str, label: str, cwd: Path): + return ui.input_select( + id, + label, + get_file_selector_choices(cwd), + size="6", + selected=None, + ) def log_slider(id: str, lower_bound: float, upper_bound: float): diff --git a/dp_wizard/shiny/dataset_panel.py b/dp_wizard/shiny/dataset_panel.py index 17bd211..961d4ec 100644 --- a/dp_wizard/shiny/dataset_panel.py +++ b/dp_wizard/shiny/dataset_panel.py @@ -9,7 +9,11 @@ PUBLIC_PRIVATE_TEXT, ) from dp_wizard.utils.csv_helper import get_csv_names_mismatch -from dp_wizard.shiny.components.inputs import file_selector +from dp_wizard.shiny.components.inputs import ( + get_file_selector_choices, + file_selector, + parent_name, +) from dp_wizard.shiny.components.outputs import ( output_code_sample, demo_tooltip, @@ -64,12 +68,22 @@ def dataset_server( @reactive.event(input.public_csv_name) def _on_public_csv_name_change(): name = input.public_csv_name() - if name == "..": - public_csv_dir.set(public_csv_dir().parent) + if not name: + pass + elif name == parent_name: + new_dir = public_csv_dir().parent + public_csv_dir.set(new_dir) public_csv_path.set(None) + ui.update_select( + "public_csv_name", choices=get_file_selector_choices(new_dir) + ) elif name.endswith("/"): - public_csv_dir.set(public_csv_dir() / name) + new_dir = public_csv_dir() / name + public_csv_dir.set(new_dir) public_csv_path.set(None) + ui.update_select( + "public_csv_name", choices=get_file_selector_choices(new_dir) + ) else: new_path = public_csv_dir() / name public_csv_path.set(new_path) From 0ecaf912b3a1e9dc423ce5e774d15eb7fe6ff5f2 Mon Sep 17 00:00:00 2001 From: Chuck McCallum Date: Tue, 6 May 2025 16:55:24 -0400 Subject: [PATCH 4/5] logic may be good? --- dp_wizard/shiny/components/inputs.py | 4 +++- dp_wizard/shiny/dataset_panel.py | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/dp_wizard/shiny/components/inputs.py b/dp_wizard/shiny/components/inputs.py index b5e816b..49d4c6f 100644 --- a/dp_wizard/shiny/components/inputs.py +++ b/dp_wizard/shiny/components/inputs.py @@ -13,9 +13,11 @@ def get_file_selector_choices(cwd: Path): def file_selector(id: str, label: str, cwd: Path): + from dp_wizard.shiny.components.outputs import info_md_box + return ui.input_select( id, - label, + [label, " from:", ui.tags.br(), ui.tags.strong(cwd.name + "/")], get_file_selector_choices(cwd), size="6", selected=None, diff --git a/dp_wizard/shiny/dataset_panel.py b/dp_wizard/shiny/dataset_panel.py index 961d4ec..71b2b6b 100644 --- a/dp_wizard/shiny/dataset_panel.py +++ b/dp_wizard/shiny/dataset_panel.py @@ -69,7 +69,7 @@ def dataset_server( def _on_public_csv_name_change(): name = input.public_csv_name() if not name: - pass + column_names.set([]) elif name == parent_name: new_dir = public_csv_dir().parent public_csv_dir.set(new_dir) @@ -77,6 +77,7 @@ def _on_public_csv_name_change(): ui.update_select( "public_csv_name", choices=get_file_selector_choices(new_dir) ) + column_names.set([]) elif name.endswith("/"): new_dir = public_csv_dir() / name public_csv_dir.set(new_dir) @@ -84,6 +85,7 @@ def _on_public_csv_name_change(): ui.update_select( "public_csv_name", choices=get_file_selector_choices(new_dir) ) + column_names.set([]) else: new_path = public_csv_dir() / name public_csv_path.set(new_path) @@ -181,7 +183,7 @@ def input_files_ui(): # - After file upload, the internal copy of the file # is renamed to something like "0.csv". return ui.row( - file_selector("public_csv_name", "Choose Public CSV", Path.cwd()), + file_selector("public_csv_name", "Choose Public CSV", public_csv_dir()), ui.input_file( "private_csv_path", [ From 04cde3a6b8ad61a8169be8dfa5ebf4932d0511e1 Mon Sep 17 00:00:00 2001 From: Chuck McCallum Date: Tue, 6 May 2025 17:00:13 -0400 Subject: [PATCH 5/5] just CSVs --- dp_wizard/shiny/components/inputs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dp_wizard/shiny/components/inputs.py b/dp_wizard/shiny/components/inputs.py index 49d4c6f..8a922cd 100644 --- a/dp_wizard/shiny/components/inputs.py +++ b/dp_wizard/shiny/components/inputs.py @@ -8,7 +8,9 @@ def get_file_selector_choices(cwd: Path): return [None, parent_name] + sorted( - path.name + ("/" if path.is_dir() else "") for path in cwd.iterdir() + path.name + ("/" if path.is_dir() else "") + for path in cwd.iterdir() + if path.name.endswith(".csv") or path.is_dir() )