-
Notifications
You must be signed in to change notification settings - Fork 455
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
Plugins v1 #599
Plugins v1 #599
Conversation
622b479
to
f17c0c8
Compare
7886a91
to
3aea3bf
Compare
37b0431
to
039ade9
Compare
039ade9
to
5440f9d
Compare
5440f9d
to
31b5e22
Compare
This is ready for review @overhangio/tutor-developers. I understand this is a huge PR, and it requires some sort of explanation. We are currently planning a meeting with @kdmccormick so that everyone understands what's at stake here, and what is the technical solution that I've ended up implementing. We'll decide on a meeting date and then plugin developers will be invited to the meeting. Meanwhile, you can learn more about that project by having a look at this comment: openedx-unsupported/wg-developer-experience#32 (comment) |
If other plugin developers are interested in learning about the new plugin API, we'll be discussing it with Kyle & Rebecca today March 29th at 12:30 UTC: https://us02web.zoom.us/j/85637351768?pwd=Y1htdFlLNnRTZzd6VXQwNW45eTArUT09 |
31b5e22
to
7d5c685
Compare
Thanks for the heads-up @regis! I'll try to make that but it comes at slightly short notice for me so I'm not sure if I'll be able to, hence I'm putting a few thoughts down here in writing. I hope that's OK. In brief, I admire the rationale behind this, and I think it's a good approach. But, and this is completely separate from a discussion on the technical merits, to be honest I am a bit skeptical about the timing. Consider that since the December Open edX Maple release which made Tutor the default mode of deploying Open edX, a bunch of people would have been scrambling to achieve feature parity with edx-configuration, so that they can move their production platforms to Tutor. Since Tutor has always followed the policy of keeping its basic feature set simple, and exposing other features with plugins, that means that people have been busy writing and testing plugins since then (we've written 7 so far). Are you sure it's a good idea to introduce a new plugin API just now, less than 4 months after the Maple release, essentially forcing people to start updating/rewriting them? (Yes I understand you want to keep backward compatibility with the v0 API. But you wouldn't want to do that for long, see xkcd927 🙂). My point is just that after several years in limbo — with edx-configuration being "quietly" deprecated long before it officially was, no endorsed alternative coming out of edX, and there having been being months of back-and-forth until Tutor was finally adopted as the new community development platform — community Open edX deployers could be forgiven to desire some degree of stability in the deployment tools. So, is the v0 plugin API perhaps "good enough" for a few more months until people have completed their Maple/Tutor transitions, for a new plugin API to be introduced thereafter? |
I understand your concern Florian and I agree that the timing is not great. Several things are happening at once with Tutor: system administrators are learning to switch from the native installation and edX/2U is moving away from the Devstack. The latter project is straining the v0 plugin API beyond its capabilities, as we can see from these issues that were collected by Kyle: https://github.com/overhangio/2u-tutor-adoption/issues/ The goal of this new v1 API is to make it easier for developers to use Tutor and to customise their platforms with plugins. It would be counter-productive if it actually made people's life more more difficult. My understanding is that to make this transition successful we need to work on three key aspects:
We can cover items 1 and 2 by preserving support for the v0 API and resolving issues listed in the 2u-tutor-adoption project. To address item 3 we are planning to:
I'll flip the question: you and your team have made several significant contributions to Tutor and I'd like you to keep doing that. How can I make your life easier and more productive?
It's OK if you can't come; this is going to be a preliminary meeting, and I expect that there will be at least another one with Tutor maintainers before we merge this PR. |
ae6ebd8
to
308660d
Compare
8f01c86
to
5ab39a0
Compare
@kdmccormick what do you think about "load/unload"? Or is that too generic? |
5ab39a0
to
3e2408b
Compare
@regisb I like load/unload 👍🏻 |
3e2408b
to
c6fd572
Compare
@kdmccormick I've made the requested changes, please let me know what you think. I've tried to improve the wording across the docs and the codebase. We can always improve it later, but we should be very careful with the hook constant names, which are not supposed to change with time (although I guess that we can take some liberties). Regarding the suppression of hook |
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.
I think the plugin guide is awesome. I love that it guides a user from basic concepts all the way to adding a new service. I have suggestions for it, but like you said, we can improve it after this PR lands if you'd rather not address all my feedback on it right away.
I agree that the hook names are the most important thing to hammer out right now. I have suggested some changes to the action names, and I'm chewing on the app:task:*
filter names currently.
if we make use only of keyword arguments, then we need to provide a default value for each one of them.
Python 3 has a funky syntax to solve exactly this problem, if you were so inclined:
>>> def f(*, x, y):
... return x + y
...
>>> f(1,2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 0 positional arguments but 2 were given
>>> f(x=1,y=2)
3
>>> f(x=1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() missing 1 required keyword-only argument: 'y'
I'm starting to see this PR and at the moment I have the following questions:
|
ab7f582
to
266e70e
Compare
To answer your questions @MaferMazu:
It will not be possible to create YAML plugins with the V1 API, but existing v0 plugins will remain supported for a long time.
Yes, exactly. This will be the new "lightweight" way of creating simple plugins, similar to YAML plugins, but not subject to the same limitations (this one for example).
Not drastically, no. The
Not yet. I'm working on upgrading the plugin cookiecutter to generate valid v1 plugins (see this issue). Regarding your comment @kdmccormick:
That's a bit too funky for me :) I had no idea that this syntax existed! |
b2dd9f1
to
a0fc927
Compare
This is a very large refactoring which aims at making Tutor both more extendable and more generic. Historically, the Tutor plugin system was designed as an ad-hoc solution to allow developers to modify their own Open edX platforms without having to fork Tutor. The plugin API was simple, but limited, because of its ad-hoc nature. As a consequence, there were many things that plugin developers could not do, such as extending different parts of the CLI or adding custom template filters. Here, we refactor the whole codebase to make use of a generic plugin system. This system was inspired by the Wordpress plugin API and the Open edX "hooks and filters" API. The various components are added to a small core thanks to a set of actions and filters. Actions are callback functions that can be triggered at different points of the application lifecycle. Filters are functions that modify some data. Both actions and filters are collectively named as "hooks". Hooks can optionally be created within a certain context, which makes it easier to keep track of which application created which callback. This new hooks system allows us to provide a Python API that developers can use to extend their applications. The API reference is added to the documentation, along with a new plugin development tutorial. The plugin v0 API remains supported for backward compatibility of existing plugins. Done: - Do not load commands from plugins which are not enabled. - Load enabled plugins once on start. - Implement contexts for actions and filters, which allow us to keep track of the source of every hook. - Migrate patches - Migrate commands - Migrate plugin detection - Migrate templates_root - Migrate config - Migrate template environment globals and filters - Migrate hooks to tasks - Generate hook documentation - Generate patch reference documentation - Add the concept of action priority Close #499.
a0fc927
to
cd905cb
Compare
I think I've exhausted the list of things to do here. I'll merge now 🏴☠️ |
Woohoo! 🎉 |
This is a very large refactoring which aims at making Tutor both more
extendable and more generic. Historically, the Tutor plugin system was
designed as an ad-hoc solution to allow developers to modify their own
Open edX platforms without having to fork Tutor. The plugin API was
simple, but limited, because of its ad-hoc nature. As a consequence,
there were many things that plugin developers could not do, such as
extending different parts of the CLI or adding custom template filters.
Here, we refactor the whole codebase to make use of a generic plugin
system. This system was inspired by the Wordpress plugin API and the
Open edX "hooks and filters" API. The various components are added to a
small core thanks to a set of actions and filters. Actions are callback
functions that can be triggered at different points of the application
lifecycle. Filters are functions that modify some data. Both actions and
filters are collectively named as "hooks". Hooks can optionally be
created within a certain context, which makes it easier to keep track of
which application created which callback.
This new hooks system allows us to provide a Python API that developers
can use to extend their applications. The API reference is added to the
documentation, along with a new plugin development tutorial.
The plugin v0 API remains supported for backward compatibility of
existing plugins.
FAQ
Is this PR ready for comments?
Yes! If you are a plugin developer, we would like to hear what you have to say.
Why is this PR so large?
Because I refactored the entire code base to make use of the v1 API. Tutor core now uses its own extension mechanism, in the spirit of dogfooding. We do that because the eventual long-term goal is to extract the extension API from Tutor in a different package, such that it can be used to deploy not just Open edX, but other software as well. (see this issue for more information)
Where should I start?
I'm glad you're interested :)
I think that at this point you should already have plenty of questions and comments...
When should this be merged?
All official plugins should be migrated to v1 prior before the Nutmeg release (June 9th 2022), so April 30th would be a good deadline.
Will this PR break my plugin?
No. Existing plugins should keep working as expected. If they don't, then it's a bug. Please report them in the forum, as usual :)
How long will the v0 API be supported?
A long time. We want to leave time to all developers to migrate their plugins from v0 to v1. I don't anticipate that this will cause any issue, because under the hood the v0 plugin API already uses the v1 API.
What can I do with v1 that I couldn't with v0?
Lots of stuff! This PR does not introduce many new features by itself, but I expect that in the future it will become very easy to make profound changes to how Tutor works using just plugins. Here's a sneak peek of what I have in mind:
tutor local
andtutor k8s
CLI.Done
the source of every hook.
TODO
tutor.hooks.Filters.MY_FILTER.apply(...)
Action.on()
toAction.add()
?*args
. EDIT: we should keep them.