Skip to content

feat: add .view()#306

Open
samwaseda wants to merge 12 commits into
mainfrom
display
Open

feat: add .view()#306
samwaseda wants to merge 12 commits into
mainfrom
display

Conversation

@samwaseda

Copy link
Copy Markdown
Member

Closes #304

I absolutely love it

Screenshot 2026-07-24 at 10 54 02

@github-actions

Copy link
Copy Markdown

Binder 👈 Launch a binder notebook on branch pyiron/flowrep/display

@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.79592% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.80%. Comparing base (c1225b0) to head (0f797b9).

Files with missing lines Patch % Lines
src/flowrep/retrospective/viewer.py 90.90% 4 Missing ⚠️
src/flowrep/retrospective/datastructures.py 80.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #306      +/-   ##
==========================================
- Coverage   99.94%   99.80%   -0.15%     
==========================================
  Files          43       44       +1     
  Lines        3470     3519      +49     
==========================================
+ Hits         3468     3512      +44     
- Misses          2        7       +5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@samwaseda

Copy link
Copy Markdown
Member Author

@copilot Address the mypy problem

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

@copilot Address the mypy problem

Fixed in b098854. The mypy error was from mutating a value narrowed as Mapping, so I changed that path to build a new dict instead. I also verified python -m mypy src/flowrep/retrospective/datastructures.py passes locally.

@samwaseda
samwaseda requested review from Copilot and liamhuber and removed request for Copilot July 24, 2026 09:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses readability concerns for retrospective DAG data (#304) by adding a notebook-friendly .view() method to retrospective NodeData objects, rendering them as structured/collapsible JSON via IPython’s JSON display helper.

Changes:

  • Add NodeData.view() plus internal helpers to serialize retrospective objects into JSON-friendly structures and display them with IPython.display.JSON.
  • Add unit tests for .view() and the JSON display helper (skipped when IPython is unavailable).
  • Add a minimal identity atomic in the static test library to support the new view tests.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/flowrep/retrospective/datastructures.py Adds .view() to NodeData and implements _to_jsonable + _display_json to produce notebook-friendly JSON output.
tests/unit/test_retrospective_wfms.py Adds tests validating .view() behavior and the _display_json helper, gated on IPython availability.
tests/flowrep_static/library.py Adds a simple identity atomic used by the new view tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@liamhuber liamhuber left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I love the way it looks too!

Only technical notes:

  • At 40 lines, let's go ahead an refactor it over to its own module flowrep.retrospective.viewer, and have NodeData.view just call the view routine from there (should have no trouble with circular imports because viewer should only need NodeData behind a IF_TYPE_CHECKING:)
  • Let's have a backup str representation when ipython is not available; NodeData.view turns into viewer._view_json, write a simple viewer._view_str, and have viewer.view branch to either depending on _has_ipython
  • Formalize the optionality, but adding a new optional dependency section to the pyproject.toml -- I think "dataviewer" is an ok name but don't feel strongly
  • Fix the coverage by adding ipython to the .ci_support/environment-optional.yml; the CI is already set up so this will get it into the main testing cycle and clock our coverage, but the skipif stuff is still brilliant because we also do a separate test run without these optional dependencies

@liamhuber

Copy link
Copy Markdown
Member
  • Let's have a backup str representation when ipython is not available

I don't really care how pretty this is; if you're feeling lazy str(data) is already enough for me -- it's just about making sure there is a non-destructive branch to follow so users who ask for view() when it's not there can avoid a hard exception.

Comment thread tests/flowrep_static/library.py Outdated
Comment thread tests/unit/test_retrospective_wfms.py Outdated
@samwaseda

Copy link
Copy Markdown
Member Author

Yep, I love the way it looks too!

Only technical notes:

  • At 40 lines, let's go ahead an refactor it over to its own module flowrep.retrospective.viewer, and have NodeData.view just call the view routine from there (should have no trouble with circular imports because viewer should only need NodeData behind a IF_TYPE_CHECKING:)
  • Let's have a backup str representation when ipython is not available; NodeData.view turns into viewer._view_json, write a simple viewer._view_str, and have viewer.view branch to either depending on _has_ipython
  • Formalize the optionality, but adding a new optional dependency section to the pyproject.toml -- I think "dataviewer" is an ok name but don't feel strongly
  • Fix the coverage by adding ipython to the .ci_support/environment-optional.yml; the CI is already set up so this will get it into the main testing cycle and clock our coverage, but the skipif stuff is still brilliant because we also do a separate test run without these optional dependencies

@copilot Address these points

@samwaseda

Copy link
Copy Markdown
Member Author

oh my goodness what can I do without AI...

@liamhuber liamhuber left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do Niklas' reprjson idea as well, then I'm happy

Display this data object as structured JSON in a notebook and return the display
object. Falls back to a plain-text representation when IPython is not available.
"""
from flowrep.retrospective import viewer

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ruff should complain about this non-head import. Since viewer only imports this module behind a type checking flag, it should be perfectly safe to move this up to the top

@liamhuber

Copy link
Copy Markdown
Member

And the moment this is in we can go ahead and make a patch release. It's great and simple so let's get it available

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dag data difficult to read

5 participants