openedx.core.djangoapps.content.search package

Contents

openedx.core.djangoapps.content.search package#

Subpackages#

Submodules#

openedx.core.djangoapps.content.search.api module#

Content index and search API using Meilisearch

openedx.core.djangoapps.content.search.api.clear_meilisearch_client()#
openedx.core.djangoapps.content.search.api.delete_all_draft_docs_for_library(library_key: LibraryLocatorV2) None#

Deletes draft documents for the given XBlocks from the search index

openedx.core.djangoapps.content.search.api.delete_index_doc(usage_key: UsageKey) None#

Deletes the document for the given XBlock from the search index

Parameters:

usage_key (UsageKey) – The usage key of the XBlock to be removed from the index

Returns a Meilisearch API key that only allows the user to search content that they have permission to view

openedx.core.djangoapps.content.search.api.init_index(status_cb: Callable[[str], None] | None = None, warn_cb: Callable[[str], None] | None = None) None#

Initialize the Meilisearch index, creating it and configuring it if it doesn’t exist

openedx.core.djangoapps.content.search.api.is_meilisearch_enabled() bool#

Returns whether Meilisearch is enabled

openedx.core.djangoapps.content.search.api.only_if_meilisearch_enabled(f)#

Only call f if meilisearch is enabled

openedx.core.djangoapps.content.search.api.rebuild_index(status_cb: Callable[[str], None] | None = None, incremental=False) None#

Rebuild the Meilisearch index from scratch

openedx.core.djangoapps.content.search.api.reset_index(status_cb: Callable[[str], None] | None = None) None#

Reset the Meilisearch index, deleting all documents and reconfiguring it

openedx.core.djangoapps.content.search.api.update_library_components_collections(library_key: LibraryLocatorV2, collection_key: str, batch_size: int = 1000) None#

Updates the “collections” field for all components associated with a given Library Collection.

Because there may be a lot of components, we send these updates to Meilisearch in batches.

openedx.core.djangoapps.content.search.api.upsert_block_collections_index_docs(usage_key: UsageKey)#

Updates the collections data in documents for the given Course/Library block

openedx.core.djangoapps.content.search.api.upsert_block_tags_index_docs(usage_key: UsageKey)#

Updates the tags data in documents for the given Course/Library block

openedx.core.djangoapps.content.search.api.upsert_collection_tags_index_docs(collection_usage_key: LibraryCollectionLocator)#

Updates the tags data in documents for the given library collection

openedx.core.djangoapps.content.search.api.upsert_content_library_index_docs(library_key: LibraryLocatorV2) None#

Creates or updates the documents for the given Content Library in the search index

openedx.core.djangoapps.content.search.api.upsert_library_block_index_doc(usage_key: UsageKey) None#

Creates or updates the document for the given Library Block in the search index

openedx.core.djangoapps.content.search.api.upsert_library_collection_index_doc(library_key: LibraryLocatorV2, collection_key: str) None#

Creates, updates, or deletes the document for the given Library Collection in the search index.

If the Collection is not found or disabled (i.e. soft-deleted), then delete it from the search index.

openedx.core.djangoapps.content.search.api.upsert_xblock_index_doc(usage_key: UsageKey, recursive: bool = True) None#

Creates or updates the document for the given XBlock in the search index

Parameters:
  • usage_key (UsageKey) – The usage key of the XBlock to index

  • recursive (bool) – If True, also index all children of the XBlock

openedx.core.djangoapps.content.search.apps module#

Define the content search Django App.

class openedx.core.djangoapps.content.search.apps.ContentSearchConfig(app_name, app_module)#

Bases: AppConfig

App config for the content search feature

default_auto_field = 'django.db.models.BigAutoField'#
name = 'openedx.core.djangoapps.content.search'#
ready()#

Override this method in subclasses to run code when Django starts.

openedx.core.djangoapps.content.search.documents module#

Utilities related to indexing content for search

class openedx.core.djangoapps.content.search.documents.DocType#

Bases: object

Values for the ‘type’ field on each doc in the search index

collection = 'collection'#
course_block = 'course_block'#
library_block = 'library_block'#
class openedx.core.djangoapps.content.search.documents.Fields#

Bases: object

Fields that exist on the documents in our search index

access_id = 'access_id'#
block_id = 'block_id'#
block_type = 'block_type'#
breadcrumbs = 'breadcrumbs'#
collections = 'collections'#
collections_display_name = 'display_name'#
collections_key = 'key'#
content = 'content'#
context_key = 'context_key'#
created = 'created'#
description = 'description'#
display_name = 'display_name'#
id = 'id'#
last_published = 'last_published'#
modified = 'modified'#
num_children = 'num_children'#
org = 'org'#
problem_types = 'problem_types'#
published = 'published'#
published_description = 'description'#
published_display_name = 'display_name'#
published_num_children = 'num_children'#
tags = 'tags'#
tags_level0 = 'level0'#
tags_level1 = 'level1'#
tags_level2 = 'level2'#
tags_level3 = 'level3'#
tags_taxonomy = 'taxonomy'#
type = 'type'#
usage_key = 'usage_key'#
openedx.core.djangoapps.content.search.documents.meili_id_from_opaque_key(usage_key: UsageKey) str#

Meilisearch requires each document to have a primary key that’s either an integer or a string composed of alphanumeric characters (a-z A-Z 0-9), hyphens (-) and underscores (_). Since our opaque keys don’t meet this requirement, we transform them to a similar slug ID string that does.

In the future, with Learning Core’s data models in place for courseware, we could use PublishableEntity’s primary key / UUID instead.

