-
Notifications
You must be signed in to change notification settings - Fork 51
feat: 🔌 Initial plugin system implementation #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: 🔌 Initial plugin system implementation #23
Conversation
nabinchha
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for partitioning the changes into multiple scoped PRs. It's helpful to follow along and easier to review.
Trying to follow your lead, my friend 👍 |
Co-authored-by: Nabin Mulepati <[email protected]>
Co-authored-by: Nabin Mulepati <[email protected]>
d112d9c to
4bccea7
Compare
|
@nabinchha – made some internal updates to the PluginRegistry in c752bd4. I moved the thread lock call to the initialization, which calls |
🔌 Plugin System Overview
This PR implements the initial scaffolding for Data Designer's plugin system. Column Generators are the first plugin type we will support. For now, plugin developers will need to deal with all the boilerplate and build their generators from the bottom up. This means importing and correctly using objects like the
ConfigurableTaskbase class. In a follow up PR, we will implement a decorator that will streamline plugin development.Update: I am starting to have doubts about the decorator approach mentioned above. I don't think it will play nice with IDEs. I'm thinking about instead implementing helper objects that will make it easier to put column generators together. For example, so you don't have to worry about defining the task metadata or inherit from
ColumnGenerator(not sure if we can avoid this one, though).💡 Plugin Discovery
Failed attempt: file search
I initially built the plugin discovery so that it recursively searched for plugins in python files located in
~/.data_designer/plugins. However, it became clear that this approach (1) wouldn't be straightforward to transition to pip-installable plugins and (2) doesn't play nice with IDEs (e.g., how are the plugins loaded? is the plugin file in the user's python path?).Successful approach (hopefully): entrypoints
Instead, plugin discovery has been implemented using entrypoints. In short, plugin developers need to create a python package for their plugin and specify an entrypoint (or points) that point to their plugin object(s).
For example, they might have an entrypoint like
Data Designer can then discover this plugin as follows:
While this approach requires a bit more effort from the plugin developer, it will support pip-installed plugins out of the box. It also plays nicely with IDEs, since the user can import plugin configs directly and use them with DD:
📢 Callouts
I split
data_designer/configs/columns.pyinto two files:column_configs.pyandcolumn_types.py. The latter is where plugins are injected into type unions, emoji maps, the column type enum, etc. Importantly,column_types.pyshouldn't be imported in the plugin implementation. With plugin extensions,column_types.pyshould be thought of as something that gets fully defined at runtime (with all the plugins ready to go). Thinking about renaming to_column_types.pyto make this more clear.There is a PluginManager, which handles plugin discovery, registration, and loading / fetching.
This is the Plugin object that needs to be defined and added to the entrypoint (i.e., the ":plugin" at the end of the entrypoint definition above).
These plugin helper functions are how the client-side code interacts with plugins (can't depend on engine or plugin code directly).