Skip to content
Closed
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
3 changes: 2 additions & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,15 @@ jobs:
prefix = "rtichoke/_vendor/rtichoke_viz/"
required = {
f"{prefix}VENDORED_FROM",
f"{prefix}rtichoke-viz-0.20.2.tar.gz",
f"{prefix}rtichoke-viz-0.22.0.tar.gz",
f"{prefix}rtichoke-viz.js",
f"{prefix}rtichoke-viz.css",
f"{prefix}rtichoke-viz.schema.json",
f"{prefix}rtichoke-viz-v2.schema.json",
f"{prefix}rtichoke-viz-report.schema.json",
}
assert required <= names
assert f"{prefix}rtichoke-viz-0.20.2.tar.gz" not in names
assert f"{prefix}rtichoke-viz-0.20.1.tar.gz" not in names
assert f"{prefix}rtichoke-viz-0.20.0.tar.gz" not in names
assert f"{prefix}rtichoke-viz-0.19.0.tar.gz" not in names
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/quarto-acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ on:
- "tests/test_summary_report_browser.py"
- "tests/test_summary_report_times_browser.py"
- "tests/test_decision_curve_browser_acceptance.py"
- "tests/test_probs_histogram_browser_acceptance.py"
- "src/rtichoke/probs_distribution.py"
- ".github/workflows/quarto-acceptance.yml"
pull_request:
branches: ["main"]
Expand All @@ -30,6 +32,8 @@ on:
- "tests/test_summary_report_browser.py"
- "tests/test_summary_report_times_browser.py"
- "tests/test_decision_curve_browser_acceptance.py"
- "tests/test_probs_histogram_browser_acceptance.py"
- "src/rtichoke/probs_distribution.py"
- ".github/workflows/quarto-acceptance.yml"
workflow_dispatch:

Expand Down Expand Up @@ -65,3 +69,4 @@ jobs:
tests/test_decision_curve_browser_acceptance.py
tests/test_summary_report_browser.py
tests/test_summary_report_times_browser.py
tests/test_probs_histogram_browser_acceptance.py
5 changes: 5 additions & 0 deletions src/rtichoke/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,17 @@
render_performance_table as render_performance_table,
)

from rtichoke.probs_distribution import (
create_probs_histogram as create_probs_histogram,
)

from rtichoke.summary_report.summary_report import (
create_summary_report as create_summary_report,
create_summary_report_times as create_summary_report_times,
)

