Skip to content

Conversation

@NiveditJain
Copy link
Member

  • Introduced the StateManager class for managing workflow states and triggering graph executions.
  • Added the TriggerState class to represent trigger states with identifiers and input parameters.
  • Updated the README.md to include documentation for the new classes and their usage.
  • Created a new example script in temp.py demonstrating the usage of StateManager and TriggerState.
  • Bumped version to 0.0.7b6 to reflect the new features.

- Introduced the `StateManager` class for managing workflow states and triggering graph executions.
- Added the `TriggerState` class to represent trigger states with identifiers and input parameters.
- Updated the README.md to include documentation for the new classes and their usage.
- Created a new example script in `temp.py` demonstrating the usage of `StateManager` and `TriggerState`.
- Bumped version to 0.0.7b6 to reflect the new features.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 17, 2025

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added State Management API to the Python SDK for programmatic graph execution, including single and batch triggers, configurable via parameters or environment variables, with input validation and clear error handling.
    • Exposed StateManager and TriggerState at the top-level package for easier importing.
  • Documentation
    • Expanded README with a State Management section and usage examples.
  • Chores
    • Bumped SDK version to 0.0.7b6.

Walkthrough

Introduces a new StateManager client and TriggerState model for programmatic graph execution, integrates them into the exospherehost public API, documents usage in README (with a duplicated section), and bumps the package version to 0.0.7b6.

Changes

Cohort / File(s) Summary of changes
State management client
python-sdk/exospherehost/statemanager.py
Added TriggerState (Pydantic model) and StateManager with endpoint construction and async POST-based trigger() supporting single or multiple states, input validation, and error handling.
Public API exports
python-sdk/exospherehost/__init__.py
Re-exported StateManager and TriggerState; updated __all__ to include them.
Documentation
python-sdk/README.md
Added “State Management” section detailing StateManager/TriggerState usage, config, parameters, return types, and errors; section appears twice.
Version bump
python-sdk/exospherehost/_version.py
Updated version from 0.0.7b5 to 0.0.7b6.

Sequence Diagram(s)

sequenceDiagram
  actor Developer
  participant SDK as StateManager (SDK)
  participant HTTP as aiohttp Client
  participant Svc as State Manager Service

  Developer->>SDK: trigger(graph_name, state|states)
  SDK->>SDK: Validate inputs / build payload
  SDK->>HTTP: POST {uri/version/namespace/graph/graph_name/trigger}\nHeaders: x-api-key
  HTTP->>Svc: HTTP POST /trigger
  Svc-->>HTTP: 200 JSON or error
  HTTP-->>SDK: Response
  alt 200 OK
    SDK-->>Developer: Return response JSON (dict)
  else Non-200
    SDK-->>Developer: Raise Exception(status, text)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

I thump my paws on bursting dawn,
A graph to nudge, then hop along—
With keys in paw, I call the stream,
States in a bundle, swift and clean.
The wires hum, the futures sing—
0.0.7b6: a springtime fling. 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ 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 significantly enhances the Python SDK by introducing robust state management capabilities. It adds StateManager and TriggerState classes, enabling programmatic control over workflow states and the ability to trigger graph executions with specific input parameters. The changes include new core logic, updated documentation, and a version bump, providing developers with powerful tools for integrating and orchestrating ExosphereHost workflows within their applications.

Highlights

  • New Core Classes for State Management: Two new classes, StateManager and TriggerState, have been introduced to the Python SDK. StateManager facilitates programmatic triggering of graph executions and managing workflow states, while TriggerState encapsulates the identifier and input parameters for these triggers.
  • Asynchronous Graph Triggering: The StateManager class provides an async trigger method, allowing users to initiate graph executions by sending either a single TriggerState object or a list of them. This enables flexible integration with existing applications and custom orchestration logic.
  • Updated Documentation: The README.md has been significantly updated to include comprehensive documentation for the new StateManager and TriggerState classes. This includes detailed explanations of their initialization, parameters, and usage examples, ensuring developers can easily adopt these new features.
  • Version Bump: The SDK's version has been incremented to 0.0.7b6 to reflect the addition of these new state management capabilities.
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 introduces StateManager and TriggerState classes to the Python SDK, enabling programmatic triggering of graph executions. The changes are well-documented in the README. My review focuses on improving the robustness and conciseness of the new StateManager class. I've suggested adding configuration validation to prevent runtime errors, refactoring for more idiomatic Python, and using custom exceptions for better error handling. I also pointed out a minor style issue.

Comment on lines +48 to +55
def _set_config_from_env(self):
"""
Set configuration from environment variables if not provided.
"""
if self._state_manager_uri is None:
self._state_manager_uri = os.environ.get("EXOSPHERE_STATE_MANAGER_URI")
if self._key is None:
self._key = os.environ.get("EXOSPHERE_API_KEY")
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The configuration values _state_manager_uri and _key are fetched from environment variables if not provided, but there's no check to ensure they are actually set. This can lead to runtime errors later when API calls are made. It's crucial to validate that these have values after attempting to load from the environment, similar to how it's done in the Runtime class.

