Preserving Non‑JSON‑Serializable Attributes in NetworkX JSON Serialization
0 reputation · 16 Jun 2022, 09:10 UTC
0 reputation · 16 Jun 2022, 09:10 UTC
When migrating a small NetworkX application to a newer version without downtime, the JSON serialization helpers (`node_link_data`/`node_link_graph`) must retain all node and edge attributes.
However, the current API only preserves attributes that are JSON‑serializable; custom Python objects, lambdas, or mutable structures are omitted, and the format of the JSON output is not version‑locked, meaning upgrades may alter field names or nesting.
Uncertainty remains about how duplicate edges with differing attributes are handled in MultiGraphs and whether a stable schema exists for safe deserialization across releases.
How can non‑JSON‑serializable attributes be preserved during migration? Is there a documented version‑stable JSON schema for NetworkX graphs? What strategies exist for handling duplicate edge attributes in MultiGraph serialization?
35775 reputation · 16 Jun 2022, 20:40 UTC
Non‑JSON‑serializable attributes are preserved by converting them into JSON‑compatible envelopes (type tags plus base64 or constructor data) before json.dumps, then running a restoration pass after node_link_graph.
\nConfirmed facts
\nLikely strategies for migration
\nParallel edges without deterministic keys are not safely round‑trippable. If your graph lacks explicit edge keys, assign them before serialization.
\nMissing diagnostic: Do any node or edge attributes contain lambdas, custom objects, or sets that must survive deserialization? This determines whether an envelope‑encoding restoration pass is required or if exclusion is acceptable.
Use comments to ask for clarification. Post a solution as an answer.
35,775 reputation · 16 Jun 2022, 12:47 UTC
One detail worth emphasizing: node_link_data places every serializable attribute inside each link’s attributes object, so your envelope key (e.g., __custom__) must live there—not at the link root. For MultiGraph round-trips, the key field is the only thing that distinguishes parallel edges; if you synthesize keys before serialization, use a deterministic scheme (hash of endpoint IDs plus attribute fingerprint) so that a later NetworkX release that reorders links won’t scramble multiplicity. Finally, because the library does not version its JSON contract, wrap the entire encode/decode pipeline in a small integration test that asserts node/edge counts, key sets, and attribute keys match a frozen fixture—this catches silent schema drift before it reaches production.