Skip to content

Update version to 0.0.7b10 and enhance secret retrieval logic in Runtime class#277

Merged
NiveditJain merged 3 commits intoexospherehost:mainfrom
NiveditJain:improved-secret-check
Aug 24, 2025
Merged

Update version to 0.0.7b10 and enhance secret retrieval logic in Runtime class#277
NiveditJain merged 3 commits intoexospherehost:mainfrom
NiveditJain:improved-secret-check

Conversation

@NiveditJain
Copy link
Member

  • Bumped version from 0.0.7b9 to 0.0.7b10 in _version.py.
  • Modified _get_secrets method to return secrets directly if present, with error logging for missing secrets.
  • Introduced _need_secrets method to check if a node requires secrets before attempting to retrieve them.
  • Updated _worker method to conditionally fetch secrets based on node requirements.

…ime class

- Bumped version from 0.0.7b9 to 0.0.7b10 in _version.py.
- Modified _get_secrets method to return secrets directly if present, with error logging for missing secrets.
- Introduced _need_secrets method to check if a node requires secrets before attempting to retrieve them.
- Updated _worker method to conditionally fetch secrets based on node requirements.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 24, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved secrets handling for nodes: fetches only when required and uses the correct structure, reducing errors and noisy logs.
  • Refactor
    • Streamlined runtime flow to avoid unnecessary secrets retrieval for nodes that don’t need it, improving efficiency.
  • Tests
    • Added comprehensive unit tests for BaseNode and Runtime edge cases, including validation, logging, error paths, and event loop behavior.
  • Chores
    • Bumped SDK version to 0.0.7b10.

Walkthrough

Bumps SDK version to 0.0.7b10 and changes Runtime secret handling: _get_secrets now returns the flattened secrets dict (or {} on error), Runtime._need_secrets skips fetching for nodes without secret fields, and nodes are instantiated with node.Secrets(**secrets).

Changes

Cohort / File(s) Summary of Changes
Version bump
python-sdk/exospherehost/_version.py
Incremented version from "0.0.7b9" to "0.0.7b10".
Runtime secrets & control flow
python-sdk/exospherehost/runtime.py
Added Runtime._need_secrets(node); _get_secrets returns the flattened secrets dict (or {} on error); _worker only fetches secrets when _need_secrets is true and now calls node.Secrets(**secrets).
Tests — updated mocks
python-sdk/tests/test_runtime_comprehensive.py
Adjusted mocked return shape and assertions to expect top-level secret keys (e.g., {"api_key": "..."}) instead of nested {"secrets": {...}}.
Tests — new modules
python-sdk/tests/test_base_node_abstract.py, python-sdk/tests/test_runtime_edge_cases.py, python-sdk/tests/test_runtime_validation.py
Added comprehensive unit tests: BaseNode abstract behavior, many Runtime edge cases (secret/no-secret nodes, validation, enqueue/start behavior), and updated duplicate-name test handling and warnings suppression. Multiple mock node classes added for test coverage.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant W as Runtime._worker
  participant N as Node (class)
  participant S as Secrets service / _get_secrets

  W->>N: Inspect N.Secrets.model_fields
  alt N requires secrets
    W->>S: call _get_secrets()
    S-->>W: {"api_key": "..."} or error
    note right of W #DFF2E1: use returned dict (or {})\n(no nested "secrets" key)
  else N does not require secrets
    note right of W #F5F5DC: skip _get_secrets(), secrets = {}
  end

  W->>N: Instantiate N.Secrets(**secrets)
  W->>N: Execute node with inputs
  N-->>W: Outputs / exception
  W-->>W: notify / cleanup
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

A rabbit nudges code with careful paws,
Fetches secrets only where there's cause.
Version hops up to b10, nice and neat,
Keys now tidy — no nested seat.
Carrots, tests, and quieter queues — hop, repeat! 🐰✨


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 36ca1ed and 76e1f2d.

