From b9a6925ad818ed8e35d93b7245b76ef1e359c220 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Tue, 30 Jun 2026 09:36:39 +0530 Subject: [PATCH 1/2] OpenConceptLab/ocl_issues#2501 | Expansion processing API --- core/collections/models.py | 8 ++++ core/collections/urls.py | 5 +++ core/collections/views.py | 22 ++++++++- core/common/tasks.py | 4 +- core/integration_tests/tests_collections.py | 50 +++++++++++++++++++++ 5 files changed, 85 insertions(+), 4 deletions(-) diff --git a/core/collections/models.py b/core/collections/models.py index aa47e59d..6babecf0 100644 --- a/core/collections/models.py +++ b/core/collections/models.py @@ -1635,6 +1635,14 @@ def update_diffs(rel): return diff + def clear_processing(self, full_save=False): + if self.is_processing: + self.is_processing = False + if full_save: + self.save() + else: + self.save(update_fields=['is_processing']) + class ExpansionParameters: ACTIVE = 'activeOnly' diff --git a/core/collections/urls.py b/core/collections/urls.py index 708d3516..c0af34de 100644 --- a/core/collections/urls.py +++ b/core/collections/urls.py @@ -151,6 +151,11 @@ views.CollectionVersionExpansionView.as_view(), name='collection-version-expansion-detail' ), + path( + '//expansions//processing/', + views.CollectionVersionExpansionProcessingView.as_view(), + name='collection-version-expansion-processing' + ), path( '//expansions//resolved-repo-updates/', views.CollectionVersionExpansionResolvedRepoUpdatesView.as_view(), diff --git a/core/collections/views.py b/core/collections/views.py index d141c5e4..8a9fa749 100644 --- a/core/collections/views.py +++ b/core/collections/views.py @@ -47,7 +47,7 @@ ConceptContainerProcessingMixin) from core.common.permissions import ( CanViewConceptDictionary, CanEditConceptDictionary, HasAccessToVersionedObject, - CanViewConceptDictionaryVersion + CanViewConceptDictionaryVersion, HasOwnership ) from core.common.serializers import TaskSerializer from core.common.swagger_parameters import q_param, compress_header, page_param, verbose_param, \ @@ -1308,3 +1308,23 @@ def get_results(self): ) def post(self, _): return Response(self.get_results(), status=status.HTTP_200_OK) + + +class CollectionVersionExpansionProcessingView(CollectionVersionExpansionBaseView): + def get_permissions(self): + if self.request.method == 'POST': + return [HasOwnership(), IsAuthenticated()] + + return [CanViewConceptDictionary(), ] + + def get(self, request, *args, **kwargs): # pylint: disable=unused-argument + expansion = self.get_object() + response = Response(status=200) + response.content = expansion.is_processing + return response + + def post(self, request, *args, **kwargs): # pylint: disable=unused-argument + expansion = self.get_object() + expansion.clear_processing() + + return Response(status=status.HTTP_200_OK) diff --git a/core/common/tasks.py b/core/common/tasks.py index e9363415..85919345 100644 --- a/core/common/tasks.py +++ b/core/common/tasks.py @@ -431,9 +431,7 @@ def seed_children_to_expansion(expansion_id, index=True, force_reevaluate=False) expansion = Expansion.objects.filter(id=expansion_id).first() if expansion: expansion.seed_children(index=index, force_reevaluate=force_reevaluate) - if expansion.is_processing: - expansion.is_processing = False - expansion.save() + expansion.clear_processing(True) @app.task diff --git a/core/integration_tests/tests_collections.py b/core/integration_tests/tests_collections.py index 1a2316cb..fa818b6a 100644 --- a/core/integration_tests/tests_collections.py +++ b/core/integration_tests/tests_collections.py @@ -4094,6 +4094,56 @@ def test_get(self): self.assertEqual([expansion['mnemonic'] for expansion in response.data], ['e2-head', 'e1-v1', 'e1-head']) +class CollectionVersionExpansionProcessingViewTest(OCLAPITestCase): + def setUp(self): + super().setUp() + self.collection = OrganizationCollectionFactory() + self.expansion = ExpansionFactory(collection_version=self.collection) + self.token = self.collection.created_by.get_token() + + def test_get_200(self): + response = self.client.get( + self.expansion.url + 'processing/', + HTTP_AUTHORIZATION=f'Token {self.token}' + ) + + self.assertEqual(response.status_code, 200) + self.assertEqual(response.content, b'False') + + self.expansion.is_processing = True + self.expansion.save(update_fields=['is_processing']) + + response = self.client.get( + self.expansion.url + 'processing/', + HTTP_AUTHORIZATION=f'Token {self.token}' + ) + + self.assertEqual(response.status_code, 200) + self.assertEqual(response.content, b'True') + + def test_post_200(self): + self.expansion.is_processing = True + self.expansion.save(update_fields=['is_processing']) + + response = self.client.post( + self.expansion.url + 'processing/', + HTTP_AUTHORIZATION=f'Token {self.token}' + ) + + self.assertEqual(response.status_code, 200) + self.expansion.refresh_from_db() + self.assertFalse(self.expansion.is_processing) + + response = self.client.post( + self.expansion.url + 'processing/', + HTTP_AUTHORIZATION=f'Token {self.token}' + ) + + self.assertEqual(response.status_code, 200) + self.expansion.refresh_from_db() + self.assertFalse(self.expansion.is_processing) + + class CollectionVersionExpansionResolvedRepoUpdatesViewTest(OCLAPITestCase): def setUp(self): super().setUp() From f671faec0cde5e8b8dd4f55320ec55747f5bac92 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Wed, 1 Jul 2026 10:33:24 +0530 Subject: [PATCH 2/2] OpenConceptLab/ocl_issues#2501 | expansion persist to set processing True --- core/collections/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/core/collections/models.py b/core/collections/models.py index 6babecf0..be2ec682 100644 --- a/core/collections/models.py +++ b/core/collections/models.py @@ -1575,6 +1575,7 @@ def persist(cls, index, **kwargs): temp_version = not bool(expansion.mnemonic) if temp_version: expansion.mnemonic = generate_temp_version() + expansion.is_processing = True expansion.clean() expansion.full_clean() expansion.save()