openedx.core.djangoapps.content.search.documents.searchable_doc_collections(usage_key: UsageKey) dict#

Generate a dictionary document suitable for ingestion into a search engine like Meilisearch or Elasticsearch, with the collections data for the given content object.

openedx.core.djangoapps.content.search.documents.searchable_doc_for_collection(library_key: LibraryLocatorV2, collection_key: str, *, collection: Collection | None = None) dict#

Generate a dictionary document suitable for ingestion into a search engine like Meilisearch or Elasticsearch, so that the given collection can be found using faceted search.

If no collection is found for the given library_key + collection_key, the returned document will contain only basic information derived from the collection usage key, and no Fields.type value will be included in the returned dict.

openedx.core.djangoapps.content.search.documents.searchable_doc_for_course_block(block) dict#

Generate a dictionary document suitable for ingestion into a search engine like Meilisearch or Elasticsearch, so that the given course block can be found using faceted search.

openedx.core.djangoapps.content.search.documents.searchable_doc_for_library_block(xblock_metadata: LibraryXBlockMetadata) dict#

Generate a dictionary document suitable for ingestion into a search engine like Meilisearch or Elasticsearch, so that the given library block can be found using faceted search.

Datetime fields (created, modified, last_published) are serialized to POSIX timestamps so that they can be used to sort the search results.

openedx.core.djangoapps.content.search.documents.searchable_doc_for_usage_key(usage_key: UsageKey) dict#

Generates a base document identified by its usage key.

openedx.core.djangoapps.content.search.documents.searchable_doc_tags(usage_key: UsageKey) dict#

Generate a dictionary document suitable for ingestion into a search engine like Meilisearch or Elasticsearch, with the tags data for the given content object.

openedx.core.djangoapps.content.search.documents.searchable_doc_tags_for_collection(library_key: LibraryLocatorV2, collection_key: str) dict#

Generate a dictionary document suitable for ingestion into a search engine like Meilisearch or Elasticsearch, with the tags data for the given library collection.

openedx.core.djangoapps.content.search.handlers module#

Signal/event handlers for content search

openedx.core.djangoapps.content.search.handlers.content_library_updated_handler(**kwargs) None#

Update the index for the content library

openedx.core.djangoapps.content.search.handlers.content_object_associations_changed_handler(**kwargs) None#

Update the collections/tags data in the index for the Content Object

openedx.core.djangoapps.content.search.handlers.delete_course_search_access(sender, instance, **kwargs)#

Deletes the SearchAccess instance for deleted CourseOverview

openedx.core.djangoapps.content.search.handlers.delete_library_search_access(content_library: ContentLibraryData, **kwargs)#

Deletes the SearchAccess instance for deleted content libraries

openedx.core.djangoapps.content.search.handlers.library_block_deleted(**kwargs) None#

Delete the index for the content library block

openedx.core.djangoapps.content.search.handlers.library_block_updated_handler(**kwargs) None#

Create or update the index for the content library block

openedx.core.djangoapps.content.search.handlers.library_collection_updated_handler(**kwargs) None#

Create or update the index for the content library collection

openedx.core.djangoapps.content.search.handlers.xblock_created_handler(**kwargs) None#

Create the index for the XBlock

openedx.core.djangoapps.content.search.handlers.xblock_deleted_handler(**kwargs) None#

Delete the index for the XBlock

openedx.core.djangoapps.content.search.handlers.xblock_updated_handler(**kwargs) None#

Update the index for the XBlock and its children

openedx.core.djangoapps.content.search.index_config module#

Configuration for the search index.

openedx.core.djangoapps.content.search.models module#

Database models for content search

class openedx.core.djangoapps.content.search.models.IncrementalIndexCompleted(*args, **kwargs)#

Bases: Model

Stores the contex keys of aleady indexed courses and libraries for incremental indexing.

exception DoesNotExist#

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

context_key#

DO NOT REUSE THIS CLASS. Provided for backwards compatibility only!

A placeholder class that provides a way to set the attribute on the model.

id#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <django.db.models.manager.Manager object>#
class openedx.core.djangoapps.content.search.models.SearchAccess(*args, **kwargs)#

Bases: Model

Stores a numeric ID for each ContextKey.

We use this shorter ID instead of the full ContextKey when determining a user’s access to search-indexed course and library content because:

  1. in some deployments, users may be granted access to more than 1_000 individual courses, and

  2. the search filter request is stored in the JWT, which is limited to 8Kib.

exception DoesNotExist#

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

context_key#

DO NOT REUSE THIS CLASS. Provided for backwards compatibility only!

A placeholder class that provides a way to set the attribute on the model.

id#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <django.db.models.manager.Manager object>#
openedx.core.djangoapps.content.search.models.get_access_ids_for_request(request: Request, omit_orgs: list[str] = None) list[int]#

Returns a list of SearchAccess.id values for courses and content libraries that the requesting user has been individually grated access to.

Omits any courses/libraries with orgs in the omit_orgs list.

openedx.core.djangoapps.content.search.tasks module#

Defines asynchronous celery task for content indexing

openedx.core.djangoapps.content.search.urls module#

URLs for content sesarch

openedx.core.djangoapps.content.search.views module#

REST API for content search

class openedx.core.djangoapps.content.search.views.StudioSearchView(**kwargs)#

Bases: APIView

Give user details on how they can search studio content

authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>, <class 'openedx.core.lib.api.authentication.BearerAuthenticationAllowInactiveUser'>, <class 'edx_rest_framework_extensions.auth.session.authentication.SessionAuthenticationAllowInactiveUser'>)#
get(request)#

Give user details on how they can search studio content

permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#

Module contents#