1919from cms .djangoapps .import_from_modulestore import api
2020from cms .djangoapps .import_from_modulestore .models import Import
2121from cms .djangoapps .import_from_modulestore .permissions import IsImportAuthor
22- from cms .djangoapps .import_from_modulestore .views .v0 .serializers import CourseToLibraryImportSerializer
22+ from cms .djangoapps .import_from_modulestore .views .v0 .serializers import ImportBlocksSerializer , ImportSerializer
2323from openedx .core .djangoapps .content_libraries .api import ContentLibrary
2424from openedx .core .lib .api .authentication import BearerAuthenticationAllowInactiveUser
25- from .serializers import ImportBlocksSerializer
2625
2726
2827class ImportBlocksView (APIView ):
2928 """
3029 Import blocks from a course to a library.
30+
31+ **Example Request**
32+ POST /api/import_from_modulestore/v0/import_blocks/
33+
34+ **Example request data**
35+ ```
36+ {
37+ "usage_ids": ["block-v1:org+course+run+type@problem+block@12345"],
38+ "target_library": "lib:org:test",
39+ "import_uuid": "78df3b2c-4e5a-4d6b-8c7e-1f2a3b4c5d6e",
40+ "composition_level": "xblock",
41+ "override": false
42+ }
43+ ```
44+
45+ **POST Parameters**
46+ - usage_ids (list): A list of usage IDs of the blocks to be imported.
47+ - target_library (str): The library to which the blocks will be imported.
48+ - import_uuid (str): The UUID of the import task.
49+ - composition_level (str): The composition level of the blocks to be imported.
50+ - override (bool): Whether to override existing blocks in the library.
51+
52+ **Responses**
53+ - 200: Import blocks from a course to a library task successfully started.
54+ - 400: Invalid request data.
55+ - 401: Unauthorized.
56+ - 403: Forbidden, request user is not the author of the received import.
57+ - 404: Import not found.
58+
59+ **Example Response**:
60+ ```
61+ {
62+ "status": "success"
63+ }
64+ ```
3165 """
3266
3367 serializer_class = ImportBlocksSerializer
@@ -42,54 +76,70 @@ class ImportBlocksView(APIView):
4276 def post (self , request , * args , ** kwargs ):
4377 """
4478 Import blocks from a course to a library.
45- API endpoint: POST /api/import_from_modulestore/v0/import_blocks/
46- Request:
47- {
48- "usage_ids": ["block-v1:org+course+run+type@problem+block@12345"],
49- "import_uuid": "78df3b2c-4e5a-4d6b-8c7e-1f2a3b4c5d6e",
50- "composition_level": "xblock",
51- "override": false
52- }
53- Response:
54- {
55- "status": "success"
56- }
5779 """
58- data = self .serializer_class (data = request .data )
59- data .is_valid (raise_exception = True )
80+ serializer = self .serializer_class (data = request .data )
81+ serializer .is_valid (raise_exception = True )
82+
83+ library_key = LibraryLocatorV2 .from_string (serializer .validated_data ['target_library' ])
84+ try :
85+ content_library = ContentLibrary .objects .get_by_key (library_key )
86+ except ContentLibrary .DoesNotExist :
87+ return Response (status = status .HTTP_404_NOT_FOUND )
6088
6189 api .import_course_staged_content_to_library (
62- usage_ids = data .validated_data ['usage_ids' ],
63- import_uuid = data .validated_data ['import_uuid' ],
90+ usage_ids = serializer .validated_data ['usage_ids' ],
91+ import_uuid = serializer .validated_data ['import_uuid' ],
92+ target_learning_package_id = content_library .learning_package_id ,
6493 user_id = request .user .pk ,
65- composition_level = data .validated_data ['composition_level' ],
66- override = data .validated_data ['override' ],
94+ composition_level = serializer .validated_data ['composition_level' ],
95+ override = serializer .validated_data ['override' ],
6796 )
6897 return Response ({'status' : 'success' })
6998
7099
71100class CreateCourseToLibraryImportView (CreateAPIView ):
72101 """
73- **Use Case**
74- Allows to create course to library import.
102+ Create course to library import.
103+
75104 **Example Request**
76- POST /api/import_from_modulestore/v0/create_import/<content_library_id>/
77- **POST Parameters**
78- * course_ids (list) - A list of course IDs whose content will be saved
79- in Staged Content for further import.
80- **POST Response Values**
81- If the request is successful, an HTTP 201 "Created" response
82- is returned with the newly created Import details.
83- The HTTP 201 response has the following values.
105+ POST /api/import_from_modulestore/v0/create_import/
106+
107+ **Example request data**
108+ ```
84109 {
85- "course_ids": ["course-v1:edX+DemoX+Demo_Course", "course-v1:edX+DemoX+Demo_Course2"],
86- "status": "pending",
87- "library_key": "lib:edX:1",
88- "uuid": "89b71d29-2135-4cf2-991d-e4e13b5a959a"
110+ "course_ids": ["course-v1:edX+DemoX+Demo_Course", "course-v1:edX+M12+2025"],
89111 }
112+ ```
113+
114+ **POST Parameters**
115+ - course_ids (list): A list of course IDs for which imports will be created
116+ and content will be saved to the Staged Content.
117+
118+ **Responses**
119+ - 200: Imports created successfully and saving content to Staged Content started.
120+ - 400: Invalid request data.
121+ - 401: Unauthorized.
122+ - 403: Forbidden.
123+ - 404: ContentLibrary not found.
124+
125+ **Example Response**:
126+ ```
127+ [
128+ {
129+ "course_id": "course-v1:edX+DemoX+Demo_Course",
130+ "status": "staging",
131+ "uuid": "89b71d29-2135-4cf2-991d-e4e13b5a959a"
132+ },
133+ {
134+ "course_id": "course-v1:edX+M12+2025",
135+ "status": "not_started",
136+ "uuid": "0782921a-4b56-4972-aa3a-edd1c99de85f"
137+ },
138+ ]
139+ ```
90140 """
91141
92- serializer_class = CourseToLibraryImportSerializer
142+ serializer_class = ImportSerializer
93143
94144 permission_classes = (IsAdminUser ,)
95145 authentication_classes = (
@@ -98,45 +148,36 @@ class CreateCourseToLibraryImportView(CreateAPIView):
98148 SessionAuthenticationAllowInactiveUser ,
99149 )
100150
101- def get_serializer_context (self ) -> dict :
102- """
103- Add library_id to the serializer context.
104- """
105- context = super ().get_serializer_context ()
106- context ['content_library_id' ] = self .kwargs ['content_library_id' ]
107- return context
108-
109151 def post (self , request , * args , ** kwargs ):
110152 """
111153 Create course to library import.
112154 """
113- library_key = LibraryLocatorV2 .from_string (self .kwargs ['content_library_id' ])
114-
115- try :
116- content_library = ContentLibrary .objects .get_by_key (library_key )
117- except ContentLibrary .DoesNotExist :
118- return Response (status = status .HTTP_404_NOT_FOUND )
119155 serializer = self .get_serializer (data = request .data )
120156 serializer .is_valid (raise_exception = True )
121157
122- result = []
123- for course_id in serializer .validated_data ['course_ids' ]:
124- import_event = api .create_import (course_id , request .user .pk , content_library .learning_package .id )
125- result .append ({
126- 'uuid' : str (import_event .uuid ),
127- 'course_id' : str (import_event .source_key ),
128- 'status' : import_event .get_status_display (),
129- 'library_key' : str (import_event .target .contentlibrary .library_key )
130- })
131- return Response ({'result' : result }, status = status .HTTP_201_CREATED )
158+ result = (
159+ api .create_import (course_id , request .user .pk )
160+ for course_id in serializer .validated_data ['course_ids' ]
161+ )
162+
163+ serializer = self .get_serializer (result , many = True )
164+ return Response (serializer .data , status = status .HTTP_201_CREATED )
132165
133166
134167class GetCourseStructureToLibraryImportView (RetrieveAPIView ):
135168 """
136- **Use Case**
137- Get the course structure saved when creating the import.
169+ Get the course structure saved when creating the import.
170+
138171 **Example Request**
139- GET /api/import_from_modulestore/v0/get_import/{course-to-library-uuid}/
172+ GET /api/import_from_modulestore/v0/get_import/{import_uuid}/
173+
174+ **Responses**
175+ - 200: Course structure retrieved successfully.
176+ - 400: Invalid request data.
177+ - 401: Unauthorized.
178+ - 403: Forbidden.
179+ - 404: Import not found.
180+
140181 **GET Response Values**
141182 The query returns a list of hierarchical structures of
142183 courses that are related to the import in the format:
@@ -202,7 +243,7 @@ class GetCourseStructureToLibraryImportView(RetrieveAPIView):
202243
203244 queryset = Import .objects .all ()
204245 lookup_field = 'uuid'
205- lookup_url_kwarg = 'course_to_lib_uuid '
246+ lookup_url_kwarg = 'import_uuid '
206247
207248 permission_classes = (IsAdminUser ,)
208249 authentication_classes = (
@@ -215,7 +256,7 @@ def get(self, request, *args, **kwargs) -> Response:
215256 """
216257 Get the course structure saved when creating the import.
217258 """
218- import_event = get_object_or_404 (Import , uuid = self .kwargs ['course_to_lib_uuid ' ])
259+ import_event = get_object_or_404 (Import , uuid = self .kwargs ['import_uuid ' ])
219260 staged_content = [
220261 staged_content_for_import .staged_content
221262 for staged_content_for_import in import_event .staged_content_for_import .all ()
0 commit comments