Skip to content

feat(cache): add read-only cache inspection command (sebs resources inspect) - #310

Open
sanskar-singh-2403 wants to merge 1 commit into
spcl:masterfrom
sanskar-singh-2403:feat/cache-inspect
Open

feat(cache): add read-only cache inspection command (sebs resources inspect)#310
sanskar-singh-2403 wants to merge 1 commit into
spcl:masterfrom
sanskar-singh-2403:feat/cache-inspect

Conversation

@sanskar-singh-2403

@sanskar-singh-2403 sanskar-singh-2403 commented Jul 28, 2026

Copy link
Copy Markdown

Summary

Adds sebs resources inspect, a read-only command that visualizes the
on-disk cache without contacting any cloud provider or requiring a Docker
daemon. Addresses #306.

Per the discussion on the issue, this extends the existing
sebs.cache.Cache API rather than introducing a separate inspection layer,
and lives as a subcommand under the existing resources command group.

What it shows

  • Deployed benchmarks: benchmark, platform, language, packaging
    (container vs code_package), number of functions, and trigger types.
  • Allocated resources per platform: resources_id, region, storage
    bucket count, and locally allocated ports.

Changes

  • Extend sebs.cache.Cache with two read-only helpers:
    • get_deployed_benchmarks(): flattens the per-benchmark config.json
      files into rows of (benchmark, platform, language, packaging,
      functions, triggers, storage, nosql).
    • get_allocated_resources(): reads the per-cloud files (aws.json,
      local.json, ...) for resources_id, region, storage buckets, and
      locally allocated ports.
  • Make Cache docker_client optional so read-only consumers can open a
    cache without a running Docker daemon; guard the container-caching paths
    with an assertion.
  • Add the resources inspect CLI command with a rich table view and a
    --json output mode, plus an optional --deployment platform filter.
  • Add offline unit tests that build a synthetic cache directory.

Usage

sebs resources inspect --cache ./cache
sebs resources inspect --cache ./cache --deployment aws
sebs resources inspect --cache ./cache --output json

Test plan

  • Offline unit tests pass (synthetic cache directory)
  • black, flake8, mypy, and interrogate (100%) pass locally
  • Verified table, JSON, and --deployment filter against a real cache

Addresses #306.



<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added a read-only `resources inspect` command for viewing cached benchmark deployments and allocated cloud resources.
  - Supports deployment filtering and JSON, static table, or interactive expandable views.
  - Displays packaging, triggers, URLs, storage and NoSQL details, regions, resource classes, and allocated ports.
  - Cache inspection works without Docker, while Docker-dependent operations provide clear errors when unavailable.
- **Tests**
  - Added offline and headless coverage for filtering, resource grouping, empty caches, and read-only behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

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
📝 Walkthrough

Walkthrough

The change adds offline cache inspection APIs, a resources inspect CLI command, and a Textual interface. It supports JSON, Rich, and interactive output, optional Docker clients, cloud filtering, detached results, and offline tests.

Changes

Cache inspection

