Repository navigation
Add ndi.cloud.api.feedback; fix bridge CI for MATLAB files on an unmerged branch - #323
Conversation
Port of NDI-matlab#1023 (75f937a76): wrappers for the in-app problem
report endpoints from ndi-cloud-node#158.
- submitFeedback(app, category, description, *, appVersion, datasetId,
documentId, environment, state, log, traceback) POSTs /feedback with
schemaVersion 1. Optional fields keep MATLAB's camelCase names because
they are the shared payload keys; None omits a field, as MATLAB's
missing / struct.empty do. Returns an APIResponse whose data is the
stored report id.
- deleteFeedback(feedbackID) DELETEs /feedback/{feedbackId} (204).
- FeedbackCategory validator in _validators.py (bug/performance/other).
- Bridge entries for both; url bumped to 75f937a76 for the two new
routes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B22A1gLVKa1E3uQm3tv4t8
Port of NDI-matlab feedbackTest.m (75f937a76). - tests/test_cloud_api_feedback.py: real CloudClient over a stub transport; pins the exact payload, optional-field omission, URL and method, MATLAB-style unpacking, client-side validation, and the 400/401/403/404/413/429 error mapping. POST is not retried. - tests/test_cloud_feedback_live.py: the live cases, skipped without credentials or where the endpoint is not deployed (404 on a malformed id); every submitted report is deleted, with a teardown backstop. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B22A1gLVKa1E3uQm3tv4t8
|
Update: the bridge failure is fixed on this PR (03e5f26, 26f859a, 8775099). It was already red on Cause.
Fix. A bridge entry can now carry Drift cleared, no Python change needed:
Locally, against NDI-matlab Generated by Claude Code |
…branch NDI-python main records MATLAB files (the lightsheet OME-Zarr functions, LightsheetZarrManager, resolveOrganizationId, and six ndi_common document files) that exist only on VH-Lab/NDI-matlab claude/lightsheet-zarr-ndi-viewer-djp5vk, which has not merged. CI checks out NDI-matlab main, so the bridge job has been red on main since 2026-09-26, reporting them as stale paths. Add a matlab_branch field (and MATLAB_BRANCH_PENDING for ndi_common) that names the branch, and check the claim rather than skip it: - the branch must exist and the file be on it (ndi_common: byte-identical); - drift is measured against the branch tip instead of HEAD; - once the branch merges into NDI-matlab main, the marker must be removed. Helpers in tests/_matlab_branch.py, tested against a throwaway git repo in tests/test_matlab_branch_pending.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B22A1gLVKa1E3uQm3tv4t8
…sheet drift - matlab_branch on resolveOrganizationId, LightsheetZarrManager and the eight +ndi/+fun/+doc/+lightsheet entries. - fromOMEZarr / makePyramid / chooseTileShape: examined against 5c9e8a83 on that branch (default tile budget 8 MB -> 32 MB). No Python counterpart yet, nothing to follow; noted in each decision_log. - decodeJwt: examined against 4a571dce (NDI-matlab#1024, Java base64 decoder replaced by matlab.net.base64decode). Python uses the stdlib; nothing to follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B22A1gLVKa1E3uQm3tv4t8
Section 8 of docs/developer_notes/ndi_matlab_python_bridge.yaml defines when an entry may name an NDI-matlab branch and how the checks hold it to account; the field table and the porting guide point there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B22A1gLVKa1E3uQm3tv4t8
Brings in ndi.cloud.api.feedback (submitFeedback, deleteFeedback) and its tests (#323) plus the bridge checks for MATLAB files that live on an NDI-matlab branch, ahead of the viewer's Report-a-problem button. Conflict: src/ndi/fun/doc_lightsheet/ndi_matlab_python_bridge.yaml. Both sides recorded the NDI-matlab 5c9e8a8 tile-budget bump; took main's entries, which add the matlab_branch field its new bridge checks use. Semantic fix: this branch's CloudClient re-authenticates on 401/403 when _can_reauth is set (initialised in __init__). The feedback tests build a client with CloudClient.__new__, so their helper now sets _can_reauth = False, as test_cloud_client_retry's helper does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016wj6cuvAwgAaYN5dNM1o6L
Summary
Two pieces of work:
ndi.cloud.api.feedback(submitFeedback,deleteFeedback) from NDI-matlab#1023. The endpoints are the in-app problem report API in ndi-cloud-node#158.mainsince 2026-09-26.mainrecords MATLAB files that exist only on the unmerged NDI-matlab branchclaude/lightsheet-zarr-ndi-viewer-djp5vk.1. Feedback API
src/ndi/cloud/api/feedback.py:submitFeedback(app, category, description, *, appVersion, datasetId, documentId, environment, state, log, traceback)sendsPOST /feedbackwithschemaVersion: 1.deleteFeedback(feedbackID)sendsDELETE /feedback/{feedbackId}._submit()sends a body as-is, like MATLAB'sSubmitFeedbackclass. The tests use it to reach the server's own validation.Noneis not sent, like MATLAB'smissing/struct.empty.""and{}are sent.APIResponsethat unpacks like MATLAB's outputs:b, feedbackID, status, url = submitFeedback(...).ndi.cloud.apifunction:CloudAPIErrorwithstatus_code400, 413 or 429;CloudNotFoundErrorfor a missing report;CloudAuthErrorfor 401/403.FeedbackCategoryvalidator in_validators.py(bug/performance/other), and the module is registered inndi.cloud.api.__init__.tests/test_cloud_api_feedback.py(offline): a realCloudClientover a stub transport. It checks the exact request body, each optional field, URL and method, the unpacking, input checks, the error mapping, and that POST is not retried.tests/test_cloud_feedback_live.py: ports the server-facing cases offeedbackTest.m. It skips without credentials, or when the endpoint is not deployed (404 for a malformed id). Every submitted report is deleted, with a cleanup step if a test fails part-way.2. Bridge CI: MATLAB files on an NDI-matlab branch
Cause. The bridge job checks out NDI-matlab
main, or a branch named like the PR's. These NDI-pythonmainrecords point at files that are only onclaude/lightsheet-zarr-ndi-viewer-djp5vk:resolveOrganizationIdLightsheetZarrManager+ndi/+fun/+doc/+lightsheet/*.mfunctionsndi_commonCI reported every one as a stale path. Neither existing escape fits:
matlab_path: "N/A"andretiredboth say the MATLAB file doesn't exist, which is false.Fix. An entry can now carry
matlab_branch: <branch>, andndi_commonfiles have a matchingMATLAB_BRANCH_PENDINGmap. The checks verify the claim rather than skip it:ndi_common);main, the check fails until the marker is removed. "Merged" is checked againstmain, not the checked-out tree, so CI on the branch itself doesn't trip it.The helpers are in
tests/_matlab_branch.py.tests/test_matlab_branch_pending.pytests them against a throwaway git repo, so it runs in every job.Entries updated.
matlab_branchadded to the 10 affected entries.fromOMEZarr,makePyramidandchooseTileShapenow record 5c9e8a83 on the branch (default tile budget raised from 8 MB to 32 MB). None has a Python port yet, so there was nothing to follow; eachdecision_logsays so.decodeJwtnow records 4a571dce (NDI-matlab#1024). MATLAB replaced a Java base64 decoder it no longer ships withmatlab.net.base64decode. Python uses the standard library, so there was nothing to follow.urlnow records 75f937a76, for the two feedback routes.Docs. New section 8 in
docs/developer_notes/ndi_matlab_python_bridge.yamlsays whenmatlab_branchmay be used. It is also in the field table, andPYTHON_PORTING_GUIDE.mdpoints to it.Test plan
black --checkandruff checkare clean.main.🤖 Generated with Claude Code
https://claude.ai/code/session_01B22A1gLVKa1E3uQm3tv4t8