Suggested change
def _set_config_from_env(self):
"""
Set configuration from environment variables if not provided.
"""
if self._state_manager_uri is None:
self._state_manager_uri = os.environ.get("EXOSPHERE_STATE_MANAGER_URI")
if self._key is None:
self._key = os.environ.get("EXOSPHERE_API_KEY")
def _set_config_from_env(self):
"""
Set configuration from environment variables if not provided.
"""
if self._state_manager_uri is None:
self._state_manager_uri = os.environ.get("EXOSPHERE_STATE_MANAGER_URI")
if self._key is None:
self._key = os.environ.get("EXOSPHERE_API_KEY")
if self._state_manager_uri is None:
raise ValueError("State manager URI is not set. Provide it as an argument or set the EXOSPHERE_STATE_MANAGER_URI environment variable.")
if self._key is None:
raise ValueError("API key is not set. Provide it as an argument or set the EXOSPHERE_API_KEY environment variable.")

Comment on lines +106 to +110
states_list = []
if state is not None:
states_list.append(state)
if states is not None:
states_list.extend(states)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The logic for constructing states_list is correct but can be expressed more concisely using a conditional expression. This improves readability.

Suggested change
states_list = []
if state is not None:
states_list.append(state)
if states is not None:
states_list.extend(states)
states_list = [state] if state is not None else states

}
endpoint = self._get_trigger_state_endpoint(graph_name)
async with aiohttp.ClientSession() as session:
async with session.post(endpoint, json=body, headers=headers) as response: # type: ignore
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The # type: ignore comment suppresses a potential type error. The validation I suggested for _state_manager_uri and _key should ensure they are not None, which will likely resolve the underlying type issue for the endpoint and headers parameters. Once the validation is in place, please check if this type: ignore can be removed.

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: 10

📜 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 1002eea and 11edd0f.

📒 Files selected for processing (4)
  • python-sdk/README.md (1 hunks)
  • python-sdk/exospherehost/__init__.py (1 hunks)
  • python-sdk/exospherehost/_version.py (1 hunks)
  • python-sdk/exospherehost/statemanager.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
python-sdk/exospherehost/statemanager.py (5)
state-manager/app/models/create_models.py (4)
  • TriggerGraphResponseModel (36-39)
  • TriggerGraphRequestModel (32-33)
  • ResponseStateModel (12-19)
  • RequestStateModel (7-9)
state-manager/app/controller/create_states.py (1)
  • trigger_graph (24-48)
state-manager/tests/unit/controller/test_trigger_graph.py (2)
  • test_trigger_graph_success (28-80)
  • test_trigger_graph_create_states_error (84-99)
state-manager/app/models/db/state.py (1)
  • State (8-18)
state-manager/app/routes.py (1)
  • trigger_graph_route (72-82)
python-sdk/exospherehost/__init__.py (1)
python-sdk/exospherehost/statemanager.py (2)
  • StateManager (38-123)
  • TriggerState (6-35)
python-sdk/README.md (4)
state-manager/app/controller/create_states.py (1)
  • trigger_graph (24-48)
state-manager/app/models/create_models.py (2)
  • TriggerGraphResponseModel (36-39)
  • TriggerGraphRequestModel (32-33)
state-manager/tests/unit/controller/test_trigger_graph.py (1)
  • test_trigger_graph_success (28-80)
state-manager/app/models/db/state.py (1)
  • State (8-18)
🪛 Gitleaks (8.27.2)
python-sdk/exospherehost/statemanager.py

28-28: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

python-sdk/README.md

239-239: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 LanguageTool
python-sdk/README.md

[grammar] ~198-~198: Use correct spacing
Context: ...andle them manually ## State Management The SDK provides a StateManager class ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~200-~200: Use correct spacing
Context: ...for building custom orchestration logic. ### StateManager Class The StateManager c...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~202-~202: Use correct spacing
Context: ...estration logic. ### StateManager Class The StateManager class allows you to t...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~204-~204: Use correct spacing
Context: ...the ExosphereHost state manager service. #### Initialization ```python from exosphere...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~206-~206: Use correct spacing
Context: ...te manager service. #### Initialization python from exospherehost import StateManager # Initialize with explicit configuration state_manager = StateManager( namespace="MyProject", state_manager_uri="https://your-state-manager.exosphere.host", key="your-api-key", state_manager_version="v0" ) # Or initialize with environment variables state_manager = StateManager(namespace="MyProject") Parameters: - namespace (str): The n...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~223-~223: Use correct spacing
Context: ...amespace="MyProject") ``` Parameters: - namespace (str): The namespace for your project - ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~224-~224: Use correct spacing
Context: ...e(str): The namespace for your project -state_manager_uri` (str, optional): The URI of the state ma...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~225-~225: Use articles correctly
Context: ...manager service. If not provided, reads from EXOSPHERE_STATE_MANAGER_URI environme...

(QB_NEW_EN_OTHER_ERROR_IDS_11)