Layer / File(s) Summary
Cache inspection APIs
sebs/cache.py
Cache accepts an optional Docker client, centralizes supported clouds, exposes benchmark and resource inspection methods, and guards Docker-dependent package operations.
Resources inspection command
sebs/cli.py, pyproject.toml, requirements.txt
Adds resources inspect with deployment filtering and JSON, Textual, or Rich output. Adds the Textual dependency.
Interactive resource inspector
sebs/tui/...
Adds an expandable Textual tree that groups benchmarks and allocated resources by cloud and resource class.
Offline inspection coverage
tests/test_cache_inspect.py, tests/test_tui_inspect.py
Tests cache flattening, resource summaries, filtering, read-only behavior, inventory grouping, and headless UI rendering.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant resources_inspect
  participant Cache
  participant ResourceInspectorApp

  Operator->>resources_inspect: invoke resources inspect
  resources_inspect->>Cache: load cached benchmarks and resources
  Cache-->>resources_inspect: return inspection data
  resources_inspect->>ResourceInspectorApp: provide benchmark and resource data
  ResourceInspectorApp->>ResourceInspectorApp: group data by cloud and resource class
  ResourceInspectorApp-->>Operator: render interactive inventory
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the read-only cache inspection command, which is the primary change in the pull request.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@sebs/cache.py`:
- Around line 1004-1006: Update add_code_package and update_code_package to
validate Docker availability for container packages at method entry, before
creating cache directories or copying/deleting code. Replace the Docker-client
assert with a RuntimeError, and move cache_dir creation until after this
validation so failures cannot leave partial cache entries.

In `@sebs/cli.py`:
- Around line 927-929: Update the emptiness check in the allocated-resource loop
to also consider the `allocated_ports` field, so entries containing only ports
are retained; continue skipping entries only when resources, storage buckets,
and allocated ports are all absent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d5e5aa5c-5045-432a-95fa-71c5e9e61254

📥 Commits

Reviewing files that changed from the base of the PR and between c650942 and e242c16.

📒 Files selected for processing (3)
  • sebs/cache.py
  • sebs/cli.py
  • tests/test_cache_inspect.py

Comment thread sebs/cache.py Outdated
Comment thread sebs/cli.py Outdated
@sanskar-singh-2403

Copy link
Copy Markdown
Author

@coderabbitai help

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

CodeRabbit commands

These commands are invoked using PR/Issue comments.

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai rate limit to show your current review rate limit status.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai evaluate custom pre-merge check --instructions <custom-checks-instructions> --name <custom-checks-title> [--mode <error|warning>] to validate the custom pre-merge checks instructions. Defaults to error when --mode is omitted.
  • @coderabbitai ignore pre-merge checks to override pre-merge checks and get an approval on PR.
  • @coderabbitai run pre-merge checks to run pre-merge checks on the pull request.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai emit path instructions to emit generated path-specific review instructions for this repository.
  • @coderabbitai resolve merge conflict to automatically resolve merge conflicts.
  • @coderabbitai autofix to automatically fix issues identified in unresolved review comments.
  • @coderabbitai fix-ci to automatically fix failing CI checks by creating a stacked PR with fixes.
  • @coderabbitai resolve to resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai generate configuration to create a PR that adds the current resolved configuration as .coderabbit.yaml (or show it if already present).
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit configuration file (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, support, documentation and community

  • Visit our status page to check the current availability of CodeRabbit.
  • Create a ticket on our support page for assistance with any issues or questions.
  • Visit our documentation site for detailed information on how to use CodeRabbit.
  • Join our Discord community to connect with other users and get help from the community.
  • Follow us on X/Twitter for updates and announcements.

@sanskar-singh-2403

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
sebs/cache.py (1)

525-635: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consolidate the hardcoded cloud list into SUPPORTED_CLOUDS.

SUPPORTED_CLOUDS duplicates the ["azure", "aws", "gcp", "openwhisk", "local"] literal already used in load_config (line 267) and shutdown (line 315). Now there are three copies of the same list; a future change (adding/removing a supported cloud) risks silently missing one of them.

♻️ Proposed consolidation
     def load_config(self) -> None:
         with self._lock:
-            for cloud in ["azure", "aws", "gcp", "openwhisk", "local"]:
+            for cloud in self.SUPPORTED_CLOUDS:
                 cloud_config_file = os.path.join(self.cache_dir, "{}.json".format(cloud))
     def shutdown(self) -> None:
         if self.config_updated:
             with self._lock:
-                for cloud in ["azure", "aws", "gcp", "openwhisk", "local"]:
+                for cloud in self.SUPPORTED_CLOUDS:
                     if cloud in self.cached_config:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sebs/cache.py` around lines 525 - 635, Reuse the class-level SUPPORTED_CLOUDS
constant in load_config and shutdown instead of their duplicated hardcoded cloud
lists. Update those cloud-iteration or validation paths to reference
SUPPORTED_CLOUDS so future supported-cloud changes apply consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@sebs/cache.py`:
- Around line 525-635: Reuse the class-level SUPPORTED_CLOUDS constant in
load_config and shutdown instead of their duplicated hardcoded cloud lists.
Update those cloud-iteration or validation paths to reference SUPPORTED_CLOUDS
so future supported-cloud changes apply consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a55b6c63-32e0-4295-9b2d-a578aa8109b3

📥 Commits

Reviewing files that changed from the base of the PR and between e242c16 and 74db93e.

📒 Files selected for processing (3)
  • sebs/cache.py
  • sebs/cli.py
  • tests/test_cache_inspect.py

@sanskar-singh-2403

Copy link
Copy Markdown
Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
sebs/cache.py (2)

528-636: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Simplify redundant key-check before dict access.

Ruff (RUF019) flags the "containers" in lang_cfg and lang_cfg["containers"] / "code_package" in lang_cfg and lang_cfg["code_package"] patterns at lines 608 and 610 — dict.get(...) already returns a falsy default, so the membership check is redundant.

♻️ Suggested tweak
-                        if "containers" in lang_cfg and lang_cfg["containers"]:
+                        if lang_cfg.get("containers"):
                             packaging = "container"
-                        elif "code_package" in lang_cfg and lang_cfg["code_package"]:
+                        elif lang_cfg.get("code_package"):
                             packaging = "code_package"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sebs/cache.py` around lines 528 - 636, Update packaging detection in
