Skip to content

Matlab api tool v2#2

Open
petersenpeter wants to merge 6 commits intomainfrom
matlab_api_tool_v2
Open

Matlab api tool v2#2
petersenpeter wants to merge 6 commits intomainfrom
matlab_api_tool_v2

Conversation

@petersenpeter
Copy link
Copy Markdown
Collaborator

No description provided.

Introduce a +brainstem MATLAB package implementing the BrainSTEM API client and helpers: BrainstemClient, load_model, get_token, delete_model, numerous load_<model>.m convenience wrappers, and private helper functions (build_url, build_query_string, apply_field_filters, parse_api_error). Add comprehensive unit and integration tests (+brainstem/BrainstemTests.m) and update README and tutorial. Remove legacy top-level files replaced by the new package structure.
Rename and refactor core BrainSTEM API helpers and update tests accordingly. load_model/delete_model/save_model were renamed to load/delete/save and callers updated to use brainstem.* namespaced functions. get_token was reworked to use the device authorization flow with a fallback manual PAT flow, persist tokens to prefdir, and simplified signature; token save/update logic was added. load* helpers now accept empty settings (load_settings is invoked lazily), expose limit/offset/load_all pagination args, omit Authorization header for public requests, and surface unified error IDs (e.g. 'BrainSTEM:load'/'BrainSTEM:delete'). Unit tests were updated to match API changes and client token_type handling (PAT-only flow). Miscellaneous: inputParser validation tweaks, minor I/O/text improvements, and function renames in the +brainstem package files.
Revise the device authorization flow to match the server's newer API: use resp.device_code and resp.verification_uri_complete, open the verification URI as a char, and poll POST /api/auth/device/token/ with {device_code} instead of GET with state. Improve polling request options and response handling (handle success, expired_token, access_denied and other errors; treat authorization_pending as continued polling). Also handle the fallback manual PAT flow by saving the token when provided and return early. Misc: adjust weboptions naming and small control-flow cleanup.
Introduce private helpers to remove duplicated loader boilerplate and improve settings/token handling. Added brainstem_convenience_load to centralize common parsing/filter mapping for load_* functions and updated numerous load_* files to delegate to it. Added brainstem_get_settings to resolve URL/token from BRAINSTEM_URL/BRAINSTEM_TOKEN, cached credentials, or interactive flow; load_settings is now a deprecated wrapper. Added brainstem_normalize_list_response to normalize API list responses into struct arrays and integrated normalization into load/pagination. Add defensive checks and improvements: UUID validation for load/delete, guard against empty id deletes, default weboptions Timeout and error handling. Minor fixes: get_app_from_model maps 'group' → 'auth', updated tests to match new settings shape and examples/docs updated. These changes reduce duplication, make authentication more predictable, and make API responses more consistent.
Copy link
Copy Markdown

Copilot AI left a comment

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 introduces “MATLAB API tool v2” by replacing the legacy standalone MATLAB functions with a +brainstem package API and a BrainstemClient class that centralizes auth/settings and provides convenience loaders, plus updated docs/tutorials.

Changes:

  • Added BrainstemClient and a new +brainstem package (load/save/delete/get_token + convenience loaders) with token caching and device-flow authentication.
  • Refactored URL/query building and response normalization into shared private helpers.
  • Updated README.md, Contents.m, and brainstem_api_tutorial.m; removed the legacy v1 functions.

Reviewed changes

Copilot reviewed 43 out of 43 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
BrainstemClient.m New client wrapper around brainstem.* functions with auth retry/refresh logic.
+brainstem/load.m Core loader with filtering/sorting/include, paging, and optional auto-pagination.
+brainstem/save.m Core create/update (POST/PUT/PATCH) helper with validation and error parsing.
+brainstem/delete.m Core delete helper by UUID with 204 handling.
+brainstem/get_token.m Device authorization flow with fallback to manual PAT entry + token caching.
+brainstem/private/* Shared helpers for settings resolution, URL/query building, response normalization, and error parsing.
+brainstem/load_*.m Convenience loaders delegating to shared helper with model-specific defaults.
+brainstem/BrainstemTests.m New matlab.unittest coverage (offline/network/authenticated).
README.md Updated v2 usage docs, auth guidance, and API surface overview.
brainstem_api_tutorial.m Updated tutorial to demonstrate client-based workflows and new options.
Contents.m New package index/entry points summary for MATLAB.

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

Comment on lines +98 to +107
% Detect the data key dynamically: it is the response field whose
% value is a struct array (i.e. not the scalar metadata fields).
metadata_keys = {'count','next','previous'};
all_keys = fieldnames(output);
data_keys = all_keys(~ismember(all_keys, metadata_keys));
if ~isempty(data_keys)
model_key = data_keys{1}; % e.g. 'sessions', 'dataacquisitions'
else
model_key = '';
end
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

Auto-pagination selects the first non-metadata fieldname as the data key. When include[] is used, responses may contain multiple data arrays (e.g., sessions + behaviors + manipulations), and alphabetical field order can cause the wrong key to be appended, dropping/under-fetching the primary model. Prefer deriving the primary key from the requested model (e.g., sessions for model=session) and/or appending all non-metadata keys that are present in both pages.

Copilot uses AI. Check for mistakes.
Add brainstem.logout to remove cached tokens and document it in Contents/README. Require a non-empty token for brainstem.save and brainstem.delete to fail early. Improve brainstem_build_query_string to handle both N×2 and flat 1×(2N) filter layouts and preserve string/number formatting. Ensure brainstem_build_url normalizes trailing slashes and handles empty ids. Enhance brainstem_parse_api_error to prefer JSON validation bodies (showing field-level errors) while still including HTTP status when present. Make BrainstemClient honor BRAINSTEM_URL when no explicit url is provided. Add comprehensive unit tests covering these behaviors.
Allow brainstem.logout to accept name-value form (brainstem.logout('url', url)) and validate inputs; use BRAINSTEM_URL env var as default. Normalize the on-disk authentication table schema in get_token/save_token_: add missing columns ('usernames', 'saved_at'), canonicalize column order, and build new rows consistently so older auth files are upgraded. Improve save feedback to print the auth file path. Add BrainstemClient.logout to clear the client's in-memory token and remove the saved token for the client's URL. Update unit tests (BrainstemTests) to match the new table schema and add a test for the name-value logout form.
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