mitodl / mitxonline

BSD 3-Clause "New" or "Revised" License
4 stars 2 forks source link

Certificates: Investigate updating MITx Online data based on webhooks from OpenedX #690

Closed rhysyngsun closed 2 years ago

rhysyngsun commented 2 years ago

Summary

For certificates we need to be able to generate certificates automatically within a short time of a learner completing a course and exam. Current we use a polling mechanism and a blocking call when the learner loads the dashboard. The former causes a delay and the latter isn't great for performance and requires a learner to actually visit the dashboard.

To accomplish this, we need to investigate utilizing OpenedX's hooks infrastructure to send webhooks based on certain events to be able to reflect updates on the MITx Online side.

References

OEP-50: Hooks extension framework openedx-events Github openedx-events Docs

Tasks

Investigates the OpenedX infrastructure above and determine if it is the kind of mechanism we're looking for here:

arslanashraf7 commented 2 years ago

Posting initial update:

While looking at a lot of documentation in various different places there are a things that i can mention regarding the ticket tasks:

The hooks from Open edX are provided and can be used in two ways, 1- Filters, The package implementation can be seen here. The filters generally allow us to manipulate/update some data through a pipeline before it's passed to the actual functionality. 2- Events, The package implementation can be seen here. Events are just a piece of information to whoever is listening to them and don't allow us to update the data before it gets used in the functionality itself.

Does it provide hooks for the events we need (course grade updates, course completion)?

As seen in the above lists, Both filters and events don't provide the specific hooks that we need but there are some regarding certificates that we might dig around more for our use case.

Does it provide an ability to make webhook calls (either natively or via additional code)? Would this require our own plugin?

Per my initial research, we will need to create a plugin for whatever we use (Events or Filters).

An implementation reference for Filters can be seen here and it looks like we will need to inject a custom filter function through a plugin in settings.

An implementation detail for Events can be seen here and for this we would need a plugin and register to the signals/events the platform would emit.

The above is kind of initial details but I just wanted to share anyway. It's possible that these might change with some more research.

FYI, @rhysyngsun @pdpinch

pdpinch commented 2 years ago

Can use the filter CertificateCreationRequested https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L142 to send a webhook to mitxonline which can take care of actually creating the certificate?

The provided list of filters is here https://github.com/openedx/edx-platform/blob/master/docs/guides/hooks/filters.rst#index-of-filters

arslanashraf7 commented 2 years ago

Can use the filter CertificateCreationRequested https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L142 to send a webhook to mitxonline which can take care of actually creating the certificate?

We might be able to use that but we will have to check at which point that filter will run. e.g. We want automatic creation of certificates in MITxOnline upon course creation and in edX it is possible that this filter will run when the user manually clicks the Generate Certificate button that's there in multiple places I think e.g. on dashboard page and course details page.

I think there is a functionality for automatic certificate generation in edX and in that case we should be able to use this filter. I'll need to look more into how we can enable that and if enabling that will run this filter automatically too.

arslanashraf7 commented 2 years ago

Adding more to my above comment:

While looking around I also explored the event bus confluence doc and this readthedoc and tried to check if it has any usage as of now on the platform but looking at the confluence documentation it looks like that is still in progress.

Basically, from what I understand the event bus once complete will provide the functionality of posting event streams on some data feed systems e.g. kafka from where the other services might connect, get the event streams and perform the operations that they need to.

Since as per my understanding the event bus is still in progress and it looks like currently our best shot at doing what we want would be to create a simple edx plugin that will register to the CertificateCreation filter or event (Depending upon the question I'm mentioning below).

Q: Currently, for someone who completes a course do we generate two certificates (one in edX and the other one in MicroMasters)?

The above information might be required about whether we would like to use the Filter or an Event hook from edX hooks framework. As per my understanding, If we generate two certificates we should be using Event to hook to our MITxOnline. If we need to create the certificate on MITxOnline only then we will use Filter so when a CreateCertificate filter runs we call our MITxOnline API to create the certificate and pass on the certificate creation in edX since Filter will allow us to manipulate the data to be used for Certificate creation within edX.

Currently, Looks like we can enable automatic certificates in edX and configure our hook through our new plugin. We will also need an API in MITxOnline that creates a certificate for a user.

FYI, @pdpinch @rhysyngsun

pdpinch commented 2 years ago

Q: Currently, for someone who completes a course do we generate two certificates (one in edX and the other one in MicroMasters)?

In mitxonline, we only need to generate a certificate in mitxonline. This is similar to xPRO.

We will also need an API in MITxOnline that creates a certificate for a user.

Yes. Can you open an issue for that?

arslanashraf7 commented 2 years ago

Yes. Can you open an issue for that?

The associated has been created https://github.com/mitodl/mitxonline/issues/700

rhysyngsun commented 2 years ago

Ideally we'd try to upstream an openedx_events event for course passing, but for now using the filters is ok although we should make a note in the implementation that this is not optimal since it's misusing the filters feature.

rhysyngsun commented 2 years ago

So I discovered that openedx has another event dispatch mechanism: https://github.com/openedx/event-tracking

It's mean to route events to external systems so this actually seems like pretty much exactly what we'd want. We'd be able to implement a backend for this that does what we want. We'd want to filter to edx.course.grade.now_passed and there are others in grades/events.py we'll probably want to use eventually.

I'd also suggest that instead on making a certificates-specific API that we actually create a webhook endpoint and send well-structured events. There may be other things besides generating certificates that we want to do when a learner passes a course in the future so it would be good to keep this generalized. I'm thinking of a payload like this:

{
  "event_type": "edx.course.grade.now_passed",
  "event_id": "<event_transaction_id>",
  "event_created: <timestamp>,
  "data": {
    // relevant data
  }
}

And we'd have the eventtracker backend send these to a webhook endpoint like /api/v0/openedx-webhooks/ which would route according to event_type and execute the relevant code (e.g. generate a certificate when a learner passes).

What do we think of this?

blarghmatey commented 2 years ago

My first question is what level of reliability we need to guarantee around event delivery. If we want to tolerate occasional delivery failures and have a reconciliation process that runs in batch mode then this seems ok. If we need guaranteed delivery then we'll want to think about what delivery mechanism we want (e.g. Pulsar, Kinesis, etc.). As to the use of the event-tracking backend, there is also https://github.com/openedx/openedx-events which is part of their Hooks extension approach defined here https://open-edx-proposals.readthedocs.io/en/latest/architectural-decisions/oep-0050-hooks-extension-framework.html

I'll have to spend some time remembering which of those libraries is intended for what purposes...

rhysyngsun commented 2 years ago

Closing this since we've evaluated the options enough but picked a different direction anyway.