[grammar] ~225-~225: There might be a mistake here.
Context: ..._STATE_MANAGER_URIenvironment variable -key` (str, optional): Your API key. If not pr...

(QB_NEW_EN_OTHER)


[grammar] ~226-~226: Use articles correctly
Context: ...): Your API key. If not provided, reads from EXOSPHERE_API_KEY environment variabl...

(QB_NEW_EN_OTHER_ERROR_IDS_11)


[grammar] ~226-~226: There might be a mistake here.
Context: ...EXOSPHERE_API_KEY environment variable - state_manager_version (str): The API version to use (default: ...

(QB_NEW_EN_OTHER)


[grammar] ~227-~227: Use correct spacing
Context: ...: The API version to use (default: "v0") #### Triggering Graph Execution ```python fr...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~229-~229: Use correct spacing
Context: ...: "v0") #### Triggering Graph Execution python from exospherehost import StateManager, TriggerState # Create a single trigger state trigger_state = TriggerState( identifier="user-login", inputs={ "user_id": "12345", "session_token": "abc123def456", "timestamp": "2024-01-15T10:30:00Z" } ) # Trigger a single state result = await state_manager.trigger("my-graph", state=trigger_state) # Or trigger multiple states trigger_states = [ TriggerState(identifier="trigger1", inputs={"key1": "value1"}), TriggerState(identifier="trigger2", inputs={"key2": "value2"}) ] result = await state_manager.trigger("my-graph", states=trigger_states) Parameters: - graph_name (str): The ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~256-~256: Use correct spacing
Context: ...tates=trigger_states) ``` Parameters: - graph_name (str): The name of the graph to trigger ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~257-~257: Use correct spacing
Context: ... (str): The name of the graph to trigger - state (TriggerState, optional): A single trigg...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~258-~258: Use correct spacing
Context: ...State, optional): A single trigger state - states (list[TriggerState], optional): A list o...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~259-~259: Use correct spacing
Context: ...te], optional): A list of trigger states Returns: - dict: The JSON response f...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~261-~261: There might be a mistake here.
Context: ...l): A list of trigger states Returns: - dict: The JSON response from the state manag...

(QB_NEW_EN)


[grammar] ~262-~262: Use correct spacing
Context: ...JSON response from the state manager API Raises: - ValueError: If neither `st...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~264-~264: There might be a mistake here.
Context: ...se from the state manager API Raises: - ValueError: If neither state nor states is pro...

(QB_NEW_EN)


[grammar] ~265-~265: There might be a mistake here.
Context: ...rovided, or if states is an empty list - Exception: If the API request fails with a non-20...

(QB_NEW_EN)


[grammar] ~266-~266: Use correct spacing
Context: ...request fails with a non-200 status code ### TriggerState Class The TriggerState c...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~268-~268: Use correct spacing
Context: ...-200 status code ### TriggerState Class The TriggerState class represents a tr...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~270-~270: Use correct spacing
Context: ...assed to the graph when it is triggered. #### Creating Trigger States ```python from ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~272-~272: Use correct spacing
Context: ...triggered. #### Creating Trigger States python from exospherehost import TriggerState # Basic trigger state trigger_state = TriggerState( identifier="data-processing", inputs={ "file_path": "/path/to/data.csv", "batch_size": "1000", "priority": "high" } ) # Trigger state with complex data (serialized as JSON) import json complex_data = { "filters": ["active", "verified"], "date_range": {"start": "2024-01-01", "end": "2024-01-31"}, "options": {"include_metadata": True, "format": "json"} } trigger_state = TriggerState( identifier="complex-processing", inputs={ "config": json.dumps(complex_data), "user_id": "12345" } ) Attributes: - identifier (str): A un...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~305-~305: Use correct spacing
Context: ..._id": "12345" } ) ``` Attributes: - identifier (str): A unique identifier for this trig...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~306-~306: Use correct spacing
Context: ... to determine how to process the trigger - inputs (dict[str, str]): A dictionary of input ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~307-~307: There might be a problem here.
Context: ...ed to the graph. The keys are parameter names and values are parameter values, both as st...

(QB_NEW_EN_MERGED_MATCH)


[grammar] ~307-~307: There might be a mistake here.
Context: ...es are parameter values, both as strings ## Integration with ExosphereHost Platform ...

(QB_NEW_EN_OTHER)

🪛 markdownlint-cli2 (0.17.2)
python-sdk/README.md

224-224: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


257-257: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


262-262: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


265-265: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


306-306: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)

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

1-1: Version bump aligns with new public API exposure.

The version update to 0.0.7b6 is appropriate for introducing StateManager and TriggerState.

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

40-40: Public re-export of StateManager and TriggerState looks good.

This makes the new API available via exospherehost.StateManager and exospherehost.TriggerState.

python-sdk/exospherehost/statemanager.py (2)

99-105: Input validation for mutually exclusive arguments looks correct.

Covers all invalid combinations, including empty list.


1-3: aiohttp already declared in python-sdk dependencies

The python-sdk/pyproject.toml includes:

  • Line 9: "aiohttp>=3.12.15"

No changes needed for runtime dependency declaration.

Copy link
Contributor

@nk-ag nk-ag left a comment

Choose a reason for hiding this comment

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

lgtm

@NiveditJain NiveditJain merged commit 7038dc2 into exospherehost:main Aug 17, 2025
3 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.

2 participants