get_deployed_benchmarks to use lang_cfg.get("containers") and
lang_cfg.get("code_package") directly as truthiness checks, removing the
redundant membership tests while preserving the existing container,
code_package, and unknown precedence.

Source: Linters/SAST tools


161-163: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Class-level mutable list attribute.

Ruff flags SUPPORTED_CLOUDS as a mutable default at class scope (RUF012). It's only iterated today, but annotating as ClassVar (or using a Tuple) makes the immutability intent explicit and future-proofs against accidental in-place mutation.

♻️ Suggested tweak
-    # Cloud platforms that own a per-cloud cache file (`<cloud>.json`).
-    SUPPORTED_CLOUDS: List[str] = ["azure", "aws", "gcp", "openwhisk", "local"]
+    # Cloud platforms that own a per-cloud cache file (`<cloud>.json`).
+    SUPPORTED_CLOUDS: ClassVar[Tuple[str, ...]] = ("azure", "aws", "gcp", "openwhisk", "local")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sebs/cache.py` around lines 161 - 163, Update the SUPPORTED_CLOUDS class
attribute to declare class-level ownership and prevent mutable-default linting,
using ClassVar with an immutable tuple or another immutable representation.
Preserve the existing cloud values and iteration behavior.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@sebs/cache.py`:
- Around line 528-636: Update packaging detection in get_deployed_benchmarks to
use lang_cfg.get("containers") and lang_cfg.get("code_package") directly as
truthiness checks, removing the redundant membership tests while preserving the
existing container, code_package, and unknown precedence.
- Around line 161-163: Update the SUPPORTED_CLOUDS class attribute to declare
class-level ownership and prevent mutable-default linting, using ClassVar with
an immutable tuple or another immutable representation. Preserve the existing
cloud values and iteration behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 83639dca-bfae-41e3-906d-26624b4eb8ad

📥 Commits

Reviewing files that changed from the base of the PR and between 74db93e and fb17cbc.

📒 Files selected for processing (3)
  • sebs/cache.py
  • sebs/cli.py
  • tests/test_cache_inspect.py

@sanskar-singh-2403

sanskar-singh-2403 commented Jul 29, 2026

Copy link
Copy Markdown
Author

@mcopik this pr is ready to be reviewed, let me know your thoughts, Thanks!

@mcopik

mcopik commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

@sanskar-singh-2403 Thank you for the help and contribution! It is much appreciated :)

I think this is a great first step, but it's not complete for #306. When we mention "TUI", we mean a TUI that is an interactive visualizer and displays the resources. The interface part is important because in a complex experiment, you might have many different resources allocated. Having a TUI that groups them according to cloud system and resource class will be necessary, as a regular CLI printout will be too busy.

@mcopik

mcopik commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

I tested this locally, and I think it's a good start. For a complete solution, we will have to support more resources - URLs, triggers, cloud storage buckets, tables, resource groups, etc. As you can imagine, the display will get much busier with that. I think that the Textual library should be a good help here.

image

@sanskar-singh-2403

Copy link
Copy Markdown
Author
image Screenshot 2026-08-07 115029 Screenshot 2026-08-07 115034

how does these look to you @mcopik

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@sanskar-singh-2403

Copy link
Copy Markdown
Author
tui_preview

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (10)
sebs/tui/inspect.py (2)

230-234: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the redundant container around the detail table.

