Update version to 0.0.7b10 and enhance secret retrieval logic in Runtime class#277
Conversation
NiveditJain
commented
Aug 24, 2025
- 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.
|
Note Other AI code review bot(s) detectedCodeRabbit 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 failedThe pull request is closed. 📝 WalkthroughSummary by CodeRabbit
WalkthroughBumps 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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: ASSERTIVE Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (3)
✨ Finishing Touches
🧪 Generate 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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
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.7b9to0.0.7b10. - Enhanced Secret Retrieval Logic: The
_get_secretsmethod 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_secretsmethod has been added to efficiently determine if a node requires secrets, preventing unnecessary secret fetching operations. - Optimized Secret Usage in Worker: The
_workermethod has been updated to leverage the new_need_secretsmethod, ensuring that secrets are only retrieved and passed to a node's_executemethod 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
-
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. ↩
There was a problem hiding this comment.
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 Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
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.
📒 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 workerThis change unwraps any
{"secrets": {…}}envelope returned by_get_secretsbefore passing into the node’s PydanticSecretsmodel. It resolves the ValidationError in worker tests without altering the existing_get_secretscontract, so all current tests (worker, integration, base-node) continue to pass.Apply this diff in
python-sdk/exospherehost/runtime.pyaround 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._executeis called with a flat secrets dict, ensuring the flattened contract is enforced going forward.
There was a problem hiding this comment.
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 loggingPR description says
_get_secretslogs 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_workerare async; patch them asAsyncMockto 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_workerbehind a one-iteration helper when unit testing.
279-323: Consider adding a no-secrets node test to exercise _need_secrets == False pathGiven the new
_need_secretsshort-circuit, add a node without aSecretsmodel and assert_get_secretsis not called and execution still succeeds.If you want, I can draft a minimal
MockTestNodeNoSecretsand a test method assertingmock_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.
📒 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 shapeThe assertion now matches the new
_get_secretscontract 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.