Mitxonline ETL: switch to consuming internal courses endpoint#3543
Mitxonline ETL: switch to consuming internal courses endpoint#3543shanbady wants to merge 14 commits into
Conversation
OpenAPI Changes24 changes: 0 error, 9 warning, 15 info Unexpected changes? Ensure your branch is up-to-date with |
There was a problem hiding this comment.
Pull request overview
This PR updates the MITx Online ETL to support consuming MITx Online’s internal courses endpoint by optionally attaching an API key, and hardens pagination behavior when the upstream API returns next URLs with an unexpected scheme.
Changes:
- Add
MITX_ONLINE_ETL_API_KEYsetting and send it asAuthorization: Api-Key <key>for MITx Online ETL requests. - Preserve the original request scheme (e.g., keep
https) when following paginationnextlinks. - Add unit tests covering scheme preservation and authorization header behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| main/settings_course_etl.py | Adds a new optional env setting for the MITx Online internal endpoint API key. |
| learning_resources/etl/mitxonline.py | Sends the API key header (when configured) and preserves scheme across pagination. |
| learning_resources/etl/mitxonline_test.py | Adds test coverage for scheme preservation and auth header injection. |
| params = {} | ||
| headers = {} | ||
| if settings.MITX_ONLINE_ETL_API_KEY: | ||
| headers["Authorization"] = f"Api-Key {settings.MITX_ONLINE_ETL_API_KEY}" |
There was a problem hiding this comment.
The API returns all published runs per course — including B2B and variant runs that v2 filtered out. _transform_course (:352) keeps all of them and publishes any run with is_enrollable AND page.live, so they surface in the catalog. (include_in_learn_catalog gates the course, not its runs.)
With RC data, published courses expose published B2B/variant published runs in API responses.
Also, these runs can impact the assignment of best_run (models.py:581-634), which picks purely by enrollment/start date with no B2B/variant awareness — some of these runs now resolve to a B2B run as their best_run , which drives the displayed dates/price/URL and gates opensearch content-file indexing, so the wrong run could be shown and indexed in opensearch.
Example: http://api.open.odl.local:8065/api/v1/learning_resources/?readable_id=course-v1%3AMITxT%2BSTL.162x
Maybe we need a new field on LearningResourceRun to differentiate B2B/variant runs and exclude them from API results and calculation of best_run?
There was a problem hiding this comment.
Not sure if we want these b2b/variant runs in the API results or not, but pretty sure they should not be assigned as the best_run for published courses.
There was a problem hiding this comment.
Maybe can just set these runs as always unpublished, so they get their contentfiles indexed but that's it (assuming they don't have to show up anywhere else in mit-learn).
There was a problem hiding this comment.
that is a good point..let me see if i can filter those out some how
There was a problem hiding this comment.
I added a is_b2b attribute for runs which gets set based on b2b_contract from the api
| MITX_ONLINE_COURSES_API_URL = get_string("MITX_ONLINE_COURSES_API_URL", None) | ||
| # API key for the MITx Online internal-only secured endpoint. When set, it is | ||
| # sent as an "Authorization: Api-Key <key>" header on MITx Online ETL requests. | ||
| MITX_ONLINE_ETL_API_KEY = get_string("MITX_ONLINE_ETL_API_KEY", None) |
There was a problem hiding this comment.
README.md:300-301 and env/codespaces.env:29-30 still point at /api/v2/courses/ — maybe worth updating to the internal endpoint (and mentioning that MITX_ONLINE_ETL_API_KEY is now required for that ETL).
There was a problem hiding this comment.
I was intending this to be backwards compatable (local setups default to the public endpoint ~ less configuration for default environments)
| while url: | ||
| # Preserve the scheme of the current request: the upstream API can | ||
| # return an http "next" URL even when we requested over https. | ||
| scheme = urlparse(url).scheme |
There was a problem hiding this comment.
Nit: scheme is invariant across loop iterations — each rewritten url already carries the preserved scheme — so it could be captured once before the while. Not a bug, just slightly clearer.
There was a problem hiding this comment.
Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit at claude.ai/admin-settings/claude-code.
Once credits are available, push a new commit or reopen this pull request to trigger a review.
mbertrand
left a comment
There was a problem hiding this comment.
LGTM, one question I have is if this will handle variant courses (other languages?) that are not B2B, or do those not exist?
Other than that, 1 minor nit about a trailing slash for individual course endpoint urls
| courses = [] | ||
| for course_id in course_ids: | ||
| response = requests.get( | ||
| f"{base_url}/{course_id}", |
There was a problem hiding this comment.
Maybe add a trailing slash to avoid a 301 redirect
What are the relevant tickets?
Closes https://github.com/mitodl/hq/issues/11671
Description (What does it do?)
This PR allows us to be able to use the internal mitxonline courses api which includes variant and b2b courses
How can this be tested?
./manage.py backpopulate_mitxonline_dataAdditional Context
merging this will be blocked on getting the actual api key secrets onto mitlearn rc/prod via https://github.com/mitodl/hq/issues/12088