Horizontal(id="detail") wraps a single DataTable. The id can move to the table, or the container can become a Vertical if a second detail widget is planned.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sebs/tui/inspect.py` around lines 230 - 234, Remove the redundant Horizontal
container with id "detail" around the single DataTable in the inspect view, and
assign the "detail" id directly to the DataTable while preserving its existing
zebra_stripes and cursor_type settings.

73-77: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider skipping clouds that have no resources.

get_allocated_resources returns an entry for every supported cloud that has a cache file, even when the resource block is empty. _clouds_in_use then adds a cloud node whose classes are all empty. The static table path filters such entries, so the two output modes disagree.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sebs/tui/inspect.py` around lines 73 - 77, Update the cloud iteration in the
inspection output flow to skip clouds whose allocated resource mapping is empty,
matching the static table behavior. Use the existing resources value from
allocated.get(cloud, {}) before creating the cloud node and its RESOURCE_CLASSES
entries, while preserving clouds that have actual resources.
tests/test_cache_inspect.py (1)

181-199: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the Docker guard.

_require_docker_client is new behavior that raises RuntimeError when a container package is cached without a Docker client. No test exercises it. A small test that calls add_code_package with a container variant on a Cache built without a client would lock in the guard and confirm that no cache directory is created.

Do you want me to generate this test?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_cache_inspect.py` around lines 181 - 199, Add a focused test
alongside test_inspection_is_read_only that creates Cache without a Docker
client, calls add_code_package with a container package variant, and asserts
RuntimeError is raised. Also verify no cache directory or persisted cache state
is created after the failed operation.
sebs/cache.py (3)

620-626: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Simplify the packaging detection.

Ruff reports RUF019 for the key check before the dictionary access. dict.get gives the same result.

♻️ Proposed change
                         functions = lang_cfg.get("functions") or {}
-                        if "containers" in lang_cfg and lang_cfg["containers"]:
+                        if lang_cfg.get("containers"):
                             packaging = "container"
-                        elif "code_package" in lang_cfg and lang_cfg["code_package"]:
+                        elif lang_cfg.get("code_package"):
                             packaging = "code_package"
                         else:
                             packaging = "unknown"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sebs/cache.py` around lines 620 - 626, Update the packaging detection logic
near the functions assignment to use dictionary get-based truthiness checks for
both "containers" and "code_package", removing the redundant key-existence
checks while preserving the existing packaging values and precedence.

Source: Linters/SAST tools


162-163: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Annotate SUPPORTED_CLOUDS as a class-level constant.

Ruff reports RUF012 for the mutable class attribute. Use ClassVar (and optionally a tuple) so the shared list cannot be reassigned or mutated per instance.

♻️ Proposed change
-    SUPPORTED_CLOUDS: List[str] = ["azure", "aws", "gcp", "openwhisk", "local"]
+    SUPPORTED_CLOUDS: ClassVar[List[str]] = ["azure", "aws", "gcp", "openwhisk", "local"]

Add ClassVar to the typing import.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sebs/cache.py` around lines 162 - 163, Update the cache class’s
SUPPORTED_CLOUDS declaration to use a ClassVar annotation, adding ClassVar to
the typing imports; preferably use an immutable tuple so the shared cloud list
cannot be mutated or reassigned per instance.

Source: Linters/SAST tools


611-618: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Consider a positive language test instead of a deny list.

The loop treats every dict-valued key except storage and nosql as a language. If a new non-language key is added under a deployment, the inspector reports it as a benchmark row with packaging unknown. A positive check, for example requiring one of functions, code_package, or containers, keeps the view correct as the cache schema grows.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sebs/cache.py` around lines 611 - 618, Update the language filtering in the
dep_cfg iteration to accept only dictionary entries containing at least one
recognized language marker: functions, code_package, or containers. Remove the
deny-list reliance on storage and nosql while preserving the existing handling
for non-dictionary entries, so new deployment-level keys are not emitted as
language benchmark rows.
tests/test_tui_inspect.py (1)

94-94: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Replace the single-element slices with next(...).

Ruff reports RUF015 at three places in this file. next(...) states the intent and avoids building an intermediate list.

♻️ Proposed change
-        http = [t for t in triggers if t["type"] == "http"][0]
+        http = next(t for t in triggers if t["type"] == "http")
@@
-            aws_node = [n for n in tree.root.children if str(n.label) == "aws"][0]
-            bench_node = [
-                n for n in aws_node.children if str(n.label).startswith("Benchmarks")
-            ][0]
+            aws_node = next(n for n in tree.root.children if str(n.label) == "aws")
+            bench_node = next(
+                n for n in aws_node.children if str(n.label).startswith("Benchmarks")
+            )

