From a55c1ddabf971b797ffa67134b0780aeaeec2bfd Mon Sep 17 00:00:00 2001 From: Kyle McCormick Date: Fri, 13 Feb 2026 15:39:05 -0500 Subject: [PATCH] chore: Switch to new openedx-learning import paths (#38004) Upgrades openedx-learning from 0.31.0 to 0.32.0, incorporating a major openedx-learning Python API restructuring: ca0b3eb --- ...squashed_0015_switch_to_openedx_content.py | 20 +++---- ...ontextlinksstatus_publishableentitylink.py | 14 ++--- .../migrations/0010_container_link_models.py | 10 ++-- cms/djangoapps/contentstore/models.py | 6 +-- .../rest_api/v0/views/api_heartbeat.py | 4 +- .../rest_api/v1/views/tests/test_home.py | 4 +- .../views/tests/test_clipboard_paste.py | 2 +- .../modulestore_migrator/api/read_api.py | 4 +- .../modulestore_migrator/api/write_api.py | 2 +- cms/djangoapps/modulestore_migrator/models.py | 2 +- .../rest_api/v1/serializers.py | 2 +- cms/djangoapps/modulestore_migrator/tasks.py | 32 +++++------ .../modulestore_migrator/tests/test_api.py | 10 ++-- .../modulestore_migrator/tests/test_tasks.py | 52 +++++++++--------- cms/envs/common.py | 8 +-- cms/envs/mock.yml | 1 - lms/envs/common.py | 9 ++-- openedx/core/djangoapps/content/search/api.py | 10 ++-- .../djangoapps/content/search/documents.py | 10 ++-- .../content/search/tests/test_api.py | 12 ++--- .../content/search/tests/test_documents.py | 4 +- .../content_libraries/api/blocks.py | 54 +++++++++---------- .../content_libraries/api/collections.py | 24 ++++----- .../api/container_metadata.py | 14 ++--- .../content_libraries/api/containers.py | 50 ++++++++--------- .../content_libraries/api/exceptions.py | 2 +- .../content_libraries/api/libraries.py | 29 +++++----- .../content_libraries/library_context.py | 4 +- .../djangoapps/content_libraries/models.py | 2 +- .../content_libraries/rest_api/blocks.py | 6 +-- .../content_libraries/rest_api/collections.py | 10 ++-- .../content_libraries/rest_api/containers.py | 10 ++-- .../content_libraries/rest_api/serializers.py | 2 +- .../content_libraries/signal_handlers.py | 4 +- .../djangoapps/content_libraries/tasks.py | 10 ++-- .../content_libraries/tests/test_api.py | 26 ++++----- .../tests/test_content_libraries.py | 6 +-- .../tests/test_views_collections.py | 2 +- .../migrations/0003_olx_unicode.py | 6 +-- .../core/djangoapps/content_staging/models.py | 2 +- .../core/djangoapps/content_tagging/api.py | 6 +-- .../core/djangoapps/content_tagging/auth.py | 2 +- .../djangoapps/content_tagging/models/base.py | 2 +- .../content_tagging/rest_api/v1/filters.py | 2 +- .../rest_api/v1/serializers.py | 2 +- .../rest_api/v1/tests/test_views.py | 6 +-- .../content_tagging/rest_api/v1/urls.py | 6 +-- .../content_tagging/rest_api/v1/views.py | 4 +- .../core/djangoapps/content_tagging/rules.py | 2 +- .../core/djangoapps/content_tagging/tasks.py | 2 +- .../content_tagging/tests/test_api.py | 2 +- .../tests/test_objecttag_export_helpers.py | 2 +- .../content_tagging/tests/test_rules.py | 4 +- .../content_tagging/tests/test_tasks.py | 8 +-- .../core/djangoapps/content_tagging/types.py | 2 +- .../core/djangoapps/content_tagging/utils.py | 2 +- openedx/core/djangoapps/xblock/api.py | 8 +-- .../xblock/runtime/learning_core_runtime.py | 12 ++--- .../core/lib/xblock_serializer/test_api.py | 2 +- requirements/constraints.txt | 3 +- requirements/edx/base.txt | 2 +- requirements/edx/development.txt | 2 +- requirements/edx/doc.txt | 2 +- requirements/edx/testing.txt | 2 +- setup.cfg | 9 ++-- 65 files changed, 291 insertions(+), 286 deletions(-) diff --git a/cms/djangoapps/contentstore/migrations/0001_squashed_0015_switch_to_openedx_content.py b/cms/djangoapps/contentstore/migrations/0001_squashed_0015_switch_to_openedx_content.py index f65c9a8cd3..b39c898d56 100644 --- a/cms/djangoapps/contentstore/migrations/0001_squashed_0015_switch_to_openedx_content.py +++ b/cms/djangoapps/contentstore/migrations/0001_squashed_0015_switch_to_openedx_content.py @@ -3,8 +3,8 @@ import django.db.migrations.operations.special import django.db.models.deletion import opaque_keys.edx.django.models -import openedx_learning.lib.fields -import openedx_learning.lib.validators +import openedx_django_lib.fields +import openedx_django_lib.validators import uuid from django.conf import settings from django.db import migrations, models @@ -107,8 +107,8 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('context_key', opaque_keys.edx.django.models.CourseKeyField(help_text='Linking status for course context key', max_length=255, unique=True)), ('status', models.CharField(choices=[('pending', 'Pending'), ('processing', 'Processing'), ('failed', 'Failed'), ('completed', 'Completed')], help_text='Status of links in given learning context/course.', max_length=20)), - ('created', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])), - ('updated', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])), + ('created', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])), + ('updated', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])), ], options={ 'verbose_name': 'Learning Context Links status', @@ -121,13 +121,13 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True, verbose_name='UUID')), ('upstream_usage_key', opaque_keys.edx.django.models.UsageKeyField(help_text='Upstream block usage key, this value cannot be null and useful to track upstream library blocks that do not exist yet', max_length=255)), - ('upstream_context_key', openedx_learning.lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', max_length=500)), + ('upstream_context_key', openedx_django_lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', max_length=500)), ('downstream_usage_key', opaque_keys.edx.django.models.UsageKeyField(max_length=255, unique=True)), ('downstream_context_key', opaque_keys.edx.django.models.CourseKeyField(db_index=True, max_length=255)), ('version_synced', models.IntegerField()), ('version_declined', models.IntegerField(blank=True, null=True)), - ('created', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])), - ('updated', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])), + ('created', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])), + ('updated', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])), ('upstream_block', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='links', to='openedx_content.component')), ], options={ @@ -140,13 +140,13 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True, verbose_name='UUID')), - ('upstream_context_key', openedx_learning.lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', max_length=500)), + ('upstream_context_key', openedx_django_lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', max_length=500)), ('downstream_usage_key', opaque_keys.edx.django.models.UsageKeyField(max_length=255, unique=True)), ('downstream_context_key', opaque_keys.edx.django.models.CourseKeyField(db_index=True, max_length=255)), ('version_synced', models.IntegerField()), ('version_declined', models.IntegerField(blank=True, null=True)), - ('created', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])), - ('updated', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])), + ('created', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])), + ('updated', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])), ('upstream_container_key', opaque_keys.edx.django.models.ContainerKeyField(help_text='Upstream block key (e.g. lct:...), this value cannot be null and is useful to track upstream library blocks that do not exist yet or were deleted.', max_length=255)), ('upstream_container', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='links', to='openedx_content.container')), ], diff --git a/cms/djangoapps/contentstore/migrations/0009_learningcontextlinksstatus_publishableentitylink.py b/cms/djangoapps/contentstore/migrations/0009_learningcontextlinksstatus_publishableentitylink.py index 84b80cd633..9f32a904eb 100644 --- a/cms/djangoapps/contentstore/migrations/0009_learningcontextlinksstatus_publishableentitylink.py +++ b/cms/djangoapps/contentstore/migrations/0009_learningcontextlinksstatus_publishableentitylink.py @@ -4,8 +4,8 @@ import uuid import django.db.models.deletion import opaque_keys.edx.django.models -import openedx_learning.lib.fields -import openedx_learning.lib.validators +import openedx_django_lib.fields +import openedx_django_lib.validators from django.db import migrations, models @@ -39,8 +39,8 @@ class Migration(migrations.Migration): max_length=20, ), ), - ('created', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])), - ('updated', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])), + ('created', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])), + ('updated', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])), ], options={ 'verbose_name': 'Learning Context Links status', @@ -61,7 +61,7 @@ class Migration(migrations.Migration): ), ( 'upstream_context_key', - openedx_learning.lib.fields.MultiCollationCharField( + openedx_django_lib.fields.MultiCollationCharField( db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', @@ -72,8 +72,8 @@ class Migration(migrations.Migration): ('downstream_context_key', opaque_keys.edx.django.models.CourseKeyField(db_index=True, max_length=255)), ('version_synced', models.IntegerField()), ('version_declined', models.IntegerField(blank=True, null=True)), - ('created', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])), - ('updated', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])), + ('created', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])), + ('updated', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])), ( 'upstream_block', models.ForeignKey( diff --git a/cms/djangoapps/contentstore/migrations/0010_container_link_models.py b/cms/djangoapps/contentstore/migrations/0010_container_link_models.py index 8d42ad9614..9ec26d84ed 100644 --- a/cms/djangoapps/contentstore/migrations/0010_container_link_models.py +++ b/cms/djangoapps/contentstore/migrations/0010_container_link_models.py @@ -3,8 +3,8 @@ import uuid import django.db.models.deletion import opaque_keys.edx.django.models -import openedx_learning.lib.fields -import openedx_learning.lib.validators +import openedx_django_lib.fields +import openedx_django_lib.validators from django.db import migrations, models @@ -40,13 +40,13 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True, verbose_name='UUID')), - ('upstream_context_key', openedx_learning.lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', max_length=500)), + ('upstream_context_key', openedx_django_lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', max_length=500)), ('downstream_usage_key', opaque_keys.edx.django.models.UsageKeyField(max_length=255, unique=True)), ('downstream_context_key', opaque_keys.edx.django.models.CourseKeyField(db_index=True, max_length=255)), ('version_synced', models.IntegerField()), ('version_declined', models.IntegerField(blank=True, null=True)), - ('created', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])), - ('updated', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])), + ('created', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])), + ('updated', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])), ('upstream_container_key', opaque_keys.edx.django.models.ContainerKeyField(help_text='Upstream block key (e.g. lct:...), this value cannot be null and is useful to track upstream library blocks that do not exist yet or were deleted.', max_length=255)), ('upstream_container', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='links', to='oel_publishing.container')), ], diff --git a/cms/djangoapps/contentstore/models.py b/cms/djangoapps/contentstore/models.py index a4f2ce3c61..9baa3799ed 100644 --- a/cms/djangoapps/contentstore/models.py +++ b/cms/djangoapps/contentstore/models.py @@ -15,9 +15,9 @@ from django.utils.translation import gettext_lazy as _ from opaque_keys.edx.django.models import ContainerKeyField, CourseKeyField, UsageKeyField from opaque_keys.edx.keys import CourseKey, UsageKey from opaque_keys.edx.locator import LibraryContainerLocator -from openedx_learning.api.authoring import get_published_version -from openedx_learning.api.authoring_models import Component, Container -from openedx_learning.lib.fields import ( +from openedx_content.api import get_published_version +from openedx_content.models_api import Component, Container +from openedx_django_lib.fields import ( immutable_uuid_field, key_field, manual_date_time_field, diff --git a/cms/djangoapps/contentstore/rest_api/v0/views/api_heartbeat.py b/cms/djangoapps/contentstore/rest_api/v0/views/api_heartbeat.py index f322f23609..2a5851f203 100644 --- a/cms/djangoapps/contentstore/rest_api/v0/views/api_heartbeat.py +++ b/cms/djangoapps/contentstore/rest_api/v0/views/api_heartbeat.py @@ -32,13 +32,13 @@ class APIHeartBeatView(DeveloperErrorViewMixin, APIView): **Response Values** If the request is successful, an HTTP 200 "OK" response is returned. - The HTTP 200 response contains a single dict with the "authoring_api_enabled" value "True". + The HTTP 200 response contains a single dict with the "content_api_enabled" value "True". **Example Response** ```json { - "authoring_api_enabled": "True" + "content_api_enabled": "True" } ``` """ diff --git a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py index 72d58fa00d..a155ceb235 100644 --- a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py +++ b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py @@ -10,7 +10,7 @@ from django.conf import settings from django.test import override_settings from django.urls import reverse from opaque_keys.edx.locator import LibraryLocatorV2 -from openedx_learning.api import authoring as authoring_api +from openedx_content import api as content_api from organizations.tests.factories import OrganizationFactory from rest_framework import status @@ -272,7 +272,7 @@ class HomePageLibrariesViewTest(LibraryTestCase): self.url = reverse("cms.djangoapps.contentstore:v1:libraries") # Create a collection to migrate this library to collection_key = "test-collection" - authoring_api.create_collection( + content_api.create_collection( learning_package_id=learning_package.id, key=collection_key, title="Test Collection", diff --git a/cms/djangoapps/contentstore/views/tests/test_clipboard_paste.py b/cms/djangoapps/contentstore/views/tests/test_clipboard_paste.py index 2ca03ccf89..ba6d0b2431 100644 --- a/cms/djangoapps/contentstore/views/tests/test_clipboard_paste.py +++ b/cms/djangoapps/contentstore/views/tests/test_clipboard_paste.py @@ -13,7 +13,7 @@ from openedx_events.content_authoring.signals import ( XBLOCK_UPDATED, ) from openedx_events.tests.utils import OpenEdxEventsTestMixin -from openedx_tagging.core.tagging.models import Tag +from openedx_tagging.models import Tag from organizations.models import Organization from xmodule.modulestore.django import contentstore, modulestore from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, upload_file_to_course, ImmediateOnCommitMixin diff --git a/cms/djangoapps/modulestore_migrator/api/read_api.py b/cms/djangoapps/modulestore_migrator/api/read_api.py index 97d8a78c39..e7d57c8bc4 100644 --- a/cms/djangoapps/modulestore_migrator/api/read_api.py +++ b/cms/djangoapps/modulestore_migrator/api/read_api.py @@ -11,8 +11,8 @@ from opaque_keys.edx.keys import UsageKey from opaque_keys.edx.locator import ( LibraryLocatorV2, LibraryUsageLocatorV2, LibraryContainerLocator ) -from openedx_learning.api.authoring import get_draft_version, get_all_drafts -from openedx_learning.api.authoring_models import ( +from openedx_content.api import get_draft_version, get_all_drafts +from openedx_content.models_api import ( PublishableEntityVersion, PublishableEntity, DraftChangeLogRecord ) from xblock.plugin import PluginMissingError diff --git a/cms/djangoapps/modulestore_migrator/api/write_api.py b/cms/djangoapps/modulestore_migrator/api/write_api.py index 4bef6c9527..a84d5bf11b 100644 --- a/cms/djangoapps/modulestore_migrator/api/write_api.py +++ b/cms/djangoapps/modulestore_migrator/api/write_api.py @@ -5,7 +5,7 @@ from __future__ import annotations from celery.result import AsyncResult from opaque_keys.edx.locator import LibraryLocatorV2 -from openedx_learning.api.authoring import get_collection +from openedx_content.api import get_collection from openedx.core.types.user import AuthUser from openedx.core.djangoapps.content_libraries.api import get_library diff --git a/cms/djangoapps/modulestore_migrator/models.py b/cms/djangoapps/modulestore_migrator/models.py index 11f614c2ed..2dcc6224ca 100644 --- a/cms/djangoapps/modulestore_migrator/models.py +++ b/cms/djangoapps/modulestore_migrator/models.py @@ -11,7 +11,7 @@ from opaque_keys.edx.django.models import ( LearningContextKeyField, UsageKeyField, ) -from openedx_learning.api.authoring_models import ( +from openedx_content.models_api import ( Collection, DraftChangeLog, DraftChangeLogRecord, diff --git a/cms/djangoapps/modulestore_migrator/rest_api/v1/serializers.py b/cms/djangoapps/modulestore_migrator/rest_api/v1/serializers.py index 43a0b03ee3..54d9fb6dd7 100644 --- a/cms/djangoapps/modulestore_migrator/rest_api/v1/serializers.py +++ b/cms/djangoapps/modulestore_migrator/rest_api/v1/serializers.py @@ -5,7 +5,7 @@ Serializers for the Course to Library Import API. from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import LearningContextKey from opaque_keys.edx.locator import LibraryLocatorV2 -from openedx_learning.api.authoring_models import Collection +from openedx_content.models_api import Collection from rest_framework import serializers from user_tasks.models import UserTaskStatus from user_tasks.serializers import StatusSerializer diff --git a/cms/djangoapps/modulestore_migrator/tasks.py b/cms/djangoapps/modulestore_migrator/tasks.py index fe1182716f..1ec72b558f 100644 --- a/cms/djangoapps/modulestore_migrator/tasks.py +++ b/cms/djangoapps/modulestore_migrator/tasks.py @@ -30,8 +30,8 @@ from opaque_keys.edx.locator import ( LibraryLocatorV2, LibraryUsageLocatorV2, ) -from openedx_learning.api import authoring as authoring_api -from openedx_learning.api.authoring_models import ( +from openedx_content import api as content_api +from openedx_content.models_api import ( Collection, Component, ComponentType, @@ -295,8 +295,8 @@ def _import_assets(migration: models.ModulestoreMigration) -> dict[str, int]: continue filename = os.path.basename(old_path) media_type_str = mimetypes.guess_type(filename)[0] or "application/octet-stream" - media_type = authoring_api.get_or_create_media_type(media_type_str) - content_by_filename[filename] = authoring_api.get_or_create_file_content( + media_type = content_api.get_or_create_media_type(media_type_str) + content_by_filename[filename] = content_api.get_or_create_file_content( migration.target_id, media_type.id, data=file_data, @@ -335,7 +335,7 @@ def _import_structure( tuple[Any, _MigratedNode]: A tuple containing: - The first element (`change_log`): the bulk draft change log generated by - `authoring_api.bulk_draft_changes_for`, containing all the imported changes. + `content_api.bulk_draft_changes_for`, containing all the imported changes. - The second element (`root_migrated_node`): a `_MigratedNode` object that represents the mapping between the legacy root node and its newly created Learning Core equivalent. @@ -345,12 +345,12 @@ def _import_structure( used_component_keys=set( LibraryUsageLocatorV2(target_library.key, block_type, block_id) # type: ignore[abstract] for block_type, block_id - in authoring_api.get_components(migration.target.pk).values_list( + in content_api.get_components(migration.target.pk).values_list( "component_type__name", "local_key" ) ), used_container_slugs=set( - authoring_api.get_containers( + content_api.get_containers( migration.target.pk ).values_list("publishable_entity__key", flat=True) ), @@ -369,7 +369,7 @@ def _import_structure( created_by=status.user_id, created_at=datetime.now(timezone.utc), ) - with authoring_api.bulk_draft_changes_for(migration.target.id) as change_log: + with content_api.bulk_draft_changes_for(migration.target.id) as change_log: root_migrated_node = _migrate_node( context=migration_context, source_node=root_node, @@ -407,7 +407,7 @@ def _populate_collection(user_id: int, migration: models.ModulestoreMigration) - ).values_list('target_id', flat=True) ) if block_target_pks: - authoring_api.add_to_collection( + content_api.add_to_collection( learning_package_id=migration.target.pk, key=migration.target_collection.key, entities_qset=PublishableEntity.objects.filter(id__in=block_target_pks), @@ -693,7 +693,7 @@ def bulk_migrate_from_modulestore( if source_data.previous_migration: if previous_collection_slug := source_data.previous_migration.target_collection_slug: try: - existing_collection_to_use = authoring_api.get_collection( + existing_collection_to_use = content_api.get_collection( target_package.id, previous_collection_slug ) except Collection.DoesNotExist: @@ -886,11 +886,11 @@ def _migrate_container( version_num=container.draft_version_num, ), None - container_publishable_entity_version = authoring_api.create_next_container_version( + container_publishable_entity_version = content_api.create_next_container_version( container.container_pk, title=title, entity_rows=[ - authoring_api.ContainerEntityRow(entity_pk=child.entity_id, version_pk=None) + content_api.ContainerEntityRow(entity_pk=child.entity_id, version_pk=None) for child in children ], created=context.created_at, @@ -924,7 +924,7 @@ def _migrate_component( (We assume that the destination is a library rather than some other future kind of learning package, but let's keep than an internal assumption.) """ - component_type = authoring_api.get_or_create_component_type("xblock.v1", source_key.block_type) + component_type = content_api.get_or_create_component_type("xblock.v1", source_key.block_type) target_key = _get_distinct_target_usage_key( context, @@ -934,7 +934,7 @@ def _migrate_component( ) try: - component = authoring_api.get_components(context.target_package_id).get( + component = content_api.get_components(context.target_package_id).get( component_type=component_type, local_key=target_key.block_id, ) @@ -954,7 +954,7 @@ def _migrate_component( except PluginMissingError as e: log.error(f"Block type not supported in {context.target_library_key}: {e}") return None, f"Invalid block type: {e}" - component = authoring_api.create_component( + component = content_api.create_component( context.target_package_id, component_type=component_type, local_key=target_key.block_id, @@ -974,7 +974,7 @@ def _migrate_component( if filename_no_ext not in olx: continue new_path = f"static/{filename}" - authoring_api.create_component_version_content( + content_api.create_component_version_content( component_version.pk, content_pk, key=new_path ) diff --git a/cms/djangoapps/modulestore_migrator/tests/test_api.py b/cms/djangoapps/modulestore_migrator/tests/test_api.py index 937729a8b8..068a0308a7 100644 --- a/cms/djangoapps/modulestore_migrator/tests/test_api.py +++ b/cms/djangoapps/modulestore_migrator/tests/test_api.py @@ -5,7 +5,7 @@ Test cases for the modulestore migrator API. import pytest from unittest.mock import patch from opaque_keys.edx.locator import LibraryLocator, LibraryLocatorV2, CourseLocator -from openedx_learning.api import authoring as authoring_api +from openedx_content import api as content_api from organizations.tests.factories import OrganizationFactory from cms.djangoapps.modulestore_migrator import api @@ -224,7 +224,7 @@ class TestModulestoreMigratorAPI(ModuleStoreTestCase): user = UserFactory() collection_key = "test-collection" - authoring_api.create_collection( + content_api.create_collection( learning_package_id=self.learning_package.id, key=collection_key, title="Test Collection", @@ -479,19 +479,19 @@ class TestModulestoreMigratorAPI(ModuleStoreTestCase): # Lib 1 has Collection A and Collection B # Lib 2 has Collection C - authoring_api.create_collection( + content_api.create_collection( learning_package_id=self.learning_package.id, key="test-collection-1a", title="Test Collection A in Lib 1", created_by=user.id, ) - authoring_api.create_collection( + content_api.create_collection( learning_package_id=self.learning_package.id, key="test-collection-1b", title="Test Collection B in Lib 1", created_by=user.id, ) - authoring_api.create_collection( + content_api.create_collection( learning_package_id=self.learning_package_2.id, key="test-collection-2c", title="Test Collection C in Lib 2", diff --git a/cms/djangoapps/modulestore_migrator/tests/test_tasks.py b/cms/djangoapps/modulestore_migrator/tests/test_tasks.py index 6c68d1944f..8af20e83c6 100644 --- a/cms/djangoapps/modulestore_migrator/tests/test_tasks.py +++ b/cms/djangoapps/modulestore_migrator/tests/test_tasks.py @@ -9,8 +9,8 @@ from django.utils import timezone from lxml import etree from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.locator import LibraryLocator, LibraryLocatorV2 -from openedx_learning.api import authoring as authoring_api -from openedx_learning.api.authoring_models import Collection, PublishableEntityVersion +from openedx_content import api as content_api +from openedx_content.models_api import Collection, PublishableEntityVersion from organizations.tests.factories import OrganizationFactory from user_tasks.models import UserTaskArtifact from user_tasks.tasks import UserTaskStatus @@ -404,8 +404,8 @@ class TestMigrateFromModulestore(ModuleStoreTestCase): source_key = self.course.id.make_usage_key("problem", "test_problem_with_image") olx = '

See image: test_image.png

' - media_type = authoring_api.get_or_create_media_type("image/png") - test_content = authoring_api.get_or_create_file_content( + media_type = content_api.get_or_create_media_type("image/png") + test_content = content_api.get_or_create_file_content( self.learning_package.id, media_type.id, data=b"fake_image_data", @@ -637,14 +637,14 @@ class TestMigrateFromModulestore(ModuleStoreTestCase): ) olx = '

See image: referenced.png

' - media_type = authoring_api.get_or_create_media_type("image/png") - referenced_content = authoring_api.get_or_create_file_content( + media_type = content_api.get_or_create_media_type("image/png") + referenced_content = content_api.get_or_create_file_content( self.learning_package.id, media_type.id, data=b"referenced_image_data", created=timezone.now(), ) - unreferenced_content = authoring_api.get_or_create_file_content( + unreferenced_content = content_api.get_or_create_file_content( self.learning_package.id, media_type.id, data=b"unreferenced_image_data", @@ -711,32 +711,32 @@ class TestMigrateFromModulestore(ModuleStoreTestCase): """ source_key = self.course.id.make_usage_key("vertical", "test_vertical") - child_component_1 = authoring_api.create_component( + child_component_1 = content_api.create_component( self.learning_package.id, - component_type=authoring_api.get_or_create_component_type( + component_type=content_api.get_or_create_component_type( "xblock.v1", "problem" ), local_key="child_problem_1", created=timezone.now(), created_by=self.user.id, ) - child_version_1 = authoring_api.create_next_component_version( + child_version_1 = content_api.create_next_component_version( child_component_1.pk, content_to_replace={}, created=timezone.now(), created_by=self.user.id, ) - child_component_2 = authoring_api.create_component( + child_component_2 = content_api.create_component( self.learning_package.id, - component_type=authoring_api.get_or_create_component_type( + component_type=content_api.get_or_create_component_type( "xblock.v1", "html" ), local_key="child_html_1", created=timezone.now(), created_by=self.user.id, ) - child_version_2 = authoring_api.create_next_component_version( + child_version_2 = content_api.create_next_component_version( child_component_2.pk, content_to_replace={}, created=timezone.now(), @@ -801,7 +801,7 @@ class TestMigrateFromModulestore(ModuleStoreTestCase): container_version = result.containerversion self.assertEqual(container_version.title, f"Test {block_type.title()}") # The container is published - self.assertFalse(authoring_api.contains_unpublished_changes(container_version.container.pk)) + self.assertFalse(content_api.contains_unpublished_changes(container_version.container.pk)) def test_migrate_container_same_title(self): """ @@ -899,16 +899,16 @@ class TestMigrateFromModulestore(ModuleStoreTestCase): context = self._make_migration_context(repeat_handling_strategy=RepeatHandlingStrategy.Skip) children = [] for i in range(3): - child_component = authoring_api.create_component( + child_component = content_api.create_component( self.learning_package.id, - component_type=authoring_api.get_or_create_component_type( + component_type=content_api.get_or_create_component_type( "xblock.v1", "problem" ), local_key=f"child_problem_{i}", created=timezone.now(), created_by=self.user.id, ) - child_version = authoring_api.create_next_component_version( + child_version = content_api.create_next_component_version( child_component.pk, content_to_replace={}, created=timezone.now(), @@ -939,48 +939,48 @@ class TestMigrateFromModulestore(ModuleStoreTestCase): """ source_key = self.course.id.make_usage_key("vertical", "mixed_vertical") - problem_component = authoring_api.create_component( + problem_component = content_api.create_component( self.learning_package.id, - component_type=authoring_api.get_or_create_component_type( + component_type=content_api.get_or_create_component_type( "xblock.v1", "problem" ), local_key="mixed_problem", created=timezone.now(), created_by=self.user.id, ) - problem_version = authoring_api.create_next_component_version( + problem_version = content_api.create_next_component_version( problem_component.pk, content_to_replace={}, created=timezone.now(), created_by=self.user.id, ) - html_component = authoring_api.create_component( + html_component = content_api.create_component( self.learning_package.id, - component_type=authoring_api.get_or_create_component_type( + component_type=content_api.get_or_create_component_type( "xblock.v1", "html" ), local_key="mixed_html", created=timezone.now(), created_by=self.user.id, ) - html_version = authoring_api.create_next_component_version( + html_version = content_api.create_next_component_version( html_component.pk, content_to_replace={}, created=timezone.now(), created_by=self.user.id, ) - video_component = authoring_api.create_component( + video_component = content_api.create_component( self.learning_package.id, - component_type=authoring_api.get_or_create_component_type( + component_type=content_api.get_or_create_component_type( "xblock.v1", "video" ), local_key="mixed_video", created=timezone.now(), created_by=self.user.id, ) - video_version = authoring_api.create_next_component_version( + video_version = content_api.create_next_component_version( video_component.pk, content_to_replace={}, created=timezone.now(), diff --git a/cms/envs/common.py b/cms/envs/common.py index f0371952f8..c2cf21c056 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -45,7 +45,7 @@ from corsheaders.defaults import default_headers as corsheaders_default_headers from datetime import timedelta from django.utils.translation import gettext_lazy as _ -from openedx_learning.api.django import openedx_learning_apps_to_install +from openedx_content.settings_api import openedx_content_backcompat_apps_to_install from openedx.envs.common import * # pylint: disable=wildcard-import @@ -849,7 +849,7 @@ INSTALLED_APPS = [ 'drf_yasg', # Tagging - 'openedx_tagging.core.tagging.apps.TaggingConfig', + 'openedx_tagging', 'openedx.core.djangoapps.content_tagging', # Search @@ -898,7 +898,9 @@ INSTALLED_APPS = [ 'openedx_events', - *openedx_learning_apps_to_install(), + # Core apps that power libraries + "openedx_content", + *openedx_content_backcompat_apps_to_install(), ] ### Apps only installed in some instances diff --git a/cms/envs/mock.yml b/cms/envs/mock.yml index 685732cc97..7d81959dfd 100644 --- a/cms/envs/mock.yml +++ b/cms/envs/mock.yml @@ -818,4 +818,3 @@ ZENDESK_GROUP_ID_MAPPING: ZENDESK_OAUTH_ACCESS_TOKEN: test_zendesk_access ZENDESK_URL: https://zendesk.com ZENDESK_USER: daemon@example.com - diff --git a/lms/envs/common.py b/lms/envs/common.py index 34f8db0f54..fc86663189 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -60,7 +60,7 @@ from enterprise.constants import ( PROVISIONING_PENDING_ENTERPRISE_CUSTOMER_ADMIN_ROLE, DEFAULT_ENTERPRISE_ENROLLMENT_INTENTIONS_ROLE, ) -from openedx_learning.api.django import openedx_learning_apps_to_install +from openedx_content.settings_api import openedx_content_backcompat_apps_to_install from openedx.core.lib.derived import Derived from openedx.envs.common import * # pylint: disable=wildcard-import @@ -1950,7 +1950,7 @@ INSTALLED_APPS = [ 'lms.djangoapps.course_goals.apps.CourseGoalsConfig', # Tagging - 'openedx_tagging.core.tagging.apps.TaggingConfig', + 'openedx_tagging', 'openedx.core.djangoapps.content_tagging', # Features @@ -2020,8 +2020,9 @@ INSTALLED_APPS = [ 'openedx_events', - # Learning Core apps that power libraries - *openedx_learning_apps_to_install(), + # Core apps that power libraries + "openedx_content", + *openedx_content_backcompat_apps_to_install(), ] # Add LMS specific optional apps diff --git a/openedx/core/djangoapps/content/search/api.py b/openedx/core/djangoapps/content/search/api.py index 9cdb519419..b36beeba47 100644 --- a/openedx/core/djangoapps/content/search/api.py +++ b/openedx/core/djangoapps/content/search/api.py @@ -25,7 +25,7 @@ from opaque_keys.edx.locator import ( LibraryContainerLocator, LibraryLocatorV2, ) -from openedx_learning.api import authoring as authoring_api +from openedx_content import api as content_api from rest_framework.request import Request from common.djangoapps.student.role_helpers import get_course_roles @@ -556,7 +556,7 @@ def rebuild_index(status_cb: Callable[[str], None] | None = None, incremental=Fa # To reduce memory usage on large instances, split up the Collections into pages of 100 collections: library = lib_api.get_library(lib_key) - collections = authoring_api.get_collections(library.learning_package_id, enabled=True) + collections = content_api.get_collections(library.learning_package_id, enabled=True) num_collections = collections.count() num_collections_done = 0 status_cb(f"{num_collections_done}/{num_collections}. Now indexing collections in library {lib_key}") @@ -572,7 +572,7 @@ def rebuild_index(status_cb: Callable[[str], None] | None = None, incremental=Fa status_cb(f"{num_collections_done}/{num_collections} collections indexed for library {lib_key}") # Similarly, batch process Containers (units, sections, etc) in pages of 100 - containers = authoring_api.get_containers(library.learning_package_id) + containers = content_api.get_containers(library.learning_package_id) num_containers = containers.count() num_containers_done = 0 status_cb(f"{num_containers_done}/{num_containers}. Now indexing containers in library {lib_key}") @@ -791,7 +791,7 @@ def update_library_components_collections( """ library_key = collection_key.lib_key library = lib_api.get_library(library_key) - components = authoring_api.get_collection_components( + components = content_api.get_collection_components( library.learning_package_id, collection_key.collection_id, ) @@ -827,7 +827,7 @@ def update_library_containers_collections( """ library_key = collection_key.lib_key library = lib_api.get_library(library_key) - containers = authoring_api.get_collection_containers( + containers = content_api.get_collection_containers( library.learning_package_id, collection_key.collection_id, ) diff --git a/openedx/core/djangoapps/content/search/documents.py b/openedx/core/djangoapps/content/search/documents.py index df673db55d..1d131923f5 100644 --- a/openedx/core/djangoapps/content/search/documents.py +++ b/openedx/core/djangoapps/content/search/documents.py @@ -10,8 +10,8 @@ from django.core.exceptions import ObjectDoesNotExist from django.utils.text import slugify from opaque_keys.edx.keys import ContainerKey, LearningContextKey, UsageKey, OpaqueKey from opaque_keys.edx.locator import LibraryCollectionLocator, LibraryContainerLocator -from openedx_learning.api import authoring as authoring_api -from openedx_learning.api.authoring_models import Collection +from openedx_content import api as content_api +from openedx_content.models_api import Collection from rest_framework.exceptions import NotFound from openedx.core.djangoapps.content.search.models import SearchAccess @@ -446,7 +446,7 @@ def searchable_doc_collections(object_id: OpaqueKey) -> dict: try: if isinstance(object_id, UsageKey): component = lib_api.get_component_from_usage_key(object_id) - collections = authoring_api.get_entity_collections( + collections = content_api.get_entity_collections( component.learning_package_id, component.key, ).values('key', 'title') @@ -543,11 +543,11 @@ def searchable_doc_for_collection( if collection: assert collection.key == collection_key.collection_id - draft_num_children = authoring_api.filter_publishable_entities( + draft_num_children = content_api.filter_publishable_entities( collection.entities, has_draft=True, ).count() - published_num_children = authoring_api.filter_publishable_entities( + published_num_children = content_api.filter_publishable_entities( collection.entities, has_published=True, ).count() diff --git a/openedx/core/djangoapps/content/search/tests/test_api.py b/openedx/core/djangoapps/content/search/tests/test_api.py index f0213eae75..4ac9abe300 100644 --- a/openedx/core/djangoapps/content/search/tests/test_api.py +++ b/openedx/core/djangoapps/content/search/tests/test_api.py @@ -15,7 +15,7 @@ import pytest from django.test import override_settings from freezegun import freeze_time from meilisearch.errors import MeilisearchApiError -from openedx_learning.api import authoring as authoring_api +from openedx_content import api as content_api from organizations.tests.factories import OrganizationFactory from common.djangoapps.student.tests.factories import UserFactory @@ -189,9 +189,9 @@ class TestSearchApi(ModuleStoreTestCase): tagging_api.add_tag_to_taxonomy(self.taxonomyB, "four") # Create a collection: - self.learning_package = authoring_api.get_learning_package_by_key(self.library.key) + self.learning_package = content_api.get_learning_package_by_key(self.library.key) with freeze_time(self.created_date): - self.collection = authoring_api.create_collection( + self.collection = content_api.create_collection( learning_package_id=self.learning_package.id, key="MYCOL", title="my_collection", @@ -926,7 +926,7 @@ class TestSearchApi(ModuleStoreTestCase): mock_meilisearch.return_value.index.reset_mock() # Soft-delete the collection - authoring_api.delete_collection( + content_api.delete_collection( self.collection.learning_package_id, self.collection.key, ) @@ -961,7 +961,7 @@ class TestSearchApi(ModuleStoreTestCase): # Restore the collection restored_date = datetime(2023, 8, 9, 10, 11, 12, tzinfo=timezone.utc) with freeze_time(restored_date): - authoring_api.restore_collection( + content_api.restore_collection( self.collection.learning_package_id, self.collection.key, ) @@ -983,7 +983,7 @@ class TestSearchApi(ModuleStoreTestCase): mock_meilisearch.return_value.index.reset_mock() # Hard-delete the collection - authoring_api.delete_collection( + content_api.delete_collection( self.collection.learning_package_id, self.collection.key, hard_delete=True, diff --git a/openedx/core/djangoapps/content/search/tests/test_documents.py b/openedx/core/djangoapps/content/search/tests/test_documents.py index 5a8a2231dc..a2bc09052b 100644 --- a/openedx/core/djangoapps/content/search/tests/test_documents.py +++ b/openedx/core/djangoapps/content/search/tests/test_documents.py @@ -7,7 +7,7 @@ from datetime import datetime, timezone from freezegun import freeze_time from opaque_keys.edx.locator import LibraryCollectionLocator, LibraryContainerLocator -from openedx_learning.api import authoring as authoring_api +from openedx_content import api as content_api from organizations.models import Organization from openedx.core.djangoapps.content_libraries import api as library_api @@ -660,7 +660,7 @@ class StudioDocumentsTest(SharedModuleStoreTestCase): self.container.container_key, [block_2.usage_key], user_id=None, - entities_action=authoring_api.ChildrenEntitiesAction.APPEND, + entities_action=content_api.ChildrenEntitiesAction.APPEND, ) doc = searchable_doc_for_container(self.container.container_key) diff --git a/openedx/core/djangoapps/content_libraries/api/blocks.py b/openedx/core/djangoapps/content_libraries/api/blocks.py index b92e7a8320..940d60e276 100644 --- a/openedx/core/djangoapps/content_libraries/api/blocks.py +++ b/openedx/core/djangoapps/content_libraries/api/blocks.py @@ -36,8 +36,8 @@ from openedx_events.content_authoring.signals import ( LIBRARY_COLLECTION_UPDATED, LIBRARY_CONTAINER_UPDATED ) -from openedx_learning.api import authoring as authoring_api -from openedx_learning.api.authoring_models import ( +from openedx_content import api as content_api +from openedx_content.models_api import ( Component, ComponentVersion, LearningPackage, MediaType, Container, Collection ) @@ -115,7 +115,7 @@ def get_library_components( lib = ContentLibrary.objects.get_by_key(library_key) # type: ignore[attr-defined] learning_package = lib.learning_package assert learning_package is not None - components = authoring_api.get_components( + components = content_api.get_components( learning_package.id, draft=True, namespace='xblock.v1', @@ -133,7 +133,7 @@ def get_library_containers(library_key: LibraryLocatorV2) -> QuerySet[Container] lib = ContentLibrary.objects.get_by_key(library_key) # type: ignore[attr-defined] learning_package = lib.learning_package assert learning_package is not None - containers: QuerySet[Container] = authoring_api.get_containers( + containers: QuerySet[Container] = content_api.get_containers( learning_package.id ) @@ -147,7 +147,7 @@ def get_library_collections(library_key: LibraryLocatorV2) -> QuerySet[Collectio lib = ContentLibrary.objects.get_by_key(library_key) # type: ignore[attr-defined] learning_package = lib.learning_package assert learning_package is not None - collections = authoring_api.get_collections( + collections = content_api.get_collections( learning_package.id ) return collections @@ -177,7 +177,7 @@ def get_library_block(usage_key: LibraryUsageLocatorV2, include_collections=Fals raise ContentLibraryBlockNotFound(usage_key) if include_collections: - associated_collections = authoring_api.get_entity_collections( + associated_collections = content_api.get_entity_collections( component.learning_package_id, component.key, ).values('key', 'title') @@ -238,13 +238,13 @@ def set_library_block_olx(usage_key: LibraryUsageLocatorV2, new_olx_str: str) -> now = datetime.now(tz=timezone.utc) with transaction.atomic(): - new_content = authoring_api.get_or_create_text_content( + new_content = content_api.get_or_create_text_content( component.learning_package_id, get_or_create_olx_media_type(usage_key.block_type).id, text=new_olx_str, created=now, ) - new_component_version = authoring_api.create_next_component_version( + new_component_version = content_api.create_next_component_version( component.pk, title=new_title, content_to_replace={ @@ -295,7 +295,7 @@ def validate_can_add_block_to_library( # If adding a component would take us over our max, return an error. assert content_library.learning_package_id is not None - component_count = authoring_api.get_all_drafts(content_library.learning_package_id).count() + component_count = content_api.get_all_drafts(content_library.learning_package_id).count() if component_count + 1 > settings.MAX_BLOCKS_PER_CONTENT_LIBRARY: raise BlockLimitReachedError( _("Library cannot have more than {} Components.").format( @@ -419,10 +419,10 @@ def _import_staged_block( with transaction.atomic(savepoint=False): # First create the Component, but do not initialize it to anything (i.e. # no ComponentVersion). - component_type = authoring_api.get_or_create_component_type( + component_type = content_api.get_or_create_component_type( "xblock.v1", usage_key.block_type ) - component = authoring_api.create_component( + component = content_api.create_component( learning_package.id, component_type=component_type, local_key=usage_key.block_id, @@ -480,14 +480,14 @@ def _import_staged_block( if not media_type_str: media_type_str = "application/octet-stream" - media_type = authoring_api.get_or_create_media_type(media_type_str) - content = authoring_api.get_or_create_file_content( + media_type = content_api.get_or_create_media_type(media_type_str) + content = content_api.get_or_create_file_content( learning_package.id, media_type.id, data=file_data, created=now, ) - authoring_api.create_component_version_content( + content_api.create_component_version_content( component_version.pk, content.id, key=filename, @@ -690,7 +690,7 @@ def get_or_create_olx_media_type(block_type: str) -> MediaType: Learning Core stores all Content with a Media Type (a.k.a. MIME type). For OLX, we use the "application/vnd.*" convention, per RFC 6838. """ - return authoring_api.get_or_create_media_type( + return content_api.get_or_create_media_type( f"application/vnd.openedx.xblock.v1.{block_type}+xml" ) @@ -704,10 +704,10 @@ def delete_library_block( """ component = get_component_from_usage_key(usage_key) library_key = usage_key.context_key - affected_collections = authoring_api.get_entity_collections(component.learning_package_id, component.key) + affected_collections = content_api.get_entity_collections(component.learning_package_id, component.key) affected_containers = get_containers_contains_item(usage_key) - authoring_api.soft_delete_draft(component.pk, deleted_by=user_id) + content_api.soft_delete_draft(component.pk, deleted_by=user_id) # .. event_implemented_name: LIBRARY_BLOCK_DELETED # .. event_type: org.openedx.content_authoring.library_block.deleted.v1 @@ -756,10 +756,10 @@ def restore_library_block(usage_key: LibraryUsageLocatorV2, user_id: int | None """ component = get_component_from_usage_key(usage_key) library_key = usage_key.context_key - affected_collections = authoring_api.get_entity_collections(component.learning_package_id, component.key) + affected_collections = content_api.get_entity_collections(component.learning_package_id, component.key) # Set draft version back to the latest available component version id. - authoring_api.set_draft_version( + content_api.set_draft_version( component.pk, component.versioning.latest.pk, set_by=user_id, @@ -895,7 +895,7 @@ def add_library_block_static_asset_file( component = get_component_from_usage_key(usage_key) with transaction.atomic(): - component_version = authoring_api.create_next_component_version( + component_version = content_api.create_next_component_version( component.pk, content_to_replace={file_path: file_content}, created=datetime.now(tz=timezone.utc), @@ -943,7 +943,7 @@ def delete_library_block_static_asset_file(usage_key, file_path, user=None): now = datetime.now(tz=timezone.utc) with transaction.atomic(): - component_version = authoring_api.create_next_component_version( + component_version = content_api.create_next_component_version( component.pk, content_to_replace={file_path: None}, created=now, @@ -971,9 +971,9 @@ def publish_component_changes(usage_key: LibraryUsageLocatorV2, user_id: int): learning_package = content_library.learning_package assert learning_package # The core publishing API is based on draft objects, so find the draft that corresponds to this component: - drafts_to_publish = authoring_api.get_all_drafts(learning_package.id).filter(entity__key=component.key) + drafts_to_publish = content_api.get_all_drafts(learning_package.id).filter(entity__key=component.key) # Publish the component and update anything that needs to be updated (e.g. search index): - publish_log = authoring_api.publish_from_drafts( + publish_log = content_api.publish_from_drafts( learning_package.id, draft_qset=drafts_to_publish, published_by=user_id, ) # Since this is a single component, it should be safe to process synchronously and in-process: @@ -1026,10 +1026,10 @@ def _create_component_for_block( assert learning_package is not None # mostly for type checker with transaction.atomic(): - component_type = authoring_api.get_or_create_component_type( + component_type = content_api.get_or_create_component_type( "xblock.v1", usage_key.block_type ) - component, component_version = authoring_api.create_component_and_version( + component, component_version = content_api.create_component_and_version( learning_package.id, component_type=component_type, local_key=usage_key.block_id, @@ -1038,13 +1038,13 @@ def _create_component_for_block( created_by=user_id, can_stand_alone=can_stand_alone, ) - content = authoring_api.get_or_create_text_content( + content = content_api.get_or_create_text_content( learning_package.id, get_or_create_olx_media_type(usage_key.block_type).id, text=xml_text, created=now, ) - authoring_api.create_component_version_content( + content_api.create_component_version_content( component_version.pk, content.id, key="block.xml", diff --git a/openedx/core/djangoapps/content_libraries/api/collections.py b/openedx/core/djangoapps/content_libraries/api/collections.py index 3f8e33f444..ad441c01da 100644 --- a/openedx/core/djangoapps/content_libraries/api/collections.py +++ b/openedx/core/djangoapps/content_libraries/api/collections.py @@ -8,8 +8,8 @@ from opaque_keys.edx.keys import BlockTypeKey, UsageKeyV2 from opaque_keys.edx.locator import LibraryCollectionLocator, LibraryContainerLocator, LibraryLocatorV2 from openedx_events.content_authoring.data import LibraryCollectionData from openedx_events.content_authoring.signals import LIBRARY_COLLECTION_UPDATED -from openedx_learning.api import authoring as authoring_api -from openedx_learning.api.authoring_models import Collection, Component, PublishableEntity +from openedx_content import api as content_api +from openedx_content.models_api import Collection, Component, PublishableEntity from ..models import ContentLibrary from .exceptions import ( @@ -52,7 +52,7 @@ def create_library_collection( assert content_library.library_key == library_key try: - collection = authoring_api.create_collection( + collection = content_api.create_collection( learning_package_id=content_library.learning_package_id, key=collection_key, title=title, @@ -84,7 +84,7 @@ def update_library_collection( assert content_library.library_key == library_key try: - collection = authoring_api.update_collection( + collection = content_api.update_collection( learning_package_id=content_library.learning_package_id, key=collection_key, title=title, @@ -132,7 +132,7 @@ def update_library_collection_items( for opaque_key in opaque_keys: if isinstance(opaque_key, LibraryContainerLocator): try: - container = authoring_api.get_container_by_key( + container = content_api.get_container_by_key( content_library.learning_package_id, key=opaque_key.container_id, ) @@ -144,7 +144,7 @@ def update_library_collection_items( # Parse the block_family from the key to use as namespace. block_type = BlockTypeKey.from_string(str(opaque_key)) try: - component = authoring_api.get_component_by_key( + component = content_api.get_component_by_key( content_library.learning_package_id, namespace=block_type.block_family, type_name=opaque_key.block_type, @@ -163,13 +163,13 @@ def update_library_collection_items( ) if remove: - collection = authoring_api.remove_from_collection( + collection = content_api.remove_from_collection( content_library.learning_package_id, collection_key, entities_qset, ) else: - collection = authoring_api.add_to_collection( + collection = content_api.add_to_collection( content_library.learning_package_id, collection_key, entities_qset, @@ -207,17 +207,17 @@ def set_library_item_collections( assert content_library.learning_package_id assert content_library.library_key == library_key - publishable_entity = authoring_api.get_publishable_entity_by_key( + publishable_entity = content_api.get_publishable_entity_by_key( content_library.learning_package_id, key=entity_key, ) # Note: Component.key matches its PublishableEntity.key - collection_qs = authoring_api.get_collections(content_library.learning_package_id).filter( + collection_qs = content_api.get_collections(content_library.learning_package_id).filter( key__in=collection_keys ) - affected_collections = authoring_api.set_collections( + affected_collections = content_api.set_collections( publishable_entity, collection_qs, created_by=created_by, @@ -263,7 +263,7 @@ def get_library_collection_from_locator( content_library = ContentLibrary.objects.get_by_key(library_key) # type: ignore[attr-defined] assert content_library.learning_package_id is not None # shouldn't happen but it's technically possible. try: - return authoring_api.get_collection( + return content_api.get_collection( content_library.learning_package_id, collection_key, ) diff --git a/openedx/core/djangoapps/content_libraries/api/container_metadata.py b/openedx/core/djangoapps/content_libraries/api/container_metadata.py index 53726ca49d..0e6ed1ea61 100644 --- a/openedx/core/djangoapps/content_libraries/api/container_metadata.py +++ b/openedx/core/djangoapps/content_libraries/api/container_metadata.py @@ -8,8 +8,8 @@ from enum import Enum from django.db.models import QuerySet from opaque_keys.edx.locator import LibraryContainerLocator, LibraryLocatorV2, LibraryUsageLocatorV2 -from openedx_learning.api import authoring as authoring_api -from openedx_learning.api.authoring_models import ( +from openedx_content import api as content_api +from openedx_content.models_api import ( Component, Container, ContainerVersion, @@ -149,7 +149,7 @@ class ContainerMetadata(PublishableItem): published_by=published_by, last_draft_created=last_draft_created, last_draft_created_by=last_draft_created_by, - has_unpublished_changes=authoring_api.contains_unpublished_changes(container.pk), + has_unpublished_changes=content_api.contains_unpublished_changes(container.pk), tags_count=tags.get(str(container_key), 0), collections=associated_collections or [], ) @@ -295,7 +295,7 @@ def _get_containers_with_entities( """ qs = Container.objects.none() for member in members: - qs = qs.union(authoring_api.get_containers_with_entity( + qs = qs.union(content_api.get_containers_with_entity( member.entity.pk, ignore_pinned=ignore_pinned, )) @@ -320,7 +320,7 @@ def _get_containers_children( for member in members: container = member.container assert container - for entry in authoring_api.get_entities_in_container( + for entry in content_api.get_entities_in_container( container, published=published, ): @@ -372,7 +372,7 @@ class ContainerHierarchyMember: container=entity, ), display_name=entity.versioning.draft.title, - has_unpublished_changes=authoring_api.contains_unpublished_changes(entity.pk), + has_unpublished_changes=content_api.contains_unpublished_changes(entity.pk), container=entity, component=None, ) @@ -425,7 +425,7 @@ def get_container_from_key(container_key: LibraryContainerLocator, include_delet content_library = ContentLibrary.objects.get_by_key(container_key.lib_key) learning_package = content_library.learning_package assert learning_package is not None - container = authoring_api.get_container_by_key( + container = content_api.get_container_by_key( learning_package.id, key=container_key.container_id, ) diff --git a/openedx/core/djangoapps/content_libraries/api/containers.py b/openedx/core/djangoapps/content_libraries/api/containers.py index 5cca0b3a99..54740d1303 100644 --- a/openedx/core/djangoapps/content_libraries/api/containers.py +++ b/openedx/core/djangoapps/content_libraries/api/containers.py @@ -22,8 +22,8 @@ from openedx_events.content_authoring.signals import ( LIBRARY_CONTAINER_DELETED, LIBRARY_CONTAINER_UPDATED, ) -from openedx_learning.api import authoring as authoring_api -from openedx_learning.api.authoring_models import Container, ContainerVersion, Component +from openedx_content import api as content_api +from openedx_content.models_api import Container, ContainerVersion, Component from openedx.core.djangoapps.content_libraries.api.collections import library_collection_locator from openedx.core.djangoapps.xblock.api import get_component_from_usage_key @@ -76,7 +76,7 @@ def get_container( """ container = get_container_from_key(container_key) if include_collections: - associated_collections = authoring_api.get_entity_collections( + associated_collections = content_api.get_entity_collections( container.publishable_entity.learning_package_id, container_key.container_id, ).values('key', 'title') @@ -126,7 +126,7 @@ def create_container( # Then try creating the actual container: match container_type: case ContainerType.Unit: - container, _initial_version = authoring_api.create_unit_and_version( + container, _initial_version = content_api.create_unit_and_version( content_library.learning_package_id, key=slug, title=title, @@ -134,7 +134,7 @@ def create_container( created_by=user_id, ) case ContainerType.Subsection: - container, _initial_version = authoring_api.create_subsection_and_version( + container, _initial_version = content_api.create_subsection_and_version( content_library.learning_package_id, key=slug, title=title, @@ -142,7 +142,7 @@ def create_container( created_by=user_id, ) case ContainerType.Section: - container, _initial_version = authoring_api.create_section_and_version( + container, _initial_version = content_api.create_section_and_version( content_library.learning_package_id, key=slug, title=title, @@ -188,7 +188,7 @@ def update_container( match container_type: case ContainerType.Unit: - version = authoring_api.create_next_unit_version( + version = content_api.create_next_unit_version( container.unit, title=display_name, created=created, @@ -198,7 +198,7 @@ def update_container( # Components have usage_key instead of container_key child_key_name = 'usage_key' case ContainerType.Subsection: - version = authoring_api.create_next_subsection_version( + version = content_api.create_next_subsection_version( container.subsection, title=display_name, created=created, @@ -206,7 +206,7 @@ def update_container( ) affected_containers = get_containers_contains_item(container_key) case ContainerType.Section: - version = authoring_api.create_next_section_version( + version = content_api.create_next_section_version( container.section, title=display_name, created=created, @@ -265,7 +265,7 @@ def delete_container( container = get_container_from_key(container_key) # Fetch related collections and containers before soft-delete - affected_collections = authoring_api.get_entity_collections( + affected_collections = content_api.get_entity_collections( container.publishable_entity.learning_package_id, container.key, ) @@ -275,7 +275,7 @@ def delete_container( container_key, published=False, ) - authoring_api.soft_delete_draft(container.pk) + content_api.soft_delete_draft(container.pk) # .. event_implemented_name: LIBRARY_CONTAINER_DELETED # .. event_type: org.openedx.content_authoring.content_library.container.deleted.v1 @@ -337,12 +337,12 @@ def restore_container(container_key: LibraryContainerLocator) -> None: library_key = container_key.lib_key container = get_container_from_key(container_key, include_deleted=True) - affected_collections = authoring_api.get_entity_collections( + affected_collections = content_api.get_entity_collections( container.publishable_entity.learning_package_id, container.key, ) - authoring_api.set_draft_version(container.pk, container.versioning.latest.pk) + content_api.set_draft_version(container.pk, container.versioning.latest.pk) # Fetch related containers after restore affected_containers = get_containers_contains_item(container_key) # Get children containers or components to update their index data @@ -430,25 +430,25 @@ def get_container_children( match container_type: case ContainerType.Unit: - child_components = authoring_api.get_components_in_unit(container.unit, published=published) + child_components = content_api.get_components_in_unit(container.unit, published=published) return [LibraryXBlockMetadata.from_component( container_key.lib_key, entry.component ) for entry in child_components] case ContainerType.Subsection: - child_units = authoring_api.get_units_in_subsection(container.subsection, published=published) + child_units = content_api.get_units_in_subsection(container.subsection, published=published) return [ContainerMetadata.from_container( container_key.lib_key, entry.unit ) for entry in child_units] case ContainerType.Section: - child_subsections = authoring_api.get_subsections_in_section(container.section, published=published) + child_subsections = content_api.get_subsections_in_section(container.section, published=published) return [ContainerMetadata.from_container( container_key.lib_key, entry.subsection, ) for entry in child_subsections] case _: - child_entities = authoring_api.get_entities_in_container(container, published=published) + child_entities = content_api.get_entities_in_container(container, published=published) return [ContainerMetadata.from_container( container_key.lib_key, entry.entity @@ -463,14 +463,14 @@ def get_container_children_count( [ 🛑 UNSTABLE ] Get the count of entities contained in the given container (e.g. the components/xblocks in a unit) """ container = get_container_from_key(container_key) - return authoring_api.get_container_children_count(container, published=published) + return content_api.get_container_children_count(container, published=published) def update_container_children( container_key: LibraryContainerLocator, children_ids: list[LibraryUsageLocatorV2] | list[LibraryContainerLocator], user_id: int | None, - entities_action: authoring_api.ChildrenEntitiesAction = authoring_api.ChildrenEntitiesAction.REPLACE, + entities_action: content_api.ChildrenEntitiesAction = content_api.ChildrenEntitiesAction.REPLACE, ): """ [ 🛑 UNSTABLE ] Adds children components or containers to given container. @@ -483,7 +483,7 @@ def update_container_children( match container_type: case ContainerType.Unit: components = [get_component_from_usage_key(key) for key in children_ids] # type: ignore[arg-type] - new_version = authoring_api.create_next_unit_version( + new_version = content_api.create_next_unit_version( container.unit, components=components, # type: ignore[arg-type] created=created, @@ -502,7 +502,7 @@ def update_container_children( ) case ContainerType.Subsection: units = [get_container_from_key(key).unit for key in children_ids] # type: ignore[arg-type] - new_version = authoring_api.create_next_subsection_version( + new_version = content_api.create_next_subsection_version( container.subsection, units=units, # type: ignore[arg-type] created=created, @@ -521,7 +521,7 @@ def update_container_children( ) case ContainerType.Section: subsections = [get_container_from_key(key).subsection for key in children_ids] # type: ignore[arg-type] - new_version = authoring_api.create_next_section_version( + new_version = content_api.create_next_section_version( container.section, subsections=subsections, # type: ignore[arg-type] created=created, @@ -566,7 +566,7 @@ def get_containers_contains_item( elif isinstance(key, LibraryContainerLocator): item = get_container_from_key(key) - containers = authoring_api.get_containers_with_entity( + containers = content_api.get_containers_with_entity( item.publishable_entity.pk, ) return [ @@ -590,9 +590,9 @@ def publish_container_changes( learning_package = content_library.learning_package assert learning_package # The core publishing API is based on draft objects, so find the draft that corresponds to this container: - drafts_to_publish = authoring_api.get_all_drafts(learning_package.id).filter(entity__pk=container.pk) + drafts_to_publish = content_api.get_all_drafts(learning_package.id).filter(entity__pk=container.pk) # Publish the container, which will also auto-publish any unpublished child components: - publish_log = authoring_api.publish_from_drafts( + publish_log = content_api.publish_from_drafts( learning_package.id, draft_qset=drafts_to_publish, published_by=user_id, diff --git a/openedx/core/djangoapps/content_libraries/api/exceptions.py b/openedx/core/djangoapps/content_libraries/api/exceptions.py index e715f08561..d7196cb875 100644 --- a/openedx/core/djangoapps/content_libraries/api/exceptions.py +++ b/openedx/core/djangoapps/content_libraries/api/exceptions.py @@ -3,7 +3,7 @@ Exceptions that can be thrown by the Content Libraries API. """ from django.db import IntegrityError -from openedx_learning.api.authoring_models import Collection, Container +from openedx_content.models_api import Collection, Container from xblock.exceptions import XBlockNotFoundError from ..models import ContentLibrary diff --git a/openedx/core/djangoapps/content_libraries/api/libraries.py b/openedx/core/djangoapps/content_libraries/api/libraries.py index f5d60e9fc8..4cd2387b9d 100644 --- a/openedx/core/djangoapps/content_libraries/api/libraries.py +++ b/openedx/core/djangoapps/content_libraries/api/libraries.py @@ -63,8 +63,8 @@ from openedx_events.content_authoring.signals import ( CONTENT_LIBRARY_DELETED, CONTENT_LIBRARY_UPDATED, ) -from openedx_learning.api import authoring as authoring_api -from openedx_learning.api.authoring_models import Component, LearningPackage +from openedx_content import api as content_api +from openedx_content.models_api import Component, LearningPackage from organizations.models import Organization from user_tasks.models import UserTaskArtifact, UserTaskStatus from xblock.core import XBlock @@ -364,9 +364,9 @@ def get_library(library_key: LibraryLocatorV2) -> ContentLibraryMetadata: ref = ContentLibrary.objects.get_by_key(library_key) learning_package = ref.learning_package assert learning_package is not None # Shouldn't happen - this is just for the type checker - num_blocks = authoring_api.get_all_drafts(learning_package.id).count() - last_publish_log = authoring_api.get_last_publish(learning_package.id) - last_draft_log = authoring_api.get_entities_with_unpublished_changes(learning_package.id) \ + num_blocks = content_api.get_all_drafts(learning_package.id).count() + last_publish_log = content_api.get_last_publish(learning_package.id) + last_draft_log = content_api.get_entities_with_unpublished_changes(learning_package.id) \ .order_by('-created').first() last_draft_created = last_draft_log.created if last_draft_log else None last_draft_created_by = last_draft_log.created_by.username if last_draft_log and last_draft_log.created_by else "" @@ -377,8 +377,9 @@ def get_library(library_key: LibraryLocatorV2) -> ContentLibraryMetadata: # with how Blockstore staged changes, but Learning Core works differently, # and has_unpublished_changes should be sufficient. # Ref: https://github.com/openedx/edx-platform/issues/34283 - has_unpublished_deletes = authoring_api.get_entities_with_unpublished_deletes(learning_package.id) \ - .exists() + has_unpublished_deletes = ( + content_api.get_entities_with_unpublished_deletes(learning_package.id).exists() + ) published_by = "" if last_publish_log and last_publish_log.published_by: @@ -450,7 +451,7 @@ def create_library( if learning_package: # A temporary LearningPackage was passed in, so update its key to match the library, # and also update its title/description in case they differ. - authoring_api.update_learning_package( + content_api.update_learning_package( learning_package.id, key=str(ref.library_key), title=title, @@ -458,7 +459,7 @@ def create_library( ) else: # We have to generate a new LearningPackage for this library. - learning_package = authoring_api.create_learning_package( + learning_package = content_api.create_learning_package( key=str(ref.library_key), title=title, description=description, @@ -485,7 +486,7 @@ def create_library( allow_public_learning=ref.allow_public_learning, allow_public_read=ref.allow_public_read, license=library_license, - learning_package_id=ref.learning_package.pk, + learning_package_id=ref.learning_package.pk, # type: ignore[union-attr] ) @@ -625,7 +626,7 @@ def update_library( content_lib.save() if learning_pkg_changed: - authoring_api.update_learning_package( + content_api.update_learning_package( learning_package_id, title=title, description=description, @@ -717,7 +718,7 @@ def publish_changes(library_key: LibraryLocatorV2, user_id: int | None = None): """ learning_package = ContentLibrary.objects.get_by_key(library_key).learning_package assert learning_package is not None # shouldn't happen but it's technically possible. - publish_log = authoring_api.publish_all_drafts(learning_package.id, published_by=user_id) + publish_log = content_api.publish_all_drafts(learning_package.id, published_by=user_id) # Update the search index (and anything else) for the affected blocks # This is mostly synchronous but may complete some work asynchronously if there are a lot of changes. @@ -735,8 +736,8 @@ def revert_changes(library_key: LibraryLocatorV2, user_id: int | None = None) -> """ learning_package = ContentLibrary.objects.get_by_key(library_key).learning_package assert learning_package is not None # shouldn't happen but it's technically possible. - with authoring_api.bulk_draft_changes_for(learning_package.id) as draft_change_log: - authoring_api.reset_drafts_to_published(learning_package.id, reset_by=user_id) + with content_api.bulk_draft_changes_for(learning_package.id) as draft_change_log: + content_api.reset_drafts_to_published(learning_package.id, reset_by=user_id) # Call the event handlers as needed. tasks.wait_for_post_revert_events(draft_change_log, library_key) diff --git a/openedx/core/djangoapps/content_libraries/library_context.py b/openedx/core/djangoapps/content_libraries/library_context.py index e1f08ac328..65c5508b22 100644 --- a/openedx/core/djangoapps/content_libraries/library_context.py +++ b/openedx/core/djangoapps/content_libraries/library_context.py @@ -10,7 +10,7 @@ from openedx_events.content_authoring.data import LibraryBlockData, LibraryConta from openedx_events.content_authoring.signals import LIBRARY_BLOCK_UPDATED, LIBRARY_CONTAINER_UPDATED from opaque_keys.edx.keys import UsageKeyV2 from opaque_keys.edx.locator import LibraryUsageLocatorV2, LibraryLocatorV2 -from openedx_learning.api import authoring as authoring_api +from openedx_content import api as content_api from openedx.core.djangoapps.content_libraries import api, permissions from openedx.core.djangoapps.content_libraries.models import ContentLibrary @@ -96,7 +96,7 @@ class LibraryContextImpl(LearningContext): if learning_package is None: return False - return authoring_api.component_exists_by_key( + return content_api.component_exists_by_key( learning_package.id, namespace='xblock.v1', type_name=usage_key.block_type, diff --git a/openedx/core/djangoapps/content_libraries/models.py b/openedx/core/djangoapps/content_libraries/models.py index 4158211456..4a292bae5d 100644 --- a/openedx/core/djangoapps/content_libraries/models.py +++ b/openedx/core/djangoapps/content_libraries/models.py @@ -57,7 +57,7 @@ from opaque_keys.edx.django.models import UsageKeyField from openedx.core.djangoapps.content_libraries.constants import ( LICENSE_OPTIONS, ALL_RIGHTS_RESERVED, ) -from openedx_learning.api.authoring_models import LearningPackage +from openedx_content.models_api import LearningPackage from organizations.models import Organization # lint-amnesty, pylint: disable=wrong-import-order from .apps import ContentLibrariesConfig diff --git a/openedx/core/djangoapps/content_libraries/rest_api/blocks.py b/openedx/core/djangoapps/content_libraries/rest_api/blocks.py index e72980f6ba..42c5b93418 100644 --- a/openedx/core/djangoapps/content_libraries/rest_api/blocks.py +++ b/openedx/core/djangoapps/content_libraries/rest_api/blocks.py @@ -10,7 +10,7 @@ from django.utils.decorators import method_decorator from drf_yasg.utils import swagger_auto_schema from opaque_keys.edx.locator import LibraryLocatorV2, LibraryUsageLocatorV2 from openedx_authz.constants import permissions as authz_permissions -from openedx_learning.api import authoring as authoring_api +from openedx_content import api as content_api from rest_framework import status from rest_framework.exceptions import NotFound, ValidationError from rest_framework.generics import GenericAPIView @@ -392,7 +392,7 @@ def get_component_version_asset(request, component_version_uuid, asset_path): eventually). """ try: - component_version = authoring_api.get_component_version_by_uuid( + component_version = content_api.get_component_version_by_uuid( component_version_uuid ) except ObjectDoesNotExist as exc: @@ -411,7 +411,7 @@ def get_component_version_asset(request, component_version_uuid, asset_path): # this response in conjunction with a media reverse proxy (Caddy or Nginx), # but in the short term we're just going to remove the redirect and stream # the content directly. - redirect_response = authoring_api.get_redirect_response_for_component_asset( + redirect_response = content_api.get_redirect_response_for_component_asset( component_version_uuid, asset_path, public=False, diff --git a/openedx/core/djangoapps/content_libraries/rest_api/collections.py b/openedx/core/djangoapps/content_libraries/rest_api/collections.py index f4d579aa04..85f0821384 100644 --- a/openedx/core/djangoapps/content_libraries/rest_api/collections.py +++ b/openedx/core/djangoapps/content_libraries/rest_api/collections.py @@ -14,8 +14,8 @@ from rest_framework.status import HTTP_204_NO_CONTENT from opaque_keys.edx.locator import LibraryLocatorV2 from openedx_authz.constants import permissions as authz_permissions -from openedx_learning.api import authoring as authoring_api -from openedx_learning.api.authoring_models import Collection +from openedx_content import api as content_api +from openedx_content.models_api import Collection from .. import api, permissions from ..models import ContentLibrary @@ -72,7 +72,7 @@ class LibraryCollectionsView(ModelViewSet): """ content_library = self.get_content_library() assert content_library.learning_package_id - return authoring_api.get_collections(content_library.learning_package_id) + return content_api.get_collections(content_library.learning_package_id) def get_object(self) -> Collection: """ @@ -183,7 +183,7 @@ class LibraryCollectionsView(ModelViewSet): ) collection = super().get_object() assert collection.learning_package_id - authoring_api.delete_collection( + content_api.delete_collection( collection.learning_package_id, collection.key, hard_delete=False, @@ -204,7 +204,7 @@ class LibraryCollectionsView(ModelViewSet): ) assert content_library.learning_package_id collection_key = kwargs["key"] - authoring_api.restore_collection( + content_api.restore_collection( content_library.learning_package_id, collection_key, ) diff --git a/openedx/core/djangoapps/content_libraries/rest_api/containers.py b/openedx/core/djangoapps/content_libraries/rest_api/containers.py index c60c40b980..4b368e8eb9 100644 --- a/openedx/core/djangoapps/content_libraries/rest_api/containers.py +++ b/openedx/core/djangoapps/content_libraries/rest_api/containers.py @@ -13,7 +13,7 @@ from drf_yasg import openapi from opaque_keys.edx.locator import LibraryLocatorV2, LibraryContainerLocator from openedx_authz.constants import permissions as authz_permissions -from openedx_learning.api import authoring as authoring_api +from openedx_content import api as content_api from rest_framework.generics import GenericAPIView from rest_framework.response import Response from rest_framework.status import HTTP_204_NO_CONTENT, HTTP_200_OK @@ -200,7 +200,7 @@ class LibraryContainerChildrenView(GenericAPIView): self, request, container_key: LibraryContainerLocator, - action: authoring_api.ChildrenEntitiesAction, + action: content_api.ChildrenEntitiesAction, ): """ Helper function to update children in container. @@ -237,7 +237,7 @@ class LibraryContainerChildrenView(GenericAPIView): return self._update_component_children( request, container_key, - action=authoring_api.ChildrenEntitiesAction.APPEND, + action=content_api.ChildrenEntitiesAction.APPEND, ) @convert_exceptions @@ -256,7 +256,7 @@ class LibraryContainerChildrenView(GenericAPIView): return self._update_component_children( request, container_key, - action=authoring_api.ChildrenEntitiesAction.REMOVE, + action=content_api.ChildrenEntitiesAction.REMOVE, ) @convert_exceptions @@ -275,7 +275,7 @@ class LibraryContainerChildrenView(GenericAPIView): return self._update_component_children( request, container_key, - action=authoring_api.ChildrenEntitiesAction.REPLACE, + action=content_api.ChildrenEntitiesAction.REPLACE, ) diff --git a/openedx/core/djangoapps/content_libraries/rest_api/serializers.py b/openedx/core/djangoapps/content_libraries/rest_api/serializers.py index c0bf07d087..9d68d6b276 100644 --- a/openedx/core/djangoapps/content_libraries/rest_api/serializers.py +++ b/openedx/core/djangoapps/content_libraries/rest_api/serializers.py @@ -8,7 +8,7 @@ import logging from django.core.validators import validate_unicode_slug from opaque_keys import InvalidKeyError, OpaqueKey from opaque_keys.edx.locator import LibraryContainerLocator, LibraryUsageLocatorV2 -from openedx_learning.api.authoring_models import Collection, LearningPackage +from openedx_content.models_api import Collection, LearningPackage from rest_framework import serializers from rest_framework.exceptions import ValidationError from user_tasks.models import UserTaskStatus diff --git a/openedx/core/djangoapps/content_libraries/signal_handlers.py b/openedx/core/djangoapps/content_libraries/signal_handlers.py index 8a5b8bd89c..3169f447ba 100644 --- a/openedx/core/djangoapps/content_libraries/signal_handlers.py +++ b/openedx/core/djangoapps/content_libraries/signal_handlers.py @@ -16,8 +16,8 @@ from openedx_events.content_authoring.signals import ( LIBRARY_COLLECTION_DELETED, LIBRARY_COLLECTION_UPDATED ) -from openedx_learning.api.authoring import get_components, get_containers -from openedx_learning.api.authoring_models import Collection, CollectionPublishableEntity, PublishableEntity +from openedx_content.api import get_components, get_containers +from openedx_content.models_api import Collection, CollectionPublishableEntity, PublishableEntity from lms.djangoapps.grades.api import signals as grades_signals diff --git a/openedx/core/djangoapps/content_libraries/tasks.py b/openedx/core/djangoapps/content_libraries/tasks.py index bbbf847bfb..3457332900 100644 --- a/openedx/core/djangoapps/content_libraries/tasks.py +++ b/openedx/core/djangoapps/content_libraries/tasks.py @@ -57,9 +57,9 @@ from openedx_events.content_authoring.signals import ( LIBRARY_CONTAINER_PUBLISHED, LIBRARY_CONTAINER_UPDATED ) -from openedx_learning.api import authoring as authoring_api -from openedx_learning.api.authoring import create_zip_file as create_lib_zip_file -from openedx_learning.api.authoring_models import DraftChangeLog, PublishLog +from openedx_content import api as content_api +from openedx_content.api import create_zip_file as create_lib_zip_file +from openedx_content.models_api import DraftChangeLog, PublishLog from path import Path from user_tasks.models import UserTaskArtifact from user_tasks.tasks import UserTask, UserTaskStatus @@ -244,7 +244,7 @@ def send_events_after_revert(draft_change_log_id: int, library_key_str: str) -> ) # If any collections contain this entity, their item count may need to be updated, e.g. if this was a # newly created component in the collection and is now deleted, or this was deleted and is now re-added. - for parent_collection in authoring_api.get_entity_collections( + for parent_collection in content_api.get_entity_collections( record.entity.learning_package_id, record.entity.key, ): collection_key = api.library_collection_locator( @@ -640,7 +640,7 @@ class LibraryRestoreTask(UserTask): TASK_LOGGER.info('Restoring learning package from temporary file %s', tmp_file.name) - result = authoring_api.load_learning_package(tmp_file.name, user=user) + result = content_api.load_learning_package(tmp_file.name, user=user) # If there was an error during the load, fail the task with the error log if result.get("status") == "error": diff --git a/openedx/core/djangoapps/content_libraries/tests/test_api.py b/openedx/core/djangoapps/content_libraries/tests/test_api.py index 2247a3188e..69fae56b2d 100644 --- a/openedx/core/djangoapps/content_libraries/tests/test_api.py +++ b/openedx/core/djangoapps/content_libraries/tests/test_api.py @@ -29,7 +29,7 @@ from openedx_events.content_authoring.signals import ( LIBRARY_CONTAINER_UPDATED, ) from openedx_authz.api.users import get_user_role_assignments_in_scope -from openedx_learning.api import authoring as authoring_api +from openedx_content import api as content_api from common.djangoapps.student.tests.factories import UserFactory from .. import api @@ -411,7 +411,7 @@ class ContentLibraryCollectionsTest(ContentLibrariesRestApiTest): LIBRARY_COLLECTION_DELETED.connect(event_receiver) assert self.lib1.learning_package_id is not None - authoring_api.delete_collection( + content_api.delete_collection( self.lib1.learning_package_id, self.col1.key, hard_delete=True, @@ -549,8 +549,8 @@ class ContentLibraryCollectionsTest(ContentLibrariesRestApiTest): ) assert self.lib2.learning_package_id is not None - assert len(authoring_api.get_collection(self.lib2.learning_package_id, self.col2.key).entities.all()) == 1 - assert len(authoring_api.get_collection(self.lib2.learning_package_id, self.col3.key).entities.all()) == 1 + assert len(content_api.get_collection(self.lib2.learning_package_id, self.col2.key).entities.all()) == 1 + assert len(content_api.get_collection(self.lib2.learning_package_id, self.col3.key).entities.all()) == 1 self.assertDictContainsEntries( event_receiver.call_args_list[0].kwargs, @@ -1059,7 +1059,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest): self.unit2.container_key, [LibraryUsageLocatorV2.from_string(html_block_1["id"])], None, - entities_action=authoring_api.ChildrenEntitiesAction.APPEND, + entities_action=content_api.ChildrenEntitiesAction.APPEND, ) event_reciver = mock.Mock() @@ -1068,7 +1068,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest): self.unit2.container_key, [LibraryUsageLocatorV2.from_string(html_block_1["id"])], None, - entities_action=authoring_api.ChildrenEntitiesAction.REMOVE, + entities_action=content_api.ChildrenEntitiesAction.REMOVE, ) assert event_reciver.call_count == 1 @@ -1091,7 +1091,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest): self.subsection2.container_key, [unit4.container_key], None, - entities_action=authoring_api.ChildrenEntitiesAction.APPEND, + entities_action=content_api.ChildrenEntitiesAction.APPEND, ) event_reciver = mock.Mock() @@ -1100,7 +1100,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest): self.subsection2.container_key, [unit4.container_key], None, - entities_action=authoring_api.ChildrenEntitiesAction.REMOVE, + entities_action=content_api.ChildrenEntitiesAction.REMOVE, ) assert event_reciver.call_count == 1 @@ -1129,7 +1129,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest): self.section2.container_key, [subsection3.container_key], None, - entities_action=authoring_api.ChildrenEntitiesAction.APPEND, + entities_action=content_api.ChildrenEntitiesAction.APPEND, ) event_reciver = mock.Mock() @@ -1138,7 +1138,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest): self.section2.container_key, [subsection3.container_key], None, - entities_action=authoring_api.ChildrenEntitiesAction.REMOVE, + entities_action=content_api.ChildrenEntitiesAction.REMOVE, ) assert event_reciver.call_count == 1 @@ -1171,7 +1171,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest): LibraryUsageLocatorV2.from_string(html_block_2["id"]) ], None, - entities_action=authoring_api.ChildrenEntitiesAction.APPEND, + entities_action=content_api.ChildrenEntitiesAction.APPEND, ) assert event_reciver.call_count == 2 @@ -1209,7 +1209,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest): self.subsection2.container_key, [unit4.container_key, unit5.container_key], None, - entities_action=authoring_api.ChildrenEntitiesAction.APPEND, + entities_action=content_api.ChildrenEntitiesAction.APPEND, ) assert event_reciver.call_count == 2 self.assertDictContainsEntries( @@ -1257,7 +1257,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest): self.section2.container_key, [subsection3.container_key, subsection4.container_key], None, - entities_action=authoring_api.ChildrenEntitiesAction.APPEND, + entities_action=content_api.ChildrenEntitiesAction.APPEND, ) assert event_reciver.call_count == 2 self.assertDictContainsEntries( diff --git a/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py b/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py index 10d6c1ead9..24609f9389 100644 --- a/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py +++ b/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py @@ -23,7 +23,7 @@ from opaque_keys.edx.locator import LibraryLocatorV2, LibraryUsageLocatorV2, Lib from organizations.models import Organization from rest_framework.test import APITestCase from rest_framework import status -from openedx_learning.api.authoring_models import LearningPackage +from openedx_content.models_api import LearningPackage from user_tasks.models import UserTaskStatus, UserTaskArtifact from common.djangoapps.student.tests.factories import UserFactory @@ -1179,7 +1179,7 @@ class LibraryRestoreViewTestCase(ContentLibrariesRestApiTest): with self.as_user(self.admin_user): with patch( - "openedx.core.djangoapps.content_libraries.tasks.authoring_api.load_learning_package", + "openedx.core.djangoapps.content_libraries.tasks.content_api.load_learning_package", return_value=error_result ): response = self._start_library_restore_task(self.uploaded_zip_file) @@ -1202,7 +1202,7 @@ class LibraryRestoreViewTestCase(ContentLibrariesRestApiTest): """ with self.as_user(self.admin_user): with patch( - "openedx.core.djangoapps.content_libraries.tasks.authoring_api.load_learning_package", + "openedx.core.djangoapps.content_libraries.tasks.content_api.load_learning_package", side_effect=Exception("Uncaught exception during processing.") ): response = self._start_library_restore_task(self.uploaded_zip_file) diff --git a/openedx/core/djangoapps/content_libraries/tests/test_views_collections.py b/openedx/core/djangoapps/content_libraries/tests/test_views_collections.py index ce9b0e880d..edd3084e90 100644 --- a/openedx/core/djangoapps/content_libraries/tests/test_views_collections.py +++ b/openedx/core/djangoapps/content_libraries/tests/test_views_collections.py @@ -5,7 +5,7 @@ Tests Library Collections REST API views from __future__ import annotations import ddt -from openedx_learning.api.authoring_models import Collection +from openedx_content.models_api import Collection from opaque_keys.edx.locator import LibraryLocatorV2 from openedx.core.djangolib.testing.utils import skip_unless_cms diff --git a/openedx/core/djangoapps/content_staging/migrations/0003_olx_unicode.py b/openedx/core/djangoapps/content_staging/migrations/0003_olx_unicode.py index 1a1c414bf1..baac395af4 100644 --- a/openedx/core/djangoapps/content_staging/migrations/0003_olx_unicode.py +++ b/openedx/core/djangoapps/content_staging/migrations/0003_olx_unicode.py @@ -1,7 +1,7 @@ # Generated by Django 3.2.23 on 2023-12-07 20:10 from django.db import migrations -import openedx_learning.lib.fields +import openedx_django_lib.fields class Migration(migrations.Migration): @@ -14,11 +14,11 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='stagedcontent', name='display_name', - field=openedx_learning.lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_unicode_ci', 'sqlite': 'NOCASE'}, max_length=768), + field=openedx_django_lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_unicode_ci', 'sqlite': 'NOCASE'}, max_length=768), ), migrations.AlterField( model_name='stagedcontent', name='olx', - field=openedx_learning.lib.fields.MultiCollationTextField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}), + field=openedx_django_lib.fields.MultiCollationTextField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}), ), ] diff --git a/openedx/core/djangoapps/content_staging/models.py b/openedx/core/djangoapps/content_staging/models.py index 0e7426f238..7cb27e4e13 100644 --- a/openedx/core/djangoapps/content_staging/models.py +++ b/openedx/core/djangoapps/content_staging/models.py @@ -11,7 +11,7 @@ from django.db import models from django.utils.translation import gettext_lazy as _ from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import ContainerKey, LearningContextKey, UsageKey -from openedx_learning.lib.fields import MultiCollationTextField, case_insensitive_char_field +from openedx_django_lib.fields import MultiCollationTextField, case_insensitive_char_field from openedx.core.djangoapps.content.course_overviews.api import get_course_overview_or_none diff --git a/openedx/core/djangoapps/content_tagging/api.py b/openedx/core/djangoapps/content_tagging/api.py index 7f22d1bbc4..13e0d8f8f8 100644 --- a/openedx/core/djangoapps/content_tagging/api.py +++ b/openedx/core/djangoapps/content_tagging/api.py @@ -9,12 +9,12 @@ import csv from typing import Iterator from opaque_keys.edx.keys import CourseKey, CollectionKey, ContainerKey, UsageKey -import openedx_tagging.core.tagging.api as oel_tagging +import openedx_tagging.api as oel_tagging from django.db.models import Exists, OuterRef, Q, QuerySet from django.utils.timezone import now from opaque_keys.edx.locator import LibraryLocatorV2 -from openedx_tagging.core.tagging.models import ObjectTag, Taxonomy -from openedx_tagging.core.tagging.models.utils import TAGS_CSV_SEPARATOR +from openedx_tagging.models import ObjectTag, Taxonomy +from openedx_tagging.models.utils import TAGS_CSV_SEPARATOR from organizations.models import Organization from .helpers.objecttag_export_helpers import build_object_tree_with_objecttags, iterate_with_level from openedx_events.content_authoring.data import ContentObjectData, ContentObjectChangedData diff --git a/openedx/core/djangoapps/content_tagging/auth.py b/openedx/core/djangoapps/content_tagging/auth.py index 73040111ab..4a1157c3bf 100644 --- a/openedx/core/djangoapps/content_tagging/auth.py +++ b/openedx/core/djangoapps/content_tagging/auth.py @@ -3,7 +3,7 @@ Functions to validate the access in content tagging actions """ -from openedx_tagging.core.tagging import rules as oel_tagging_rules +from openedx_tagging import rules as oel_tagging_rules def has_view_object_tags_access(user, object_id): diff --git a/openedx/core/djangoapps/content_tagging/models/base.py b/openedx/core/djangoapps/content_tagging/models/base.py index d799d87951..dcdf5bc684 100644 --- a/openedx/core/djangoapps/content_tagging/models/base.py +++ b/openedx/core/djangoapps/content_tagging/models/base.py @@ -6,7 +6,7 @@ from __future__ import annotations from django.db import models from django.db.models import Q, QuerySet from django.utils.translation import gettext as _ -from openedx_tagging.core.tagging.models import Taxonomy +from openedx_tagging.models import Taxonomy from organizations.models import Organization diff --git a/openedx/core/djangoapps/content_tagging/rest_api/v1/filters.py b/openedx/core/djangoapps/content_tagging/rest_api/v1/filters.py index e4fa403fa5..88695f1ffd 100644 --- a/openedx/core/djangoapps/content_tagging/rest_api/v1/filters.py +++ b/openedx/core/djangoapps/content_tagging/rest_api/v1/filters.py @@ -5,7 +5,7 @@ API Filters for content tagging org from django.db.models import Exists, OuterRef, Q from rest_framework.filters import BaseFilterBackend -import openedx_tagging.core.tagging.rules as oel_tagging +import openedx_tagging.rules as oel_tagging from ...rules import get_admin_orgs, get_user_orgs from ...models import TaxonomyOrg diff --git a/openedx/core/djangoapps/content_tagging/rest_api/v1/serializers.py b/openedx/core/djangoapps/content_tagging/rest_api/v1/serializers.py index bda2ae163c..531ad50863 100644 --- a/openedx/core/djangoapps/content_tagging/rest_api/v1/serializers.py +++ b/openedx/core/djangoapps/content_tagging/rest_api/v1/serializers.py @@ -6,7 +6,7 @@ from __future__ import annotations from rest_framework import serializers, fields -from openedx_tagging.core.tagging.rest_api.v1.serializers import ( +from openedx_tagging.rest_api.v1.serializers import ( ObjectTagMinimalSerializer, TaxonomyListQueryParamsSerializer, TaxonomySerializer, diff --git a/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py b/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py index a4094c301b..0e78b96310 100644 --- a/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py +++ b/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py @@ -15,9 +15,9 @@ from django.contrib.auth import get_user_model from django.core.files.uploadedfile import SimpleUploadedFile from edx_django_utils.cache import RequestCache from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator, LibraryCollectionLocator, LibraryContainerLocator -from openedx_tagging.core.tagging.models import Tag, Taxonomy -from openedx_tagging.core.tagging.models.system_defined import SystemDefinedTaxonomy -from openedx_tagging.core.tagging.rest_api.v1.serializers import TaxonomySerializer +from openedx_tagging.models import Tag, Taxonomy +from openedx_tagging.models.system_defined import SystemDefinedTaxonomy +from openedx_tagging.rest_api.v1.serializers import TaxonomySerializer from organizations.models import Organization from rest_framework import status from rest_framework.test import APITestCase diff --git a/openedx/core/djangoapps/content_tagging/rest_api/v1/urls.py b/openedx/core/djangoapps/content_tagging/rest_api/v1/urls.py index 50fec093c1..a59bcdf2db 100644 --- a/openedx/core/djangoapps/content_tagging/rest_api/v1/urls.py +++ b/openedx/core/djangoapps/content_tagging/rest_api/v1/urls.py @@ -3,9 +3,9 @@ Taxonomies API v1 URLs. """ from django.urls.conf import include, path -from openedx_tagging.core.tagging.rest_api.v1 import views as oel_tagging_views -from openedx_tagging.core.tagging.rest_api.v1 import views_import as oel_tagging_views_import -from openedx_tagging.core.tagging.rest_api.v1.views import ObjectTagCountsView +from openedx_tagging.rest_api.v1 import views as oel_tagging_views +from openedx_tagging.rest_api.v1 import views_import as oel_tagging_views_import +from openedx_tagging.rest_api.v1.views import ObjectTagCountsView from rest_framework.routers import DefaultRouter from . import views diff --git a/openedx/core/djangoapps/content_tagging/rest_api/v1/views.py b/openedx/core/djangoapps/content_tagging/rest_api/v1/views.py index c2da760e93..ca817ab402 100644 --- a/openedx/core/djangoapps/content_tagging/rest_api/v1/views.py +++ b/openedx/core/djangoapps/content_tagging/rest_api/v1/views.py @@ -5,8 +5,8 @@ from __future__ import annotations from django.db.models import Count from django.http import StreamingHttpResponse -from openedx_tagging.core.tagging import rules as oel_tagging_rules -from openedx_tagging.core.tagging.rest_api.v1.views import ObjectTagView, TaxonomyView +from openedx_tagging import rules as oel_tagging_rules +from openedx_tagging.rest_api.v1.views import ObjectTagView, TaxonomyView from rest_framework import status from rest_framework.decorators import action from rest_framework.exceptions import PermissionDenied, ValidationError diff --git a/openedx/core/djangoapps/content_tagging/rules.py b/openedx/core/djangoapps/content_tagging/rules.py index 72b744f5bf..3f798d4053 100644 --- a/openedx/core/djangoapps/content_tagging/rules.py +++ b/openedx/core/djangoapps/content_tagging/rules.py @@ -5,7 +5,7 @@ from __future__ import annotations from typing import Union import django.contrib.auth.models -import openedx_tagging.core.tagging.rules as oel_tagging +import openedx_tagging.rules as oel_tagging import rules from organizations.models import Organization diff --git a/openedx/core/djangoapps/content_tagging/tasks.py b/openedx/core/djangoapps/content_tagging/tasks.py index bd90aad6ea..8f67f737c2 100644 --- a/openedx/core/djangoapps/content_tagging/tasks.py +++ b/openedx/core/djangoapps/content_tagging/tasks.py @@ -12,7 +12,7 @@ from django.contrib.auth import get_user_model from edx_django_utils.monitoring import set_code_owner_attribute from opaque_keys.edx.keys import CourseKey, UsageKey from opaque_keys.edx.locator import LibraryUsageLocatorV2 -from openedx_tagging.core.tagging.models import Taxonomy +from openedx_tagging.models import Taxonomy from xmodule.modulestore.django import modulestore diff --git a/openedx/core/djangoapps/content_tagging/tests/test_api.py b/openedx/core/djangoapps/content_tagging/tests/test_api.py index 2661c02fd1..cff8908d05 100644 --- a/openedx/core/djangoapps/content_tagging/tests/test_api.py +++ b/openedx/core/djangoapps/content_tagging/tests/test_api.py @@ -7,7 +7,7 @@ from django.test.testcases import TestCase from fs.osfs import OSFS from opaque_keys.edx.keys import CourseKey, UsageKey from opaque_keys.edx.locator import LibraryLocatorV2, LibraryCollectionLocator, LibraryContainerLocator -from openedx_tagging.core.tagging.models import ObjectTag +from openedx_tagging.models import ObjectTag from organizations.models import Organization from .test_objecttag_export_helpers import TestGetAllObjectTagsMixin, TaggedCourseMixin diff --git a/openedx/core/djangoapps/content_tagging/tests/test_objecttag_export_helpers.py b/openedx/core/djangoapps/content_tagging/tests/test_objecttag_export_helpers.py index eaeea3bda2..fc6bcdd9ba 100644 --- a/openedx/core/djangoapps/content_tagging/tests/test_objecttag_export_helpers.py +++ b/openedx/core/djangoapps/content_tagging/tests/test_objecttag_export_helpers.py @@ -4,7 +4,7 @@ Test the objecttag_export_helpers module import time from unittest.mock import patch -from openedx_tagging.core.tagging.models import ObjectTag +from openedx_tagging.models import ObjectTag from organizations.models import Organization from openedx.core.djangoapps.content_libraries import api as library_api diff --git a/openedx/core/djangoapps/content_tagging/tests/test_rules.py b/openedx/core/djangoapps/content_tagging/tests/test_rules.py index d53256f510..75926d0941 100644 --- a/openedx/core/djangoapps/content_tagging/tests/test_rules.py +++ b/openedx/core/djangoapps/content_tagging/tests/test_rules.py @@ -4,11 +4,11 @@ import ddt from django.contrib.auth import get_user_model from django.test import TestCase from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator -from openedx_tagging.core.tagging.models import ( +from openedx_tagging.models import ( Tag, UserSystemDefinedTaxonomy, ) -from openedx_tagging.core.tagging.rules import ObjectTagPermissionItem +from openedx_tagging.rules import ObjectTagPermissionItem from common.djangoapps.student.auth import add_users, update_org_role from common.djangoapps.student.roles import CourseStaffRole, OrgStaffRole diff --git a/openedx/core/djangoapps/content_tagging/tests/test_tasks.py b/openedx/core/djangoapps/content_tagging/tests/test_tasks.py index 997fffbaad..39689b37a1 100644 --- a/openedx/core/djangoapps/content_tagging/tests/test_tasks.py +++ b/openedx/core/djangoapps/content_tagging/tests/test_tasks.py @@ -8,7 +8,7 @@ from unittest.mock import patch from django.test import override_settings, LiveServerTestCase from django.http import HttpRequest from edx_toggles.toggles.testutils import override_waffle_flag -from openedx_tagging.core.tagging.models import Tag, Taxonomy, ObjectTag +from openedx_tagging.models import Tag, Taxonomy, ObjectTag from organizations.models import Organization from common.djangoapps.student.tests.factories import UserFactory @@ -41,9 +41,9 @@ class LanguageTaxonomyTestMixin: running migrations. So data created by our migrations is not present. In particular, the Language Taxonomy is not present. So this mixin will create the taxonomy, simulating the effect of the following migrations: - 1. openedx_tagging.core.tagging.migrations.0012_language_taxonomy + 1. openedx_tagging.migrations.0012_language_taxonomy 2. content_tagging.migrations.0007_system_defined_org_2 - 3. openedx_tagging.core.tagging.migrations.0015_taxonomy_export_id + 3. openedx_tagging.migrations.0015_taxonomy_export_id """ super().setUp() Taxonomy.objects.get_or_create(id=-1, defaults={ @@ -54,7 +54,7 @@ class LanguageTaxonomyTestMixin: "allow_free_text": False, "visible_to_authors": True, "export_id": "-1_languages", - "_taxonomy_class": "openedx_tagging.core.tagging.models.system_defined.LanguageTaxonomy", + "_taxonomy_class": "openedx_tagging.models.system_defined.LanguageTaxonomy", }) TaxonomyOrg.objects.get_or_create(taxonomy_id=-1, defaults={"org": None}) diff --git a/openedx/core/djangoapps/content_tagging/types.py b/openedx/core/djangoapps/content_tagging/types.py index 6e54caa051..1b839eb1a0 100644 --- a/openedx/core/djangoapps/content_tagging/types.py +++ b/openedx/core/djangoapps/content_tagging/types.py @@ -7,7 +7,7 @@ from typing import Dict, List, Union from opaque_keys.edx.keys import CourseKey, UsageKey, CollectionKey, ContainerKey from opaque_keys.edx.locator import LibraryLocatorV2 -from openedx_tagging.core.tagging.models import Taxonomy +from openedx_tagging.models import Taxonomy ContentKey = Union[LibraryLocatorV2, CourseKey, UsageKey, CollectionKey, ContainerKey] ContextKey = Union[LibraryLocatorV2, CourseKey] diff --git a/openedx/core/djangoapps/content_tagging/utils.py b/openedx/core/djangoapps/content_tagging/utils.py index f6e4883251..804754a2ff 100644 --- a/openedx/core/djangoapps/content_tagging/utils.py +++ b/openedx/core/djangoapps/content_tagging/utils.py @@ -7,7 +7,7 @@ from edx_django_utils.cache import RequestCache from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey, CollectionKey, ContainerKey, UsageKey from opaque_keys.edx.locator import LibraryLocatorV2 -from openedx_tagging.core.tagging.models import Taxonomy +from openedx_tagging.models import Taxonomy from organizations.models import Organization from .models import TaxonomyOrg diff --git a/openedx/core/djangoapps/xblock/api.py b/openedx/core/djangoapps/xblock/api.py index c0293f614b..f7ada820a9 100644 --- a/openedx/core/djangoapps/xblock/api.py +++ b/openedx/core/djangoapps/xblock/api.py @@ -16,8 +16,8 @@ import threading from django.core.exceptions import PermissionDenied from django.urls import reverse from django.utils.translation import gettext as _ -from openedx_learning.api import authoring as authoring_api -from openedx_learning.api.authoring_models import Component, ComponentVersion +from openedx_content import api as content_api +from openedx_content.models_api import Component, ComponentVersion from opaque_keys.edx.keys import UsageKeyV2 from opaque_keys.edx.locator import LibraryUsageLocatorV2 from rest_framework.exceptions import NotFound @@ -202,10 +202,10 @@ def get_component_from_usage_key(usage_key: UsageKeyV2) -> Component: This is a lower-level function that will return a Component even if there is no current draft version of that Component (because it's been soft-deleted). """ - learning_package = authoring_api.get_learning_package_by_key( + learning_package = content_api.get_learning_package_by_key( str(usage_key.context_key) ) - return authoring_api.get_component_by_key( + return content_api.get_component_by_key( learning_package.id, namespace='xblock.v1', type_name=usage_key.block_type, diff --git a/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py b/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py index 5c8bc81c5f..2e24fc7ba1 100644 --- a/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py +++ b/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py @@ -12,7 +12,7 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.db.transaction import atomic from django.urls import reverse -from openedx_learning.api import authoring as authoring_api +from openedx_content import api as content_api from lxml import etree @@ -295,16 +295,16 @@ class LearningCoreXBlockRuntime(XBlockRuntime): usage_key = block.scope_ids.usage_id with atomic(): component = self._get_component_from_usage_key(usage_key) - block_media_type = authoring_api.get_or_create_media_type( + block_media_type = content_api.get_or_create_media_type( f"application/vnd.openedx.xblock.v1.{usage_key.block_type}+xml" ) - content = authoring_api.get_or_create_text_content( + content = content_api.get_or_create_text_content( component.learning_package_id, block_media_type.id, text=serialized.olx_str, created=now, ) - authoring_api.create_next_version( + content_api.create_next_component_version( component.pk, title=block.display_name, content_to_replace={ @@ -329,9 +329,9 @@ class LearningCoreXBlockRuntime(XBlockRuntime): TODO: This is the third place where we're implementing this. Figure out where the definitive place should be and have everything else call that. """ - learning_package = authoring_api.get_learning_package_by_key(str(usage_key.lib_key)) + learning_package = content_api.get_learning_package_by_key(str(usage_key.lib_key)) try: - component = authoring_api.get_component_by_key( + component = content_api.get_component_by_key( learning_package.id, namespace='xblock.v1', type_name=usage_key.block_type, diff --git a/openedx/core/lib/xblock_serializer/test_api.py b/openedx/core/lib/xblock_serializer/test_api.py index 8787e17918..ab97d1d0f9 100644 --- a/openedx/core/lib/xblock_serializer/test_api.py +++ b/openedx/core/lib/xblock_serializer/test_api.py @@ -8,7 +8,7 @@ from xmodule.modulestore.django import contentstore, modulestore from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase, upload_file_to_course from xmodule.modulestore.tests.factories import BlockFactory, CourseFactory, ToyCourseFactory, LibraryFactory from xmodule.util.sandboxing import DEFAULT_PYTHON_LIB_FILENAME -from openedx_tagging.core.tagging.models import Tag +from openedx_tagging.models import Tag from openedx.core.djangoapps.content_tagging.models import TaxonomyOrg from openedx.core.djangoapps.content_tagging import api as tagging_api diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 5b0bb207a8..27b38ac720 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -63,7 +63,7 @@ numpy<2.0.0 # Date: 2023-09-18 # pinning this version to avoid updates while the library is being developed # Issue for unpinning: https://github.com/openedx/edx-platform/issues/35269 -openedx-learning==0.31.0 +openedx-learning==0.32.0 # Date: 2023-11-29 # Open AI version 1.0.0 dropped support for openai.ChatCompletion which is currently in use in enterprise. @@ -146,4 +146,3 @@ pact-python<3.0.0 # building requirements with Python 3.12 # https://github.com/openedx/edx-platform/issues/37880 sphinx-autoapi<3.6.1 - diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 9ad78e931b..54a1ffbcd8 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -832,7 +832,7 @@ openedx-filters==2.1.0 # ora2 openedx-forum==0.4.0 # via -r requirements/edx/kernel.in -openedx-learning==0.31.0 +openedx-learning==0.32.0 # via # -c requirements/constraints.txt # -r requirements/edx/kernel.in diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 25c480a735..3251e05464 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -1399,7 +1399,7 @@ openedx-forum==0.4.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -openedx-learning==0.31.0 +openedx-learning==0.32.0 # via # -c requirements/constraints.txt # -r requirements/edx/doc.txt diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index 666ccf4f5a..05abbc436a 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -1009,7 +1009,7 @@ openedx-filters==2.1.0 # ora2 openedx-forum==0.4.0 # via -r requirements/edx/base.txt -openedx-learning==0.31.0 +openedx-learning==0.32.0 # via # -c requirements/constraints.txt # -r requirements/edx/base.txt diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 7f94a12e0c..d30dc79442 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -1059,7 +1059,7 @@ openedx-filters==2.1.0 # ora2 openedx-forum==0.4.0 # via -r requirements/edx/base.txt -openedx-learning==0.31.0 +openedx-learning==0.32.0 # via # -c requirements/constraints.txt # -r requirements/edx/base.txt diff --git a/setup.cfg b/setup.cfg index ac0907b667..28ea010b5e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -60,7 +60,7 @@ root_packages = lms cms openedx - openedx_learning + openedx_content include_external_packages = True contract_types = # Our custom contract which checks that we're only importing from 'api.py' @@ -193,14 +193,17 @@ allowed_modules = tests [importlinter:contract:3] -name = Do not import apps from openedx-learning (only import from openedx_learning.api.* and openedx_learning.lib.*). +name = Do not directly import internals of openedx_content (only import from openedx_content.api). type = forbidden source_modules = cms lms openedx + common + xmodule forbidden_modules = - openedx_learning.apps + openedx_content.applets + openedx_content.backcompat allow_indirect_imports = True [importlinter:contract:4]