📒 Files selected for processing (3)
  • python-sdk/tests/test_base_node_abstract.py (1 hunks)
  • python-sdk/tests/test_runtime_edge_cases.py (1 hunks)
  • python-sdk/tests/test_runtime_validation.py (3 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai 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.
  • 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, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @NiveditJain, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on refining the secret management within the Runtime class of the Python SDK and updating the project version. The core changes involve making secret retrieval more robust by adding explicit checks and improving efficiency by fetching secrets only when a node explicitly requires them. This leads to a more stable and performant handling of sensitive data within the application's runtime.

Highlights

  • Version Update: The project's version has been incremented from 0.0.7b9 to 0.0.7b10.
  • Enhanced Secret Retrieval Logic: The _get_secrets method now includes enhanced error handling by explicitly checking for the 'secrets' key in the response and logging an error if it's not found, ensuring more robust secret retrieval.
  • Conditional Secret Fetching: A new _need_secrets method has been added to efficiently determine if a node requires secrets, preventing unnecessary secret fetching operations.
  • Optimized Secret Usage in Worker: The _worker method has been updated to leverage the new _need_secrets method, ensuring that secrets are only retrieved and passed to a node's _execute method when genuinely required, optimizing performance.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly enhances the secret retrieval logic by only fetching secrets when needed and by parsing the response correctly. The introduction of _need_secrets is a good optimization.

However, the changes to _get_secrets alter its return contract, which will cause existing unit tests to fail. I've left a specific comment on this. It's crucial to update the tests to reflect these changes to ensure the codebase remains stable and verifiable.

I've also included a minor suggestion to improve the implementation of _need_secrets for better readability and conciseness.

@codecov
Copy link

codecov bot commented Aug 24, 2025

Codecov Report

❌ Patch coverage is 83.33333% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
python-sdk/exospherehost/runtime.py 81.81% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Contributor

@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: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1d998e1 and 806b7b3.

📒 Files selected for processing (2)
  • python-sdk/exospherehost/_version.py (1 hunks)
  • python-sdk/exospherehost/runtime.py (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
python-sdk/exospherehost/runtime.py (1)
python-sdk/exospherehost/node/BaseNode.py (4)
  • BaseNode (6-100)
  • Secrets (45-68)
  • _execute (70-83)
  • Inputs (29-35)
🪛 GitHub Actions: Python SDK Tests
python-sdk/exospherehost/runtime.py

[error] 387-387: During pytest run (test_worker_successful_execution): Pydantic ValidationError: api_key field required for Secrets when constructing Secrets(**secrets) (input: {'secrets': {'api_key': 'test_key'}}).


[error] 387-387: During pytest run (test_worker_with_list_output): Pydantic ValidationError: api_key field required for Secrets when constructing Secrets(**secrets) (input: {'secrets': {'api_key': 'test_key'}}).


[error] 387-387: During pytest run (test_worker_with_none_output): Pydantic ValidationError: api_key field required for Secrets when constructing Secrets(**secrets) (input: {'secrets': {'api_key': 'test_key'}}).


[error] 387-387: During pytest run (test_worker_execution_error): Pydantic ValidationError: api_key field required for Secrets when constructing Secrets(**secrets) (input: {'secrets': {'api_key': 'test_key'}}).

🔇 Additional comments (2)
python-sdk/exospherehost/_version.py (1)

1-1: Version bump to 0.0.7b10 looks good.

No issues spotted in this change.

python-sdk/exospherehost/runtime.py (1)

382-387: Normalize nested secrets for backward-compatibility in worker

This change unwraps any {"secrets": {…}} envelope returned by _get_secrets before passing into the node’s Pydantic Secrets model. It resolves the ValidationError in worker tests without altering the existing _get_secrets contract, so all current tests (worker, integration, base-node) continue to pass.

Apply this diff in python-sdk/exospherehost/runtime.py around the worker loop:

--- a/python-sdk/exospherehost/runtime.py
+++ b/python-sdk/exospherehost/runtime.py
@@ -379,9 +379,16 @@ class Runtime:
-                secrets = {}
-                if self._need_secrets(node):
-                    secrets = await self._get_secrets(state["state_id"])
-                    logger.info(f"Got secrets for state {state['state_id']} for node {node.__name__}")
+                secrets = {}
+                if self._need_secrets(node):
+                    secrets = await self._get_secrets(state["state_id"])
+                    # Backward-compat: unwrap {"secrets": {...}} envelopes
+                    if (
+                        isinstance(secrets, dict)
+                        and "secrets" in secrets
+                        and isinstance(secrets["secrets"], dict)
+                    ):
+                        secrets = secrets["secrets"]
+                    logger.info(f"Got secrets for state {state['state_id']} for node {node.__name__}")
@@ -386,7 +393,7 @@ class Runtime:
-                outputs = await node()._execute(node.Inputs(**state["inputs"]), node.Secrets(**secrets))
+                outputs = await node()._execute(
+                    node.Inputs(**state["inputs"]),
+                    node.Secrets(**secrets),
+                )
  • Re-run the full Python SDK test suite to confirm no regressions.
  • (Optional) Add a unit test in the runtime worker suite that verifies node._execute is called with a flat secrets dict, ensuring the flattened contract is enforced going forward.

Copy link
Contributor

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
python-sdk/tests/test_runtime_comprehensive.py (3)

500-531: Add coverage for 200 response with missing 'secrets' key and error logging

PR description says _get_secrets logs an error when "secrets" is missing and returns {}. Add a test to assert both the empty dict and the logged error.

Example test to add:

@pytest.mark.asyncio
async def test_get_secrets_missing_key_logs_error_and_returns_empty(self, runtime_config, caplog):
    with patch('exospherehost.runtime.ClientSession') as mock_session_class:
        mock_session, mock_post_response, mock_get_response, mock_put_response = create_mock_aiohttp_session()
        mock_get_response.status = 200
        mock_get_response.json = AsyncMock(return_value={"not_secrets": {}})
        mock_session_class.return_value = mock_session

        runtime = Runtime(**runtime_config)
        with caplog.at_level(logging.ERROR):
            result = await runtime._get_secrets("test_state_1")

        assert result == {}
        assert any("secret" in r.message.lower() and "missing" in r.message.lower() for r in caplog.records)

535-543: Patch async lifecycle methods in start() tests using AsyncMock

_register, _enqueue, and _worker are async; patch them as AsyncMock to avoid failures hidden by task cancellation.

-        with patch('exospherehost.runtime.Runtime._register') as mock_register, \
-             patch('exospherehost.runtime.Runtime._enqueue') as mock_enqueue, \
-             patch('exospherehost.runtime.Runtime._worker') as mock_worker:
+        with patch('exospherehost.runtime.Runtime._register', new_callable=AsyncMock) as mock_register, \
+             patch('exospherehost.runtime.Runtime._enqueue', new_callable=AsyncMock) as mock_enqueue, \
+             patch('exospherehost.runtime.Runtime._worker', new_callable=AsyncMock) as mock_worker:

Optional stability tweak: instead of sleeping and cancelling, assert the task didn't raise by inspecting task.exception() before cancellation, or restructure _worker behind a one-iteration helper when unit testing.


279-323: Consider adding a no-secrets node test to exercise _need_secrets == False path

Given the new _need_secrets short-circuit, add a node without a Secrets model and assert _get_secrets is not called and execution still succeeds.

If you want, I can draft a minimal MockTestNodeNoSecrets and a test method asserting mock_get_secrets.assert_not_called().

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 806b7b3 and 36ca1ed.

📒 Files selected for processing (1)
  • python-sdk/tests/test_runtime_comprehensive.py (5 hunks)
🔇 Additional comments (1)
python-sdk/tests/test_runtime_comprehensive.py (1)

514-514: LGTM: assertion updated for flattened secrets shape

The assertion now matches the new _get_secrets contract returning the inner dict. Good alignment with the Runtime change.

- Added two classes with the same name using different approaches to test for duplicate node names.
- Suppressed RuntimeWarning for unawaited coroutines during the test execution.
- Updated the test to ensure it raises a ValueError when duplicate node names are used.
@NiveditJain NiveditJain merged commit 8d77f6d into exospherehost:main Aug 24, 2025
3 of 5 checks passed
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.

1 participant