Also applies to: 125-128

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_tui_inspect.py` at line 94, Replace the three single-element list
comprehensions indexed with [0] in tests/test_tui_inspect.py, including the
assignment around the http trigger and the occurrences near lines 125–128, with
next(...) over the corresponding iterables. Preserve each existing filter
predicate and selected element while avoiding intermediate list construction.

Source: Linters/SAST tools

pyproject.toml (1)

42-42: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Keep the Textual dependency declaration consistent across both manifests. Both files declare textual>=0.50.0 as a required dependency, but sebs/cli.py imports sebs.tui lazily, which shows the TUI is optional. Whatever you decide about an optional extra and an upper version bound must be applied in both places, or the two manifests drift.

  • pyproject.toml#L42-L42: move textual>=0.50.0 into an optional extra such as tui, or keep it required and add an upper bound.
  • requirements.txt#L23-L23: apply the same decision so that the pip requirements file matches the project metadata.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pyproject.toml` at line 42, Make the Textual dependency policy consistent in
pyproject.toml at lines 42-42 and requirements.txt at lines 23-23: either move
textual>=0.50.0 into the same optional tui extra in both manifests, or keep it
required with the same upper version bound in both. Ensure sebs/cli.py’s lazy
sebs.tui import remains compatible with the chosen declaration.
sebs/cli.py (2)

897-901: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Fall back to the table output when stdout is not a terminal.

The default mode is tui. If a user pipes the command or runs it in CI, an interactive Textual app is not usable. The docstring already states that only table and json are safe for non-TTY environments. Detect the terminal and downgrade automatically.

♻️ Proposed change
-    if output_format == "tui":
+    if output_format == "tui" and not sys.stdout.isatty():
+        output_format = "table"
+
+    if output_format == "tui":
         from sebs.tui import run_inspector
 
         run_inspector(benchmarks, allocated)
         return

Import sys at the top of the module if it is not already imported.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sebs/cli.py` around lines 897 - 901, Update the output-format handling around
the `run_inspector` call to detect whether `sys.stdout` is a TTY; when
`output_format` is `tui` but stdout is not a terminal, switch to the documented
safe `table` output instead of launching the interactive inspector. Import `sys`
at module scope if needed, while preserving TUI behavior for terminal output and
existing JSON handling.

855-860: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Derive the platform choices from Cache.SUPPORTED_CLOUDS.

The literal list repeats the constant added in sebs/cache.py. If a platform is added there, this list silently drifts and the filter rejects a valid platform.

♻️ Proposed change
-    type=click.Choice(["azure", "aws", "gcp", "local", "openwhisk"]),
+    type=click.Choice(sorted(Cache.SUPPORTED_CLOUDS)),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sebs/cli.py` around lines 855 - 860, Update the deployment click option to
derive its Choice values from Cache.SUPPORTED_CLOUDS instead of maintaining the
duplicated literal list, while preserving the existing default and help text.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@sebs/cli.py`:
- Around line 849-854: Update the --cache click.option in the cache inspection
command to remove exists=True while retaining the directory-only and readable
constraints. Ensure a missing cache path reaches the existing empty-cache
handling, avoiding unnecessary directory creation for this read-only command if
Cache initialization would create it.
- Around line 933-956: Align the --output table behavior with the command’s
documented fields by either adding columns and row values for NoSQL tables and
resource groups in the res_table construction and allocated iteration, or
narrowing the command docstring to remove those fields; keep the documentation
and rendered output consistent.

---

Nitpick comments:
In `@pyproject.toml`:
- Line 42: Make the Textual dependency policy consistent in pyproject.toml at
lines 42-42 and requirements.txt at lines 23-23: either move textual>=0.50.0
into the same optional tui extra in both manifests, or keep it required with the
same upper version bound in both. Ensure sebs/cli.py’s lazy sebs.tui import
remains compatible with the chosen declaration.

In `@sebs/cache.py`:
- Around line 620-626: Update the packaging detection logic near the functions
assignment to use dictionary get-based truthiness checks for both "containers"
and "code_package", removing the redundant key-existence checks while preserving
the existing packaging values and precedence.
- Around line 162-163: Update the cache class’s SUPPORTED_CLOUDS declaration to
use a ClassVar annotation, adding ClassVar to the typing imports; preferably use
an immutable tuple so the shared cloud list cannot be mutated or reassigned per
instance.
- Around line 611-618: Update the language filtering in the dep_cfg iteration to
accept only dictionary entries containing at least one recognized language
marker: functions, code_package, or containers. Remove the deny-list reliance on
storage and nosql while preserving the existing handling for non-dictionary
entries, so new deployment-level keys are not emitted as language benchmark
rows.

In `@sebs/cli.py`:
- Around line 897-901: Update the output-format handling around the
`run_inspector` call to detect whether `sys.stdout` is a TTY; when
`output_format` is `tui` but stdout is not a terminal, switch to the documented
safe `table` output instead of launching the interactive inspector. Import `sys`
at module scope if needed, while preserving TUI behavior for terminal output and
existing JSON handling.
- Around line 855-860: Update the deployment click option to derive its Choice
values from Cache.SUPPORTED_CLOUDS instead of maintaining the duplicated literal
list, while preserving the existing default and help text.

In `@sebs/tui/inspect.py`:
- Around line 230-234: Remove the redundant Horizontal container with id
"detail" around the single DataTable in the inspect view, and assign the
"detail" id directly to the DataTable while preserving its existing
zebra_stripes and cursor_type settings.
- Around line 73-77: Update the cloud iteration in the inspection output flow to
skip clouds whose allocated resource mapping is empty, matching the static table
behavior. Use the existing resources value from allocated.get(cloud, {}) before
creating the cloud node and its RESOURCE_CLASSES entries, while preserving
clouds that have actual resources.

In `@tests/test_cache_inspect.py`:
- Around line 181-199: Add a focused test alongside test_inspection_is_read_only
that creates Cache without a Docker client, calls add_code_package with a
container package variant, and asserts RuntimeError is raised. Also verify no
cache directory or persisted cache state is created after the failed operation.

In `@tests/test_tui_inspect.py`:
- Line 94: Replace the three single-element list comprehensions indexed with [0]
in tests/test_tui_inspect.py, including the assignment around the http trigger
and the occurrences near lines 125–128, with next(...) over the corresponding
iterables. Preserve each existing filter predicate and selected element while
avoiding intermediate list construction.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5e81853f-5e2d-4887-9c04-35b4ebed7ff1

📥 Commits

Reviewing files that changed from the base of the PR and between 075fb2a and 76c661f.

📒 Files selected for processing (8)
  • pyproject.toml
  • requirements.txt
  • sebs/cache.py
  • sebs/cli.py
  • sebs/tui/__init__.py
  • sebs/tui/inspect.py
  • tests/test_cache_inspect.py
  • tests/test_tui_inspect.py

Comment thread sebs/cli.py
Comment thread sebs/cli.py Outdated
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@sebs/cli.py`:
- Around line 949-970: Update the static resource table row construction around
the allocated resource loop to count NoSQL tables from the matching benchmarks
rows’ row["nosql"] cached table names, rather than len(res.get("nosql") or {}),
while preserving the existing zero/default display behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7561dde6-c1e3-4bb5-882f-70ff89f9b176

