feat: axim api improvements#38755
Open
Faraz32123 wants to merge 10 commits into
Open
Conversation
| return response_data | ||
|
|
||
| except InvalidEnrollmentAttribute as error: | ||
| raise ValidationError(str(error)) from error |
| except InvalidEnrollmentAttribute as error: | ||
| raise ValidationError(str(error)) from error | ||
| except EnrollmentNotAllowed as error: | ||
| raise PermissionDenied(str(error)) from error |
148eb3c to
21b6e30
Compare
Contributor
|
@Faraz32123, there is not a lot of context in the description or in the commit messages about WHY decisions are made. I know that for example the xblock API went from V0 to V1 but it's unclear to me what prevents us from making updates to the existing api enpoint requiring us to introduce a new one. Can you make sure the relevant commit message and the PR description have this reasoning so we can find it in the future. The ADR is the broad guide but we still need to provide the specific reasoning for given changes to make it easier for us to understand later. |
Standardize HomePageCoursesView Co-authored-by: Taimoor Ahmed <taimoor.ahmed@A006-01711.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: apply ADRs to home v1 apis * feat: apply ADR 0029 error envelope to home v3 viewset Wires HomeViewSet (v3) into openedx/core/lib/api/exceptions's standardized_error_exception_handler via a v3-local StandardizedErrorMixin that overrides DRF's per-view get_exception_handler. Project-wide EXCEPTION_HANDLER setting is intentionally left unchanged so v0/v1/v2 endpoints are unaffected. * feat: refactor mixin so that both v3 and v4 can use it
21b6e30 to
b8df48f
Compare
…d APIs (#38773) * feat: apply ADR 0036 to Xblock v1 (?view=minimal) Adds a ``?view=minimal`` query parameter on ``XblockViewSet.retrieve`` that filters the (tree-shaped) xblock response down to a small set of structural fields — id, display_name, category, children, has_children, studio_url — dropping heavy/contextual fields such as data, metadata, fields, student_view_data, edited_on, published. Default response shape is unchanged (full xblock payload) to avoid breaking the existing Studio frontend. The pre-existing ``?fields=...`` query parameter retains its legacy "type of response" semantics (?fields=graderType, ?fields=ancestorInfo, ?fields=customReadToken); ADR 0036's CSV-subset interpretation is deferred to a future API version to avoid breaking those callers. Adds 4 regression tests covering: default response untouched, minimal strips heavy fields, minimal keeps structural fields, minimal is a no-op for non-dict response bodies (legacy ?fields=graderType path). * feat: apply ADR 0036 to CourseHome v3 (?fields= on list action) The v3 ``HomeViewSet.list`` action returns a wide ``StudioHomeSerializer`` payload with ~25 top-level keys (courses, archived_courses, libraries, allowed_organizations, allowed_organizations_for_libraries, plus Studio settings). Adds a ``?fields=`` query parameter so clients can request a subset of those keys explicitly. The flat-list ``courses`` and ``libraries`` actions are out of scope (each returns a single-key dict wrapping a list of small items — no nested or wide structure to filter). Adds a shared ``apply_field_selection`` helper to ``v3/utils.py`` so future v3 viewsets can opt into the same convention without re-implementing it. Adds 2 regression tests: default keeps all keys, ``?fields=courses,libraries`` restricts to exactly those keys. * docs: audit CourseHome v4 against ADR 0036 (out of scope) Adds an ADR 0036 entry to ``HomeCoursesViewSet``'s compliance list explicitly marking this endpoint as out of scope. Rationale: the v4 home endpoint returns a flat paginated list governed by ADR 0032 (DefaultPagination 7-field envelope). ADR 0036 excludes flat lists from its ``?view=`` / ``?depth=`` / minimal-by-default requirements — those apply to tree-shaped responses or wide flat objects with embedded sub-objects. Each course item is a thin 9-field record with no nested children, no embedded sub-objects, and no tree structure to bound. Per-item ``?fields=`` subset filtering remains a possible follow-up (would require a dynamic-fields serializer mixin and per-field schema documentation) but is deferred to keep the v4 contract stable for the existing Studio frontend. * feat: apply ADR 0036 to Enrollment v2 (?view=minimal flattens course_details) Each enrollment record returned by the v2 ``EnrollmentViewSet.list`` and ``EnrollmentRetrieveView.get`` actions embeds a full ``course_details`` sub-object (which itself includes a ``course_modes`` list and other heavy course-overview fields). Server-to-server callers and AI agents that only need to know which courses a user is enrolled in shouldn't have to parse the embedded sub-object on every row. Adds a ``?view=minimal`` query parameter on both actions that collapses the embedded ``course_details`` to a single ``course_id`` string. The enrollment-level fields (``created``, ``mode``, ``is_active``, ``user``) are preserved. Default response shape is unchanged. Adds 2 regression tests (mocked, MongoDB-free): default list keeps the full shape, ``?view=minimal`` collapses each row's course_details to a flat course_id and the heavy fields are dropped. * feat: apply ADR 0036 to Course Detail v3 (?view=minimal + ?fields=) The v3 ``CourseDetailsViewSet.retrieve`` action returns a wide ``CourseDetailsSerializer`` payload with ~40 top-level fields plus a nested ``instructor_info`` sub-object (instructor names, bios, image URLs) and a ``learning_info`` long-form list. The default full payload is preserved; two new opt-in query parameters apply ADR 0036: * ``?view=minimal`` drops heavy fields (overview, syllabus, description, short_description, instructor_info, learning_info, banner_image_name / banner_image_asset_path, video_thumbnail assets, license) — leaving only identification (course_id, org, run, title, subtitle, language), schedule (start_date, end_date, enrollment_start, enrollment_end, certificate_available_date), and flags (self_paced, certificates_display_behavior, has_changes). * ``?fields=a,b,c`` keeps an explicit CSV subset of top-level keys. Composes with ``?view=minimal`` — the preset is applied first, then the explicit subset. Reuses ``apply_field_selection`` from ``v3/utils.py`` (introduced in the CourseHome v3 commit) so the convention is consistent across v3. Adds 3 regression tests (mocked, MongoDB-free): default keeps all fields, ?view=minimal drops the heavy/embedded ones and keeps identification/schedule/flags, ?fields=course_id,title restricts to exactly those keys. * docs: audit AuthorGrading v3 against ADR 0036 (largely out of scope) Adds an ADR 0036 entry to ``AuthoringGradingViewSet``'s compliance list. Rationale: the v3 grading response is a single top-level ``graders`` list of small fixed-shape objects (type, min_count, drop_count, short_label, weight, id) — no tree nesting, no embedded sub-objects, no ``children`` field, no wide flat object. ``?view=minimal`` and ``?fields=`` would have no fields to drop; the only ADR 0036 concern that applies is anti-pattern #3 (unbounded child list). In practice each course has ≤8 graders (Homework, Lab, Exam, etc.) and the update flow is exercised only by course-authoring staff, so the real-world payload is always small. The hard cap is enforced upstream by ``CourseGradingModel.update_from_json``; documented as a note rather than re-implemented at the view layer.
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.
Summary
This PR applies a set of API standardization ADRs (0025–0029) to a batch of
contentstore endpoints, introducing new versioned API endpoints rather than
modifying existing ones.
ADRs applied: see related ADR PR #38738
Why new API versions instead of updating existing endpoints?
The ADRs mandate structural changes that are breaking for existing consumers:
ADR 0029 (standardized error envelope): Changes the error response format
from the legacy
{"developer_message": ..., "error_code": ...}shape to astructured RFC 7807 envelope (
type,title,status,detail,instance).Any client that parses error responses from the existing endpoint would break.
ADR 0028 (ViewSet + DefaultRouter): Replaces
APIViewwith aViewSetregistered via
DefaultRouter, which generates slightly different URL patterns(trailing slash, router-managed routing). Existing URL patterns and named routes
are preserved in the old version.
ADR 0026 (explicit auth classes): Standardizes authentication — removes
deprecated
BearerAuthentication. While not strictly breaking for JWT/sessionclients, Bearer-only consumers would lose access.
Introducing new versions allows existing consumers to stay on the current
endpoint and migrate on their own timeline, rather than absorbing a silent
breaking change.
Changes in this PR
GET/POST /api/contentstore/v0/xblock/GET/POST/PATCH/DELETE /api/contentstore/v1/xblock/{usage_key}/GET /api/contentstore/v1/home/GET /api/contentstore/v3/home/GET /api/contentstore/v2/home/GET /api/contentstore/v4/home/GET/PUT /api/contentstore/v1/course_details/{id}/GET/PUT /api/contentstore/v3/course_details/{course_key}/POST /api/contentstore/v0/grading/{id}/PATCH /api/contentstore/v3/authoring_grading/{course_key}/GET/POST /api/contentstore/v0/enrollments/GET/POST /api/contentstore/v1/enrollments/Testing
Each new endpoint has a dedicated test module covering: