Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 29 additions & 13 deletions dp_wizard/shiny/results_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,11 @@ def download_results_ui():
ui.accordion_panel(
"Reports",
button(
"Report", ".txt", "file-lines", primary=True, disabled=disabled
"Text Report",
".txt",
"file-lines",
primary=True,
disabled=disabled,
),
p(
"""
Expand All @@ -151,8 +155,10 @@ def download_results_ui():
so it can be parsed by other programs.
"""
),
button("Table", ".csv", "file-csv", disabled=disabled),
button("CSV Report", ".csv", "file-csv", disabled=disabled),
p("The same information, but condensed into a two-column CSV."),
button("HTML Report", ".html", "file-code", disabled=disabled),
p("Human-readable HTML report with tables and graphs."),
),
),
]
Expand Down Expand Up @@ -338,24 +344,34 @@ async def download_html():
async def download_html_unexecuted():
yield make_download_or_modal_error(notebook_html_unexecuted)

# The reports are all created by the code in the "coda" of the generated notebook.
# Executing the notebook creates these files in the tmp directory.

def make_make_report(ext):
def make_report():
notebook_nb() # Evaluate just for the side effect of creating report.
tmp_path = Path(__file__).parent.parent / "tmp"
return (tmp_path / f"report.{ext}").read_text()

return make_report

@render.download(
filename=lambda: download_stem() + ".txt",
media_type="text/plain",
)
async def download_report():
def make_report():
notebook_nb() # Evaluate just for the side effect of creating report.
return (Path(__file__).parent.parent / "tmp" / "report.txt").read_text()

yield make_download_or_modal_error(make_report)
async def download_text_report():
yield make_download_or_modal_error(make_make_report("txt"))

@render.download(
filename=lambda: download_stem() + ".csv",
media_type="text/csv",
)
async def download_table():
def make_table():
notebook_nb() # Evaluate just for the side effect of creating report.
return (Path(__file__).parent.parent / "tmp" / "report.csv").read_text()
async def download_csv_report():
yield make_download_or_modal_error(make_make_report("csv"))

yield make_download_or_modal_error(make_table)
@render.download(
filename=lambda: download_stem() + ".html",
media_type="text/html",
)
async def download_html_report():
yield make_download_or_modal_error(make_make_report("html"))
1 change: 1 addition & 0 deletions dp_wizard/tmp/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
demo.csv
report.txt
report.csv
report.html
not-first-run.txt
74 changes: 55 additions & 19 deletions dp_wizard/utils/code_generators/no-tests/_reports.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,58 @@
from yaml import dump
from pathlib import Path
import csv


def make_report():
return {
"inputs": {
"data": CSV_PATH,
"epsilon": EPSILON,
"columns": COLUMNS,
"contributions": contributions,
},
"outputs": OUTPUTS,
}


def save_txt_report(report):
from yaml import dump

Path(TXT_REPORT_PATH).write_text(dump(report))


def save_csv_report(report):
flat_report = flatten_dict(report)
with Path(CSV_REPORT_PATH).open(mode="w", newline="") as handle:
writer = csv.writer(handle)
for kv_pair in flat_report.items():
writer.writerow(kv_pair)


def save_html_report(report):
# There are lots of ways to build html,
# but htmltools comes bundled with shiny.
from htmltools import tags
from yaml import dump

inputs_html = tags.div(
tags.h2("Inputs"),
tags.dl(tags.dt("epsilon"), tags.dd(report["inputs"]["epsilon"])),
)

outputs_html = tags.div(
tags.h2("Outputs"),
[
[tags.h3(tags.code(k)), tags.pre(dump(v))]
for k, v in report["outputs"].items()
],
)

html = tags.html(
tags.head(tags.title("DP Wizard Report")), tags.body(inputs_html, outputs_html)
)
Path(HTML_REPORT_PATH).write_text(str(html))


# https://stackoverflow.com/a/6027615/10727889
def flatten_dict(dictionary, parent_key=""):
"""
Expand Down Expand Up @@ -34,21 +84,7 @@ def flatten_dict(dictionary, parent_key=""):
return dict(items)


report = {
"inputs": {
"data": CSV_PATH,
"epsilon": EPSILON,
"columns": COLUMNS,
"contributions": contributions,
},
"outputs": OUTPUTS,
}

print(dump(report))
Path(TXT_REPORT_PATH).write_text(dump(report))

flat_report = flatten_dict(report)
with Path(CSV_REPORT_PATH).open(mode="w", newline="") as handle:
writer = csv.writer(handle)
for kv_pair in flat_report.items():
writer.writerow(kv_pair)
report = make_report()
save_txt_report(report)
save_csv_report(report)
save_html_report(report)
1 change: 1 addition & 0 deletions dp_wizard/utils/code_generators/notebook_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def _make_extra_blocks(self):
EPSILON=self.analysis_plan.epsilon,
TXT_REPORT_PATH=str(tmp_path / "report.txt"),
CSV_REPORT_PATH=str(tmp_path / "report.csv"),
HTML_REPORT_PATH=str(tmp_path / "report.html"),
)
.finish()
)
Expand Down
Loading