Skip to content

Feature/SOF-7836 Update: use clusters API#270

Merged
VsevolodX merged 7 commits intomainfrom
feature/SOF-7836
Feb 28, 2026
Merged

Feature/SOF-7836 Update: use clusters API#270
VsevolodX merged 7 commits intomainfrom
feature/SOF-7836

Conversation

@VsevolodX
Copy link
Member

@VsevolodX VsevolodX commented Feb 20, 2026

Summary by CodeRabbit

  • New Features

    • Added IDE package to example environment for easier notebook setup.
  • Bug Fixes

    • Improved notebook compute/configuration flow: clearer cluster selection and more reliable job submission and result retrieval.
  • Chores

    • Updated project dependencies to specific remote releases and removed a local dependency for reproducible environments.

@review-notebook-app
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@coderabbitai
Copy link

coderabbitai bot commented Feb 20, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3c9f538 and 8cb56b9.

📒 Files selected for processing (1)
  • pyproject.toml
🚧 Files skipped from review as they are similar to previous changes (1)
  • pyproject.toml

📝 Walkthrough

Walkthrough

Updated dependency sourcing and added mat3ra-ide; migrated the band_gap notebook to list clusters via client.clusters.list(), construct Compute(cluster=..., queue=..., ppn=...), and pass compute.to_dict() to job creation. Minor dependency reorder in pyproject and config.yml package addition.

Changes

Cohort / File(s) Summary
Config / Packaging
config.yml, pyproject.toml
Added mat3ra-ide to api_examples.packages_common. Replaced local mat3ra-api-client reference with git-sourced mat3ra-ide and mat3ra-api-client entries and adjusted dependency ordering/comments.
Notebook Workflow API Migration
other/materials_designer/workflows/band_gap.ipynb
Refactored compute setup: list clusters via client.clusters.list(), import Compute and QueueName, construct Compute(cluster=..., queue=QueueName.D, ppn=...), and pass compute.to_dict() to client.jobs.create_by_ids. Notebook cell IDs and sections renumbered; property retrieval preserved using PropertyName.non_scalar.band_gaps.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Notebook as Notebook (band_gap.ipynb)
participant Client as mat3ra.api.Client
participant Clusters as Clusters Service
participant Jobs as Jobs Service
participant Properties as Properties Service

Notebook->>Client: client.clusters.list()
Client->>Clusters: list clusters
Clusters-->>Client: clusters[]
Client-->>Notebook: clusters (pick first)
Notebook->>Notebook: construct Compute(cluster, queue, ppn)
Notebook->>Client: client.jobs.create_by_ids(..., compute=compute.to_dict())
Client->>Jobs: create job with compute dict
Jobs-->>Client: job id
Notebook->>Client: client.properties.get_for_job(job_id, PropertyName.non_scalar.band_gaps)
Client->>Properties: fetch non_scalar.band_gaps for job
Properties-->>Client: band gap results
Client-->>Notebook: results

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • timurbazhirov

Poem

🐰 I hopped through notebooks, neat and spry,
Listed clusters, gave compute a try.
Dictified compute, fetched band gaps bright,
A tiny rabbit’s code-delight. 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feature/SOF-7836 Update: use clusters API' accurately describes the main changes, which involve integrating the clusters API into the workflow and updating dependency configurations to support this integration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/SOF-7836

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
utils/visualize.py (1)

406-408: Filter logic is correct; consider an early return when all results are filtered out.

The "value" in r or "values" in r check is the right way to guard displayable entries. One minor usability gap: if every item is stripped by the filter, the function proceeds silently — renderResults receives [] with no user-visible feedback.

💡 Optional early-return guard
     results = [r for r in results if "value" in r or "values" in r]