📥 Commits

Reviewing files that changed from the base of the PR and between 075fb2a and 80be8ea.

📒 Files selected for processing (8)
  • pyproject.toml
  • requirements.txt
  • sebs/cache.py
  • sebs/cli.py
  • sebs/tui/__init__.py
  • sebs/tui/inspect.py
  • tests/test_cache_inspect.py
  • tests/test_tui_inspect.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • pyproject.toml
  • requirements.txt
  • sebs/tui/init.py

Comment thread sebs/cli.py Outdated
@mcopik

mcopik commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

@sanskar-singh-2403 Thanks for the update, looks much better. I guess we can then kill the tabular version in the CLI :)

Add `sebs resources inspect` to visualize the on-disk cache without
contacting any cloud provider or requiring a Docker daemon.

- Extend sebs.cache.Cache with two read-only helpers:
  - get_deployed_benchmarks(): flattens per-benchmark config.json files
    into rows of (benchmark, platform, language, packaging, functions,
    triggers, storage, nosql).
  - get_allocated_resources(): reads the per-cloud files (aws.json,
    local.json, ...) for resources_id, region, storage buckets, and
    locally allocated ports.
- Make Cache docker_client optional so read-only consumers can open a
  cache without a running Docker daemon; guard the container-caching
  paths with an assertion.
- Add the `resources inspect` CLI command with a rich table view and a
  --json output mode, plus an optional --deployment platform filter.
- Add offline unit tests that build a synthetic cache directory.

Addresses spcl#306.
@sanskar-singh-2403

Copy link
Copy Markdown
Author

@sanskar-singh-2403 Thanks for the update, looks much better. I guess we can then kill the tabular version in the CLI :)

done

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