Skip to content

Commit 5c3fbec

Browse files
Faraz32123claude
andauthored
feat: configure drf-spectacular on LMS for enrollment API schema gene… (#38849)
* feat: add drf-spectacular on LMS for enrollment API schema generation Adds drf-spectacular support to LMS so the openedx-platform-sdk can generate enrollment v2 API bindings from a proper LMS schema rather than mounting enrollment URLs in CMS as a workaround. Changes: - openedx/envs/common.py: add DEFAULT_SCHEMA_CLASS to REST_FRAMEWORK so drf-spectacular's AutoSchema is used across all LMS environments - lms/envs/common.py: add drf_spectacular to INSTALLED_APPS - lms/lib/spectacular.py: preprocessing hook that filters to enrollment v2 endpoints only (/api/enrollment/v\d+/) - lms/envs/devstack.py, lms/envs/production.py: SPECTACULAR_SETTINGS with path prefix trim and enrollment-only title - lms/urls.py: expose schema at /lms-api/schema/ via SpectacularAPIView - cms/lib/spectacular.py: revert enrollment URL workaround (no longer needed) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: move settings to common.py --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 794c440 commit 5c3fbec

7 files changed

Lines changed: 53 additions & 3 deletions

File tree

cms/lib/spectacular.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ def cms_api_filter(endpoints):
1212
CMS_PATH_PATTERN = re.compile(r"^/api/contentstore/v\d+/")
1313

1414
for path, path_regex, method, callback in endpoints:
15-
if CMS_PATH_PATTERN.match(path) or (
16-
path.startswith("/api/courses/")
17-
and "bulk_enable_disable_discussions" in path
15+
if (
16+
CMS_PATH_PATTERN.match(path)
17+
or (
18+
path.startswith("/api/courses/")
19+
and "bulk_enable_disable_discussions" in path
20+
)
1821
):
1922
filtered.append((path, path_regex, method, callback))
2023

lms/envs/common.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2040,6 +2040,7 @@
20402040

20412041
# API Documentation
20422042
'drf_yasg',
2043+
'drf_spectacular',
20432044

20442045
# edx-drf-extensions
20452046
'csrf.apps.CsrfAppConfig', # Enables frontend apps to retrieve CSRF tokens.
@@ -2125,6 +2126,18 @@
21252126
'DEEP_LINKING': True,
21262127
}
21272128

2129+
###################### drf-spectacular (LMS enrollment schema) ######################
2130+
SPECTACULAR_SETTINGS = {
2131+
'TITLE': 'LMS Enrollment API',
2132+
'VERSION': '0.1.0',
2133+
'SERVE_INCLUDE_SCHEMA': False,
2134+
'PREPROCESSING_HOOKS': ['lms.lib.spectacular.lms_api_filter'],
2135+
'SCHEMA_PATH_PREFIX': '/api/enrollment',
2136+
'SCHEMA_PATH_PREFIX_TRIM': '/api/enrollment',
2137+
# SERVERS is environment-specific (LMS_ROOT_URL differs per env) and is
2138+
# set in devstack.py / production.py.
2139+
}
2140+
21282141
######################### MARKETING SITE ###############################
21292142

21302143
MKTG_URL_LINK_MAP.update({ # noqa: F405

lms/envs/devstack.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,11 @@ def should_show_debug_toolbar(request): # pylint: disable=missing-function-docs
582582
'COMPLETE',
583583
]
584584

585+
###################### drf-spectacular (LMS enrollment schema) ######################
586+
SPECTACULAR_SETTINGS['SERVERS'] = [ # noqa: F405
587+
{'url': LMS_ROOT_URL, 'description': 'Local'}, # noqa: F405
588+
]
589+
585590
################# New settings must go ABOVE this line #################
586591
########################################################################
587592
# See if the developer has any local overrides.

lms/envs/production.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,11 @@ def get_env_setting(setting):
397397
MIDDLEWARE.extend(_YAML_TOKENS.get('EXTRA_MIDDLEWARE_CLASSES', [])) # noqa: F405
398398

399399

400+
###################### drf-spectacular (LMS enrollment schema) ######################
401+
SPECTACULAR_SETTINGS['SERVERS'] = [ # noqa: F405
402+
{'url': LMS_ROOT_URL, 'description': 'Local'}, # noqa: F405
403+
]
404+
400405
#######################################################################################################################
401406
#### DERIVE ANY DERIVED SETTINGS
402407
####

lms/lib/spectacular.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Helper functions for drf-spectacular (LMS schema)."""
2+
3+
import re
4+
5+
6+
def lms_api_filter(endpoints):
7+
"""
8+
Pre-processing hook: keep only enrollment v2 endpoints tagged for the SDK.
9+
"""
10+
filtered = []
11+
ENROLLMENT_PATH_PATTERN = re.compile(r"^/api/enrollment/v\d+/")
12+
13+
for path, path_regex, method, callback in endpoints:
14+
if ENROLLMENT_PATH_PATTERN.match(path):
15+
filtered.append((path, path_regex, method, callback))
16+
17+
return filtered

lms/urls.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from django.urls import include, path, re_path
1111
from django.utils.translation import gettext_lazy as _
1212
from django.views.generic.base import RedirectView
13+
from drf_spectacular.views import SpectacularAPIView
1314
from edx_api_doc_tools import make_docs_urls
1415
from edx_django_utils.plugins import get_plugin_url_patterns
1516
from submissions import urls as submissions_urls
@@ -1068,3 +1069,8 @@
10681069
urlpatterns += [
10691070
path('xqueue/', include((submissions_urls, 'submissions'), namespace='submissions')),
10701071
]
1072+
1073+
# LMS API schema for openedx-platform-sdk generation.
1074+
urlpatterns += [
1075+
path('lms-api/schema/', SpectacularAPIView.as_view(), name='lms-schema'),
1076+
]

openedx/envs/common.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,7 @@ def add_optional_apps(optional_apps, installed_apps):
836836
'registration_validation': '30/minute',
837837
'high_service_user': '2000/minute',
838838
},
839+
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
839840
}
840841

841842
# .. setting_name: REGISTRATION_VALIDATION_RATELIMIT

0 commit comments

Comments
 (0)