Repository navigation
feat: export() writes DOT, Mermaid, GraphML, ELK JSON or a rendered image - #34
Merged
Merged
Conversation
…mage One method, g.export(filename=None, format=None, **options), replaces the idea of a method per format. The format is inferred from the extension when not given (.dot .gv .mmd .graphml .elk.json .svg .pdf .png ...). Exporters are plain functions in pgraph.exporters, registered by name, so a user can add one with @register_exporter. - text formats (dot, mermaid, graphml, elk) use only the standard library - image formats (svg, pdf, png, ...) run the GraphViz dot/neato executable, neato when any vertex has a coordinate so that positions are honoured, and raise a clear RuntimeError if it is missing - reproducible output: vertices in creation order, edges in the order of their vertices, rather than iterating the edge set - names are escaped per format; Mermaid/GraphML/ELK use generated ids - every edge is written, so parallel edges and self-loops are preserved - a path is closed even on error; a file object is never closed dotfile() and showgraph() are kept on top of it, with dotfile()'s output unchanged apart from the escaping and ordering fixes. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ring Rendering tests use the real GraphViz executables and are skipped when they are not installed; the missing-program error path is tested without. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 175 |
| Duplication | 0 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #34 +/- ##
==========================================
+ Coverage 90.76% 93.27% +2.50%
==========================================
Files 2 3 +1
Lines 845 1055 +210
==========================================
+ Hits 767 984 +217
+ Misses 78 71 -7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
- build GraphML as escaped text rather than with xml.etree (we only ever generate XML, never parse it); characters XML 1.0 cannot represent are replaced with U+FFFD so the output is always well formed - the GraphViz engine is checked against a fixed list of programs and the image format against a fixed list of formats; run with an argument list and no shell - narrow edge endpoints in _ordered_edges instead of using assert - do not shadow the builtins id / format in internal helpers Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
One method,
g.export(filename=None, format=None, **options), writes the graph as DOT, Mermaid, GraphML, ELK JSON, or a rendered image.formatdot.dot.gvpos="x,y!"direction,colorcomponents,costsmermaid.mmd.mermaiddirection,colorcomponents,costs,fencegraphml.graphmlx,y,coordelk.elk.json.elkx,ysize,layout_optionssvgpdfpngjpggifpsneatoengine,direction,colorcomponents,costsdot/neatodirectly and raise a clearRuntimeErrorif it is missing. (An earlier attempt imported thegraphvizPython package at module top level, even for the text formats.)pgraph.exporters, registered with@register_exporter(name, *extensions), so a format can be added without touchingPGraph.py.dotfile()andshowgraph()are kept as thin wrappers, so this is additive.Fixes over the old
dotfile()graph.edges(), aset, so the order changed between runs. Edges are now written in the order of their vertices, and parallel edges and self-loops are all kept.",\, a newline,<,&are escaped for each format; Mermaid, GraphML and ELK use generated ids so any name is valid.cost, ELKproperties.cost);dotfile()leaves it unlabelled as before.showgraph()no longer usesshell=True, and reports a missing GraphViz instead of silently doing nothing.For review
export()returns the text when no filename is given and returnsNonewhen it writes, whereasdotfile()prints. Easy to change; I preferred composability.showgraph(display=False)returns the PDF path (useful for tests and notebooks).Tests
tests/test_export.py, 50 tests: golden strings for dot and mermaid, parse-back for GraphML (ElementTree) and ELK (json), the multigraph and self-loop cases, escaping, reproducibility, dispatch and errors, a user-registered exporter, and real GraphViz rendering (skipped whendotis absent; the missing-program error path is tested without it). Full suite 213 passing, mypy and pyflakes clean on the changed files.Recovered from an earlier uncommitted attempt (2026-09-02), then ported to the current code and redesigned; see
claude-notes/export-formats-design.mdlocally.🤖 Generated with Claude Code