Skip to content

refactor: Event connector UX#200

Open
chrisk314 wants to merge 7 commits intomainfrom
refactor/event-connector-ux
Open

refactor: Event connector UX#200
chrisk314 wants to merge 7 commits intomainfrom
refactor/event-connector-ux

Conversation

@chrisk314
Copy link
Contributor

@chrisk314 chrisk314 commented Feb 1, 2026

Summary

This PR addresses #57 by refactoring the code involved in creating Connectors for Events in event-driven models in an attempt to simplify the user experience. Previously multiple lines of code were required involving several library classes putting some burden of understanding low level details on the user. Now these lines can be replaced with a single line of code involving a concrete Connector class which will be familiar to users.

Changes

  • EventConnectorBuilder becomes a utility class EventConnectorSpecBuilder with its responsibility changed to producing a mapping of event.type -> ConnectorSpec.
  • ConnectorBuilder exposes a new method build_event_connectors(components: list[Component]) -> list[Connector] which consumes the EventConnectorSpecBuilder to produce the required Event Connectors.
  • Connector ABC has a new class method builder which returns a ConnectorBuilder for a given Connector concrete class.
  • Updates tests, examples, and docs with this streamlined approach.
  • Also corrects the logic related to restricting attempted use of event based models with RayConnector (previously restriction was applied to RayProcess which actually can be used with different Connector classes).

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @chrisk314, 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 user experience for developers working with event-driven models by refactoring the underlying mechanism for creating event connectors. The changes consolidate the complex, multi-step process of setting up event Connectors into a single, intuitive method call on the ConnectorBuilder, thereby abstracting away low-level details and reducing boilerplate code. This makes it easier and quicker to integrate event handling into components.

Highlights

  • Simplified Event Connector Creation: The process of creating Connectors for Events has been significantly streamlined, reducing multiple lines of code to a single method call.
  • EventConnectorBuilder Replaced: The EventConnectorBuilder class has been removed. Its functionality for generating ConnectorSpec objects has been moved to a new utility class, EventConnectorSpecBuilder.
  • ConnectorBuilder Enhancement: The ConnectorBuilder now exposes a new method, build_event_connectors, which directly handles the creation of event-driven Connectors from a list of components.
  • Updated Ecosystem: All relevant documentation, examples, and integration/unit tests have been updated to utilize this new, simplified API for event connector management.
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 by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

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 pull request 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 is a solid refactoring that significantly simplifies the user experience for creating event connectors. The changes are consistently applied across the codebase, including documentation, examples, and tests, which is great to see. I have a couple of suggestions to further improve the implementation by enhancing type safety and simplifying some of the new logic.

I am having trouble creating individual review comments. Click here to see my feedback.

plugboard/connector/connector_builder.py (22)

medium

The type hint for components should be more specific for better type safety. It should be _t.Iterable[Component] instead of _t.Iterable[_t.Any] to match the signature of EventConnectorSpecBuilder.build. Using a string forward reference "Component" is necessary to avoid a circular import.

To make this work, you'll need to add the following import inside a TYPE_CHECKING block at the top of the file:

if _t.TYPE_CHECKING:
    from plugboard.component import Component
    def build_event_connectors(self, components: _t.Iterable["Component"]) -> list[Connector]:

plugboard/connector/event_connector_spec_builder.py (18-38)

medium

The build method and its helper _build_for_component can be significantly simplified. You can first gather all unique event types from all components into a set, and then create the connector specs in a single dictionary comprehension. This makes the logic more concise and easier to follow.

    @staticmethod
    def build(components: _t.Iterable[Component]) -> dict[str, ConnectorSpec]:
        """Returns mapping of connector specs for events handled by components."""
        all_event_types = {
            evt.type
            for component in components
            for evt in component.io.input_events + component.io.output_events
        }
        return {
            evt_type: EventConnectorSpecBuilder._build_for_event(evt_type)
            for evt_type in all_event_types
        }

@toby-coleman
Copy link
Contributor

@copilot can you resolve the circular import problem in this PR?

Copy link
Contributor

Copilot AI commented Feb 7, 2026

@toby-coleman I've opened a new pull request, #208, to work on those changes. Once the pull request is ready, I'll request review from you.

@github-actions
Copy link

github-actions bot commented Feb 7, 2026

Benchmark comparison for d36ec1de (base) vs 18b96d52 (PR)


------------------------------------------------------------------------------------------------------------------ benchmark: 2 tests -----------------------------------------------------------------------------------------------------------------
Name (time in ms)                                                                         Min                 Max                Mean            StdDev              Median               IQR            Outliers     OPS            Rounds  Iterations
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_benchmark_process_run (main/.benchmarks/Linux-CPython-3.12-64bit/0001_base)     309.9785 (1.0)      314.4263 (1.0)      311.5111 (1.0)      1.9013 (1.0)      310.6048 (1.0)      2.8476 (1.0)           1;0  3.2102 (1.0)           5           1
test_benchmark_process_run (pr/.benchmarks/Linux-CPython-3.12-64bit/0001_pr)         314.4213 (1.01)     334.9442 (1.07)     322.9003 (1.04)     7.7523 (4.08)     321.1359 (1.03)     9.7187 (3.41)          2;0  3.0969 (0.96)          5           1
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Legend:
  Outliers: 1 Standard Deviation from Mean; 1.5 IQR (InterQuartile Range) from 1st Quartile and 3rd Quartile.
  OPS: Operations Per Second, computed as 1 / Mean

@codecov
Copy link

codecov bot commented Feb 7, 2026

@github-actions
Copy link

github-actions bot commented Feb 7, 2026

Benchmark comparison for d36ec1de (base) vs 8180e9d9 (PR)


------------------------------------------------------------------------------------------------------------------ benchmark: 2 tests ------------------------------------------------------------------------------------------------------------------
Name (time in ms)                                                                         Min                 Max                Mean            StdDev              Median                IQR            Outliers     OPS            Rounds  Iterations
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_benchmark_process_run (pr/.benchmarks/Linux-CPython-3.12-64bit/0001_pr)         448.1174 (1.0)      466.0313 (1.00)     456.9734 (1.0)      7.5318 (1.77)     454.4770 (1.0)      12.5263 (2.99)          2;0  2.1883 (1.0)           5           1
test_benchmark_process_run (main/.benchmarks/Linux-CPython-3.12-64bit/0001_base)     453.8107 (1.01)     465.0293 (1.0)      457.8865 (1.00)     4.2668 (1.0)      457.3485 (1.01)      4.1880 (1.0)           1;0  2.1839 (1.00)          5           1
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Legend:
  Outliers: 1 Standard Deviation from Mean; 1.5 IQR (InterQuartile Range) from 1st Quartile and 3rd Quartile.
  OPS: Operations Per Second, computed as 1 / Mean

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.

3 participants