__all__ = [
"create_probs_histogram",
"create_roc_curve",
"create_roc_curve_times",
"plot_roc_curve",
Expand Down
74 changes: 57 additions & 17 deletions src/rtichoke/_renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from pathlib import Path
from typing import Any, Literal

from rtichoke._report_browser import _resolve_render_report_symbol, _sanitize_nan_values

Renderer = Literal["plotly", "matplotlib", "browser", "rtichoke_viz"]

_SUPPORTED_RENDERERS = ("plotly", "matplotlib", "browser", "rtichoke_viz")
Expand Down Expand Up @@ -46,31 +48,69 @@ def write_html(self, path: str | Path) -> Path:
output = Path(path)
output.parent.mkdir(parents=True, exist_ok=True)
vendor = files("rtichoke").joinpath("_vendor", "rtichoke_viz")
for asset in ("rtichoke-viz.js", "rtichoke-viz.css"):
(output.parent / asset).write_bytes(vendor.joinpath(asset).read_bytes())

render_export = {
"roc": "renderRocV2",
"calibration": "renderCalibrationV2",
"precision_recall": "renderPrecisionRecallV2",
"gains": "renderGainsV2",
"lift": "renderLiftV2",
"decision_curve": "renderDecisionCurveV2",
"interventions_avoided": "renderInterventionsAvoidedV2",
}.get(str(self.spec.get("type")))
if render_export is None:
raise ValueError(
f"rtichoke_viz does not support chart type {self.spec.get('type')!r}."
chart_type = str(self.spec.get("type"))
if chart_type == "prediction_distribution":
viz_js = vendor.joinpath("rtichoke-viz.js").read_text(encoding="utf-8")
viz_css = vendor.joinpath("rtichoke-viz.css").read_text(encoding="utf-8")
render_fn = _resolve_render_report_symbol(
viz_js, "renderPredictionDistribution"
)
sanitized_spec = _sanitize_nan_values(self.spec)
spec_json = json.dumps(sanitized_spec, separators=(",", ":")).replace(
"</", "<\\/"
)

spec_json = json.dumps(self.spec, separators=(",", ":")).replace("</", "<\\/")
html = f"""<!doctype html>
html = f"""<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
{viz_css}
</style>
<title>rtichoke prediction_distribution chart</title>
</head>
<body>
<div id="rtichoke-chart" class="rtichoke-viz-chart"></div>
<script id="rtichoke-spec" type="application/json">{spec_json}</script>
<script type="module">
{viz_js}
const spec = JSON.parse(document.querySelector("#rtichoke-spec").textContent);
const chart = {render_fn}(spec, {{ width: {self.size}, height: {self.size} }});
document.querySelector("#rtichoke-chart").append(chart);
</script>
</body>
</html>
"""
else:
for asset in ("rtichoke-viz.js", "rtichoke-viz.css"):
(output.parent / asset).write_bytes(vendor.joinpath(asset).read_bytes())

render_export = {
"roc": "renderRocV2",
"calibration": "renderCalibrationV2",
"precision_recall": "renderPrecisionRecallV2",
"gains": "renderGainsV2",
"lift": "renderLiftV2",
"decision_curve": "renderDecisionCurveV2",
"interventions_avoided": "renderInterventionsAvoidedV2",
}.get(chart_type)
if render_export is None:
raise ValueError(
f"rtichoke_viz does not support chart type {chart_type!r}."
)

spec_json = json.dumps(self.spec, separators=(",", ":")).replace(
"</", "<\\/"
)
html = f"""<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="./rtichoke-viz.css">
<title>rtichoke {self.spec.get("type")} chart</title>
<title>rtichoke {chart_type} chart</title>
</head>
<body>
<div id="rtichoke-chart" class="rtichoke-viz-chart"></div>
Expand Down
18 changes: 10 additions & 8 deletions src/rtichoke/_report_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,30 @@
from typing import Any


def _resolve_render_report_symbol(viz_js: str) -> str:
"""Resolve the local callable identifier exported as 'renderReport' from an ESM bundle."""
def _resolve_render_report_symbol(
viz_js: str, symbol_name: str = "renderReport"
) -> str:
"""Resolve the local callable identifier exported as symbol_name from an ESM bundle."""
export_pattern = re.compile(r"export\s*\{([^}]+)\}", re.DOTALL)
for match in export_pattern.finditer(viz_js):
clause = match.group(1)
for item in clause.split(","):
parts = item.strip().split()
if not parts:
continue
if len(parts) == 3 and parts[1] == "as" and parts[2] == "renderReport":
if len(parts) == 3 and parts[1] == "as" and parts[2] == symbol_name:
return parts[0]
if len(parts) == 1 and parts[0] == "renderReport":
return "renderReport"
if len(parts) == 1 and parts[0] == symbol_name:
return symbol_name

if re.search(
r"export\s+(?:async\s+)?function\s+renderReport\b|export\s+(?:const|let|var)\s+renderReport\b",
rf"export\s+(?:async\s+)?function\s+{symbol_name}\b|export\s+(?:const|let|var)\s+{symbol_name}\b",
viz_js,
):
return "renderReport"
return symbol_name

raise ValueError(
"Could not resolve 'renderReport' export in provided JavaScript bundle."
f"Could not resolve {symbol_name!r} export in provided JavaScript bundle."
)


Expand Down
8 changes: 4 additions & 4 deletions src/rtichoke/_vendor/rtichoke_viz/VENDORED_FROM
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
repository=https://github.com/uriahf/rtichoke_viz
release=v0.20.2
source_commit=40748bdeff7d535f516744886b64056f3aaa518d
archive=rtichoke-viz-0.20.2.tar.gz
sha256=2e4851159ceea0e3b2420c7e0aa22a566b94ec7057c27b13b7db7da88de34d11
release=v0.22.0
source_commit=e862776e2714dd20a7284bdb9c64c4bbe86962b3
archive=rtichoke-viz-0.22.0.tar.gz
sha256=64087fe0284ab2beb6e664dd419504a56000e217eaf403f33559896b67fff94d
Binary file not shown.
Binary file not shown.
Loading
Loading