Skip to content

Handle NaN and null placeholders in JSON responses#45

Merged
stevevanhooser merged 5 commits into
mainfrom
claude/fix-ndi-nan-placeholder-fCqhB
Mar 22, 2026
Merged

Handle NaN and null placeholders in JSON responses#45
stevevanhooser merged 5 commits into
mainfrom
claude/fix-ndi-nan-placeholder-fCqhB

Conversation

@stevevanhooser
Copy link
Copy Markdown
Contributor

Summary

This PR adds support for rehydrating NaN and null placeholders in JSON responses from the NDI cloud API. JSON doesn't natively support NaN values, so the API uses placeholder strings that need to be converted back to proper JSON null values before parsing.

Key Changes

  • Added json import to src/ndi/cloud/client.py
  • Modified _handle_response() in client.py to use rehydrateJSONNanNull() utility function before parsing JSON responses
  • Updated _download_chunk_zip() in download.py to decode and rehydrate JSON text from zip file entries before parsing
  • Added import of rehydrateJSONNanNull utility function in download.py

Implementation Details

  • The rehydrateJSONNanNull() function is called on the raw response text before json.loads() to convert placeholder strings back to valid JSON null values
  • In the download module, zip file contents are explicitly decoded to UTF-8 strings before rehydration and parsing
  • This ensures consistent JSON parsing behavior across both direct API responses and downloaded zip file contents

https://claude.ai/code/session_0123bjBh3DEvxwphenpH1i1b

claude added 5 commits March 22, 2026 16:17
The cloud API stores NaN/Infinity as sentinel strings (e.g. "__NDI__NaN__")
since JSON doesn't support these values natively. The MATLAB version calls
rehydrateJSONNanNull to convert these back before use, but the Python
version was missing this step. Documents downloaded from the cloud retained
the placeholder strings instead of actual NaN/Infinity values.

Apply rehydrateJSONNanNull in two places:
- _download_chunk_zip: rehydrate raw JSON text from bulk-download ZIPs
  before json.loads
- CloudClient._handle_response: rehydrate API response text before JSON
  parsing, so individual document fetches (e.g. getDocument) also get
  proper NaN/Infinity values

https://claude.ai/code/session_0123bjBh3DEvxwphenpH1i1b
Remove four functions that corresponded to deleted MATLAB files:
- dataset() + downloadFullDataset alias: old entry point that downloaded
  docs one-by-one and wrote them to disk as JSON files
- datasetDocuments(): individual document download + JSON file save
- setFileInfo(): file_info patching, now in sync layer
  (updateFileInfoForRemoteFiles in filehandler.py)

The modern pipeline (downloadDocumentCollection → orchestration.downloadDataset)
uses bulk ZIP download with proper NaN rehydration and returns documents
in memory without a disk round-trip.

Retained functions still used by orchestration.py:
- downloadDocumentCollection, jsons2documents, structsToNdiDocuments,
  downloadDatasetFiles, downloadFilesForDocument, downloadGenericFiles

https://claude.ai/code/session_0123bjBh3DEvxwphenpH1i1b
The MATLAB file +ndi/+cloud/+download/+internal/setFileInfo.m was
deleted; remove it from the MATLAB equivalents list in the module
docstring.

https://claude.ai/code/session_0123bjBh3DEvxwphenpH1i1b
Python's IEEE 754 semantics make float('nan') != float('nan'), which
caused doc.diff to report spurious mismatches for document properties
containing NaN values. The MATLAB ndi.fun.dataset.diff was updated to
treat NaN == NaN; apply the same logic in the Python _compare helper.

https://claude.ai/code/session_0123bjBh3DEvxwphenpH1i1b
@stevevanhooser stevevanhooser merged commit 546a460 into main Mar 22, 2026
5 checks passed
@stevevanhooser stevevanhooser deleted the claude/fix-ndi-nan-placeholder-fCqhB branch March 22, 2026 17:37
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.

2 participants