feat: add GH workflow to generate openapi schema - #39025
Merged
Faraz32123 merged 7 commits intoOct 5, 2026
Merged
Faraz32123 merged 7 commits into
Faraz32123 merged 7 commits into
Conversation
Faraz32123
force-pushed
the
feat/add_workflow_to_automatically_generate_openapi_schema
branch
from
August 25, 2026 13:09
b5c8f71 to
69a3dd8
Compare
taimoor-ahmed-1
approved these changes
Sep 2, 2026
feanil
reviewed
Sep 8, 2026
feanil
reviewed
Sep 9, 2026
feanil
reviewed
Sep 16, 2026
Faraz32123
added a commit
to edly-io/openedx-platform-sdk
that referenced
this pull request
Sep 17, 2026
openedx/openedx-platform#39025 writes the generated schemas to docs/lms-openapi.yaml and docs/cms-openapi.yaml instead of the repo root, so follow the sparse-checkout, the CI env vars, and the PLATFORM_DIR copy. The SDK's own local copies keep their cms_schema.yml / lms_schema.yml names.
feanil
reviewed
Sep 21, 2026
Add GH workflow to automatically generate openapi schema whenever view file tagged with the "openedx-platform-sdk" @extend_schema tag changes
address comments on generate_openapi_schemas workflow - weekly schedule - use team-reviewers param
- write to docs/lms-openapi.yaml and docs/cms-openapi.yaml instead of creating new schema files at the repo root - generate the LMS schema under docs.docs_settings so the workflow writes the same full API surface `make swagger` does, rather than overwriting the docs schema with the narrow SDK-facing one
uv sync installed no groups, so ora2 was missing and both schema steps died with ModuleNotFoundError. Use the docs group, which pulls in bundled, the same set .readthedocs.yaml installs. manage.py cms defaults to cms.envs.devstack, which needs a CMS_CFG file CI does not have. Run it under cms.envs.development, and give cms/envs/common.py the schema title and version — the Authoring API's SPECTACULAR_SETTINGS lives in devstack and production, so development would otherwise emit an untitled 0.0.0 document. Also align the setup-uv pin with the other workflows, and add branch-suffix and workflow_ref provenance to match the other PR-opening ones.
Faraz32123
force-pushed
the
feat/add_workflow_to_automatically_generate_openapi_schema
branch
from
September 22, 2026 16:54
32eba76 to
9532c3c
Compare
feanil
reviewed
Sep 28, 2026
Generation needs migrated tables, not just a server: drf-spectacular evaluates a queryset while building a warning for edxval's VideoList. Add the mysql service and a migrate step the way migrations-check.yml does. cms.envs.development inherited the Authoring API's title and version but none of its filtering, so docs/cms-openapi.yaml came out at 235 paths with the rest of the service in it. Only SERVERS and the long DESCRIPTION depend on CMS_BASE and AUTHORING_API_URL, so the hooks and the path prefix move down to cms/envs/common.py as well. 57 paths.
feanil
reviewed
Sep 29, 2026
split_modulestore_django's 0002_data_migration reads the modulestore, so migrating from empty needs Mongo even though generation doesn't. Add the service and the user setup step from migrations-check.yml. manage.py falls back to devstack without DJANGO_SETTINGS_MODULE, and devstack's DATABASES is empty without an LMS_CFG, so both migrate steps failed before reaching the service. Run each under the same settings as its generate step.
feanil
approved these changes
Oct 1, 2026
This was referenced Oct 4, 2026
Faraz32123
deleted the
feat/add_workflow_to_automatically_generate_openapi_schema
branch
October 5, 2026 07:31
Faraz32123
added a commit
to edly-io/openedx-platform-sdk
that referenced
this pull request
Oct 6, 2026
* chore: add SDK generation tooling and README
Adds the tools needed to generate the SDK from openedx-platform:
- filter_schema.py: filters the full OpenAPI schema to only paths tagged
with openedx-platform-sdk, resolving all transitive $ref dependencies
- config.yml: openapi-python-client config (package/project name + include_tags)
- README.md: documents covered APIs, regeneration steps (curl + filter +
openapi-python-client generate), and usage examples
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add auto-generated SDK from openedx-platform-sdk tagged endpoints
Generated with openapi-python-client from the filtered OpenAPI schema.
Covers 12 operations across 5 APIs:
- XBlock v1: create, retrieve, update, partial_update, destroy
- Authoring Grading v3: partial_update
- Course Details v3: retrieve, update
- Home v3: list, courses, libraries
- Home v4: courses (paginated)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add OAuth2 client credentials auth helper
Implements OAuth2ClientCredentials for the OpenedX JWT auth flow:
- Fetches JWT via POST to {lms_url}/oauth2/access_token (client_credentials grant)
- Caches token and auto-refreshes 60s before expiry
- Returns AuthenticatedClient with prefix="JWT" (required by OpenedX)
Usage:
auth = OAuth2ClientCredentials(lms_url, client_id, client_secret)
with auth.get_client(studio_url) as client:
result = v3_home_list.sync(client=client)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add regen_sdk.sh automation script
Automates the full SDK regeneration workflow:
1. Optional branch checkout in openedx-platform
2. Download OpenAPI schema from running Studio (STUDIO_URL env var)
3. Filter schema to openedx-platform-sdk tagged paths via filter_schema.py
4. Run openapi-python-client update (or generate on first run)
Usage:
./regen_sdk.sh # uses current platform branch
./regen_sdk.sh feat/axim-api_improvements # checkout branch first
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add testing steps & fix regen_sdk.sh
- Add 'Testing Locally' section to README: install, create OAuth2 app
in LMS admin (user must be linked for JWT issuance), test script
- Fix studio_url in auth example to include /api/contentstore prefix
- Make regen_sdk.sh portable: PLATFORM_DIR env var for custom platform
path, clear error if branch requested but repo not found, STUDIO_URL
error message if Studio unreachable
- Rename v3_home_list → v3_home_retrieve: fixed HomeViewSet list action
schema to return a single StudioHome object (not array) by overriding
_is_list_view in a custom AutoSchema; generator renamed the module
accordingly
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: regenerate SDK with grading schema fix, v4 paginated response, and generator bug fixes
Regenerated from updated openedx-platform schemas. Three platform-side
fixes drive this regen (see companion commit on add_changes_wrt_sdk):
- Grading: grade_cutoffs, grace_period, minimum_grade_credit are now
typed fields on AuthoringGradingCourseGradingV0 and
PatchedauthoringGradingCourseGradingV0. Callers no longer need to
pass these via additional_properties["key"] = value workarounds.
New models: AuthoringGradingGracePeriodV0,
*GradeCutoffs (additionalProperties wrapper for the dict field).
- v4 Home: operation ID changed from v4_home_courses_list to
v4_home_courses_retrieve (the schema now correctly describes a
paginated object, not an array). New model PaginatedV4HomeCoursesResponse
with count, num_pages, current_page, start, next_, previous, results.
- Course details: certificate_available_date is now nullable in the
schema; CourseDetails model updated accordingly.
Generator bug fixes baked into regen_sdk.sh (applied after every regen):
- Bug 1: v3_course_details_update.py uses Unset in type annotations
but the generator only imports UNSET. Fixed with a sed post-step.
- Bug 2: _get_kwargs emits three identical isinstance(body, X) blocks
for json / form / multipart — the multipart block always wins and
breaks nested-dict payloads. Removed data/multipart blocks, kept
only the JSON block. Affects: v1_xblock_{create,update,partial_update},
v3_authoring_grading_partial_update, v3_course_details_update.
- Bug 3: DictField wrapper models (e.g. GradeCutoffs) have their
to_dict() called unconditionally in parent model's to_dict(), but
users naturally pass plain Python dicts. Fixed with an isinstance
guard: call .to_dict() only when the value is not already a dict.
auth.py: set Accept: application/json as a default header in get_client().
XBlock retrieve returns 406 without it — httpx sends Accept: */* by
default which the view rejects.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add testing-sdk-apis.rst with typed usage examples for all API groups
Covers all five API groups exposed by the SDK with working, copy-paste
ready code snippets:
- Home v3: retrieve (studio name + courses + libraries), courses-only,
libraries-only endpoints
- Home v4: paginated courses with count / num_pages / results traversal
- Course Details v3: retrieve and PUT round-trip (retrieve → mutate →
update → restore pattern)
- Authoring Grading v3: PATCH with typed grade_cutoffs, grace_period,
and minimum_grade_credit fields (no more additional_properties hack)
- XBlock v1: retrieve, create, partial_update (rename), destroy —
including a single end-to-end lifecycle example
Also updates README to:
- Use typed SDK calls (v3_home_retrieve, v4_home_courses_retrieve) in
the Authentication, Usage, and Testing Locally sections instead of
the raw client.get_httpx_client().request() call
- Add a link to docs/testing-sdk-apis.rst from the Testing Locally
section for readers who want the full per-API examples
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add LMS Enrollment v2 API bindings and schema merge pipeline
Extends the SDK to cover the LMS Enrollment v2 API by merging an LMS
drf-spectacular schema into the Studio schema during regen_sdk.sh.
SDK changes:
- regen_sdk.sh: download LMS schema from /lms-api/schema/, pass --merge to
filter_schema.py; add Bug 5 fix (plain-list response for enrollment_allowed)
- filter_schema.py: add merge_schema(), fix_path_parameters() to strip
spurious path params that cause the generator to skip endpoints; add
--merge CLI flag
- New API modules: v2_enrollment_*, v2_course_retrieve, v2_roles_retrieve,
v2_enrollments_list (11 files)
- New models: CourseEnrollment, EnrollmentCourse, CourseEnrollmentAllowed,
and supporting paginated/response models (13 files)
- lms_schema.yml: cached LMS enrollment schema
Bug fixes applied at regen time:
- Bug 4: null-safe datetime parsing in EnrollmentCourse.from_dict()
- Bug 5: plain-list normalisation in PaginatedCourseEnrollmentAllowedList
Docs:
- README.md: add Enrollment v2 to covered APIs table, update regen steps
- docs/testing-sdk-apis.rst: update enrollment section with correct module
names, base URL (/api/enrollment), and accurate LMS schema note
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: address comments
* fix: address comments
address comments on regen_sdk.sh and regenerate_sdk workflow
- explicit schema source modes (no implicit defaults)
- rename schema.yml to cms_schema.yml
- remove branch checkout
- Tuesday schedule, as openedx-platform workflow will run on Monday, reviewers will have ample time to review and merge the PR.
* fix: address review feedback on SDK generation scripts
- regen_sdk.sh now takes PLATFORM_DIR or the schema URLs explicitly instead
of inferring them, and prefixes the schema filenames per service
- moved the auth.py round-trip out of `sed -i ''` (BSD-only, failed on Linux
after the tree was already removed) and into postprocess_sdk.py
- post-processing fails when a step patches nothing, and schema merges report
their collisions, so a schema change can't quietly invalidate a fix
- the three platform schema workarounds name their exit path:
openedx/openedx-platform#39120 for the two response-shape bugs,
openedx/openedx-platform#39121 for the spurious path parameter
- pinned the workflow actions to SHAs and recorded the platform revision from
the platform checkout rather than github.sha
- dropped the two unenroll request body models the API never accepts
* fix: read the platform schemas from their new docs/ paths
openedx/openedx-platform#39025 writes the generated schemas to
docs/lms-openapi.yaml and docs/cms-openapi.yaml instead of the repo root, so
follow the sparse-checkout, the CI env vars, and the PLATFORM_DIR copy. The
SDK's own local copies keep their cms_schema.yml / lms_schema.yml names.
* fix: switch the SDK tooling over to uv
Poetry installed the dev group into its own virtualenv, so regen_sdk.sh ran in
a plain shell with nothing on PATH and died on `import yaml` before reaching
the generator. pyproject.toml is PEP 621 now, uv.lock is committed, and the
script runs its tools through `uv run`.
Two things would have broken the first scheduled run. Ruff exits 1 on the
UP042s the generator emits and can't auto-fix, so the workflow never got as
far as opening a PR that rule is ignored now. And create-pull-request
commits everything untracked when add-paths is unset, so it would have carried
the platform/ checkout into the PR; scoped the commit and ignored the dir.
The unenroll fix deleted the two body model files unconditionally while the
__all__ removal only matched one exact indentation, and a shared counter let
one half cover for the other. Each half is tracked separately now.
Also moved the README to uv and added the studio_url its example was missing.
* fix: pin uv to the project and the lockfile
--frozen installs uv.lock without checking it against pyproject.toml, so the
generator pin was never enforced: setting it to 0.28.0 still installed 0.29.0
and exited 0. Use --locked, which fails when the two disagree.
uv run resolves the project from the working directory, so running the script
by path from elsewhere picked up whatever environment the caller was in rather
than the SDK's. A bare uv run also re-resolves and rewrites uv.lock, which can
install a different generator than the sync step did. Pass --locked and
--project on each call.
* docs: use uv sync --locked in README setup steps
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add GH workflow to automatically generate openapi schema whenever view file tagged with the "openedx-platform-sdk" @extend_schema tag changes.
Related PR: edly-io/openedx-platform-sdk#1