+
+    if not results:
+        print("No displayable properties found in results.")
+        return
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@utils/visualize.py` around lines 406 - 408, After filtering results with
results = [r for r in results if "value" in r or "values" in r], add an
early-return guard that detects an empty results list and surfaces a
user-visible message instead of passing [] to renderResults; e.g., if not
results: call renderResults with a succinct "No displayable results" message (or
invoke an existing no-results helper) and return from the current function so
downstream code (and renderResults) aren't invoked with an empty list.
pyproject.toml (1)

12-19: Both git dependencies are pinned to anonymous commit hashes — prefer named tags.

mat3ra-api-client@141d7dba... and mat3ra-prode@5b2e02dd... are bare SHA pins with no corresponding tag reference. This makes it impossible to tell at a glance what feature or release the pin corresponds to, and makes future bump PRs harder to review. Pin to a release tag (or at minimum add an inline comment with the version/date) once tags are available on those repos.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pyproject.toml` around lines 12 - 19, The two git dependencies in
pyproject.toml are pinned to raw commit SHAs ("mat3ra-api-client @
git+https://github.com/Exabyte-io/api-client.git@141d7dba220f07844e97557dda3ee74087b38c31"
and "mat3ra-prode @
git+https://github.com/Exabyte-io/prode.git@5b2e02ddbaf5dd473f0acaf1e1d76ddadc6bb184");
replace each SHA with the corresponding release tag (or branch name) from those
repositories (e.g., vX.Y.Z) so the dependency shows a human-readable version, or
if tags are not yet available add a short inline comment after the dependency
naming the intended version/date and why the SHA is used; update the two entries
"mat3ra-api-client" and "mat3ra-prode" accordingly and run your dependency
installer to verify resolution.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@other/materials_designer/workflows/band_gap.ipynb`:
- Around line 517-526: The code assumes at least one cluster exists and directly
indexes clusters[0], which raises IndexError when client.clusters.list() returns
an empty list; add a guard that checks the clusters list (e.g., if not clusters
or len(clusters) == 0) before using clusters[0], and handle the empty case by
raising a clear exception or logging an error and aborting/using a fallback
cluster; update the block around the clusters variable and the Compute(...)
instantiation (Compute, cluster, QueueName.D, ppn) to only construct Compute
when a valid cluster is present.
- Around line 103-115: Remove the hardcoded os.environ assignments
(os.environ["API_HOST"], ["API_PORT"], ["API_SECURE"]) and the unused
API_HOST/API_PORT/API_SECURE/API_VERSION variables from the notebook cell;
instead either delete the cell or replace it with a short opt-in snippet or
commented example showing how to set local overrides (e.g., guarded by a boolean
flag like use_local = False or instructions to export env vars externally)
because APIClient.authenticate() reads from environment variables and these
assignments currently force all runs to localhost:3000.

In `@pyproject.toml`:
- Around line 11-12: The comment above the dependency line is incorrect — it
mentions "file URIs" and the three-slash rule, but the dependency
"mat3ra-api-client @
git+https://github.com/Exabyte-io/api-client.git@141d7dba220f07844e97557dda3ee74087b38c31"
is a VCS/git URL; update the comment to accurately describe that this is a git
VCS dependency using a commit SHA via the git+https://...@<commit> format (or
similar VCS URL guidance), and remove any reference to file URI syntax so the
comment correctly reflects the format used by the dependency line.

---

Nitpick comments:
In `@pyproject.toml`:
- Around line 12-19: The two git dependencies in pyproject.toml are pinned to
raw commit SHAs ("mat3ra-api-client @
git+https://github.com/Exabyte-io/api-client.git@141d7dba220f07844e97557dda3ee74087b38c31"
and "mat3ra-prode @
git+https://github.com/Exabyte-io/prode.git@5b2e02ddbaf5dd473f0acaf1e1d76ddadc6bb184");
replace each SHA with the corresponding release tag (or branch name) from those
repositories (e.g., vX.Y.Z) so the dependency shows a human-readable version, or
if tags are not yet available add a short inline comment after the dependency
naming the intended version/date and why the SHA is used; update the two entries
"mat3ra-api-client" and "mat3ra-prode" accordingly and run your dependency
installer to verify resolution.

In `@utils/visualize.py`:
- Around line 406-408: After filtering results with results = [r for r in
results if "value" in r or "values" in r], add an early-return guard that
detects an empty results list and surfaces a user-visible message instead of
passing [] to renderResults; e.g., if not results: call renderResults with a
succinct "No displayable results" message (or invoke an existing no-results
helper) and return from the current function so downstream code (and
renderResults) aren't invoked with an empty list.

Comment on lines 517 to 526
"from mat3ra.ide.compute import Compute, QueueName\n",
"\n",
"CLUSTER_NAME = get_cluster_name()\n",
"cluster = clusters[0]\n",
"\n",
"compute = client.jobs.build_compute_config(\n",
" cluster=CLUSTER_NAME\n",
"compute = Compute(\n",
" cluster=cluster,\n",
" queue=QueueName.D,\n",
" ppn=2\n",
")"
]
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

clusters[0] raises IndexError when no clusters are available.

client.clusters.list() could return an empty list (no clusters provisioned for the account, API error, etc.), causing an unhandled IndexError on the next line.

🛡️ Proposed guard
 cluster = clusters[0]
+if not clusters:
+    raise RuntimeError("No clusters available for this account. Please provision a cluster first.")
+cluster = clusters[0]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@other/materials_designer/workflows/band_gap.ipynb` around lines 517 - 526,
The code assumes at least one cluster exists and directly indexes clusters[0],
which raises IndexError when client.clusters.list() returns an empty list; add a
guard that checks the clusters list (e.g., if not clusters or len(clusters) ==
0) before using clusters[0], and handle the empty case by raising a clear
exception or logging an error and aborting/using a fallback cluster; update the
block around the clusters variable and the Compute(...) instantiation (Compute,
cluster, QueueName.D, ppn) to only construct Compute when a valid cluster is
present.

@VsevolodX VsevolodX changed the base branch from main to feature/SOF-7824 February 20, 2026 01:42
@@ -465,7 +465,8 @@
"id": "34",
Copy link
Member

@timurbazhirov timurbazhirov Feb 21, 2026

Choose a reason for hiding this comment

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

Line #8.        ppn=2

Let's keep default


Reply via ReviewNB

Base automatically changed from feature/SOF-7824 to main February 25, 2026 22:06
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
other/materials_designer/workflows/band_gap.ipynb (1)

501-505: Remove explicit ppn parameter to use the default value.

The Compute class has a default ppn value of 1. The explicit ppn=2 parameter can be removed to rely on the default, simplifying the code.

♻️ Proposed fix
 compute = Compute(
     cluster=cluster,
     queue=QueueName.D,
-    ppn=2
 )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@other/materials_designer/workflows/band_gap.ipynb` around lines 501 - 505,
The code explicitly sets ppn=2 when constructing Compute
(Compute(cluster=cluster, queue=QueueName.D, ppn=2)); remove the ppn argument so
the constructor relies on the class default (ppn=1). Update the Compute
instantiation to omit the ppn parameter and leave cluster and queue unchanged,
e.g., use Compute(cluster=cluster, queue=QueueName.D).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@other/materials_designer/workflows/band_gap.ipynb`:
- Around line 501-505: The code explicitly sets ppn=2 when constructing Compute
(Compute(cluster=cluster, queue=QueueName.D, ppn=2)); remove the ppn argument so
the constructor relies on the class default (ppn=1). Update the Compute
instantiation to omit the ppn parameter and leave cluster and queue unchanged,
e.g., use Compute(cluster=cluster, queue=QueueName.D).

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7993769 and da70d6b.

📒 Files selected for processing (3)
  • config.yml
  • other/materials_designer/workflows/band_gap.ipynb
  • pyproject.toml
🚧 Files skipped from review as they are similar to previous changes (2)
  • config.yml
  • pyproject.toml

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
other/materials_designer/workflows/band_gap.ipynb (1)

498-505: ⚠️ Potential issue | 🟡 Minor

Guard against empty clusters list.

clusters[0] will raise IndexError if client.clusters.list() returns an empty list (no clusters provisioned, API error, etc.). This concern was flagged in a previous review and remains unaddressed.

🛡️ Proposed guard
 from mat3ra.ide.compute import Compute, QueueName

+if not clusters:
+    raise RuntimeError("No clusters available for this account. Please provision a cluster first.")
 cluster = clusters[0]
 compute = Compute(
     cluster=cluster,
     queue=QueueName.D,
     ppn=2
 )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@other/materials_designer/workflows/band_gap.ipynb` around lines 498 - 505,
The code assumes clusters[0] exists and will IndexError if the clusters list is
empty; before selecting cluster for Compute (the variable cluster and class
Compute/QueueName), check that clusters is non-empty (e.g., if not clusters:
handle error or raise a clear exception or log and exit) and only then assign
cluster = clusters[0] and construct Compute; ensure the error path provides a
clear message about no available clusters so callers/debugging can proceed
safely.
🧹 Nitpick comments (1)
other/materials_designer/workflows/band_gap.ipynb (1)

501-505: Consider removing hardcoded ppn=2 per reviewer feedback.

A previous reviewer requested keeping the default value for ppn. If Compute has a sensible default, omitting ppn would make this example more portable across different cluster configurations.

♻️ Proposed change
 compute = Compute(
     cluster=cluster,
     queue=QueueName.D,
-    ppn=2
 )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@other/materials_designer/workflows/band_gap.ipynb` around lines 501 - 505,
The snippet hardcodes ppn=2 when constructing Compute; remove the ppn argument
so Compute(cluster=cluster, queue=QueueName.D) relies on its internal/default
ppn value; update the call site where Compute(...) is created (refer to the
Compute constructor usage with cluster and QueueName.D) and ensure no other code
assumes ppn was explicitly set.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@other/materials_designer/workflows/band_gap.ipynb`:
- Around line 498-505: The code assumes clusters[0] exists and will IndexError
if the clusters list is empty; before selecting cluster for Compute (the
variable cluster and class Compute/QueueName), check that clusters is non-empty
(e.g., if not clusters: handle error or raise a clear exception or log and exit)
and only then assign cluster = clusters[0] and construct Compute; ensure the
error path provides a clear message about no available clusters so
callers/debugging can proceed safely.

---

Nitpick comments:
In `@other/materials_designer/workflows/band_gap.ipynb`:
- Around line 501-505: The snippet hardcodes ppn=2 when constructing Compute;
remove the ppn argument so Compute(cluster=cluster, queue=QueueName.D) relies on
its internal/default ppn value; update the call site where Compute(...) is
created (refer to the Compute constructor usage with cluster and QueueName.D)
and ensure no other code assumes ppn was explicitly set.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between da70d6b and c23430a.

📒 Files selected for processing (2)
  • other/materials_designer/workflows/band_gap.ipynb
  • pyproject.toml

@VsevolodX VsevolodX merged commit 45dea36 into main Feb 28, 2026
5 checks passed
@VsevolodX VsevolodX deleted the feature/SOF-7836 branch February 28, 2026 02:52
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