openedx.core.djangoapps.content_libraries package#
Subpackages#
Submodules#
openedx.core.djangoapps.content_libraries.api module#
Python API for content libraries#
Via views.py, most of these API methods are also exposed as a REST API.
The API methods in this file are focused on authoring and specific to content libraries; they wouldn’t necessarily apply or work in other learning contexts such as courses, blogs, “pathways,” etc.
** As this is an authoring-focused API, all API methods in this file deal with the DRAFT version of the content library.**
Some of these methods will work and may be used from the LMS if needed (mostly for test setup; other use is discouraged), but some of the implementation details rely on Studio so other methods will raise errors if called from the LMS. (The REST API is not available at all from the LMS.)
Any APIs that use/affect content libraries but are generic enough to work in
other learning contexts too are in the core XBlock python/REST API at
openedx.core.djangoapps.xblock.api/rest_api.
For example, to render a content library XBlock as HTML, one can use the generic:
render_block_view(block, view_name, user)
That is an API in openedx.core.djangoapps.xblock.api (use it from Studio for
the draft version, from the LMS for published version).
There are one or two methods in this file that have some overlap with the core
XBlock API; for example, this content library API provides a
get_library_block() which returns metadata about an XBlock; it’s in this API
because it also returns data about whether or not the XBlock has unpublished
edits, which is an authoring-only concern. Likewise, APIs for getting/setting
an individual XBlock’s OLX directly seem more appropriate for small, reusable
components in content libraries and may not be appropriate for other learning
contexts so they are implemented here in the library API only. In the future,
if we find a need for these in most other learning contexts then those methods
could be promoted to the core XBlock API and made generic.
Import from Courseware#
Content Libraries can import blocks from Courseware (Modulestore). The import
can be done per-course, by listing its content, and supports both access to
remote platform instances as well as local modulestore APIs. Additionally,
there are Celery-based interfaces suitable for background processing controlled
through RESTful APIs (see views).
- class openedx.core.djangoapps.content_libraries.api.AccessLevel#
Bases:
objectEnum defining library access levels/permissions
- ADMIN_LEVEL = 'admin'#
- AUTHOR_LEVEL = 'author'#
- NO_ACCESS = None#
- READ_LEVEL = 'read'#
- class openedx.core.djangoapps.content_libraries.api.BaseEdxImportClient(library_key=None, library=None, use_course_key_as_block_id_suffix=True)#
Bases:
ABCBase class for all courseware import clients.
Import clients are wrappers tailored to implement the steps used in the import APIs and can leverage different backends. It is not aimed towards being a generic API client for Open edX.
- EXPORTABLE_BLOCK_TYPES = {'drag-and-drop-v2', 'html', 'problem', 'video'}#
- abstract get_block_data(block_key)#
Get the block’s OLX and static files, if any.
- abstract get_block_static_data(asset_file)#
Get the contents of an asset_file..
- abstract get_export_keys(course_key)#
Get all exportable block keys of a given course.
- import_block(modulestore_key)#
Import a single modulestore block.
- import_blocks_from_course(course_key, progress_callback)#
Import all eligible blocks from course key.
Progress is reported through
progress_callback, guaranteed to be called within an exception handler ifexception is not None.
- exception openedx.core.djangoapps.content_libraries.api.BlockLimitReachedError#
Bases:
ExceptionMaximum number of allowed XBlocks in the library reached
- exception openedx.core.djangoapps.content_libraries.api.ContentLibraryBlockNotFound(usage_id)#
Bases:
XBlockNotFoundErrorXBlock not found in the content library
- class openedx.core.djangoapps.content_libraries.api.ContentLibraryMetadata(key: LibraryLocatorV2, title='', description='', num_blocks=0, version=0, type='complex', last_published: datetime | None = None, has_unpublished_changes=False, has_unpublished_deletes=False, allow_lti=False, allow_public_learning=False, allow_public_read=False, license='')#
Bases:
objectClass that represents the metadata about a content library.
- class openedx.core.djangoapps.content_libraries.api.ContentLibraryPermissionEntry(user: AbstractUser | None = None, group: Group | None = None, access_level=None)#
Bases:
objectA user or group granted permission to use a content library.
- class openedx.core.djangoapps.content_libraries.api.EdxApiImportClient(lms_url, studio_url, oauth_key, oauth_secret, *args, **kwargs)#
Bases:
BaseEdxImportClientAn import client based on a remote Open Edx API interface.
TODO: Look over this class. We’ll probably need to completely re-implement the import process.
- URL_COURSES = '/api/courses/v1/courses/{course_key}'#
- URL_MODULESTORE_BLOCK_OLX = '/api/olx-export/v1/xblock/{block_key}/'#
- get_block_data(block_key)#
See parent’s docstring.
- get_block_static_data(asset_file)#
See parent’s docstring.
- get_export_keys(course_key)#
See parent’s docstring.
- class openedx.core.djangoapps.content_libraries.api.EdxModulestoreImportClient(modulestore_instance=None, **kwargs)#
Bases:
BaseEdxImportClientAn import client based on the local instance of modulestore.
- get_block_data(block_key)#
Get block OLX by serializing it from modulestore directly.
- get_block_static_data(asset_file)#
Get static content from its URL if available, otherwise from its data.
- get_export_keys(course_key)#
Retrieve the course from modulestore and traverse its content tree.
- exception openedx.core.djangoapps.content_libraries.api.IncompatibleTypesError#
Bases:
ExceptionLibrary type constraint violated
- exception openedx.core.djangoapps.content_libraries.api.InvalidNameError#
Bases:
ValueErrorThe specified name/identifier is not valid
- exception openedx.core.djangoapps.content_libraries.api.LibraryAlreadyExists#
Bases:
KeyErrorA library with the specified slug already exists
- exception openedx.core.djangoapps.content_libraries.api.LibraryBlockAlreadyExists#
Bases:
KeyErrorAn XBlock with that ID already exists in the library
- exception openedx.core.djangoapps.content_libraries.api.LibraryPermissionIntegrityError#
Bases:
IntegrityErrorThrown when an operation would cause insane permissions.
- class openedx.core.djangoapps.content_libraries.api.LibraryXBlockMetadata(usage_key: LibraryUsageLocatorV2, display_name='', has_unpublished_changes=False, tags_count=0)#
Bases:
objectClass that represents the metadata about an XBlock in a content library.
- classmethod from_component(library_key, component)#
Construct a LibraryXBlockMetadata from a Component object.
- class openedx.core.djangoapps.content_libraries.api.LibraryXBlockStaticFile(path='', url='', size=0)#
Bases:
objectClass that represents a static file in a content library, associated with a particular XBlock.
- class openedx.core.djangoapps.content_libraries.api.LibraryXBlockType(block_type='', display_name='')#
Bases:
objectAn XBlock type that can be added to a content library
- openedx.core.djangoapps.content_libraries.api.add_library_block_static_asset_file(usage_key, file_name, file_content) LibraryXBlockStaticFile#
Upload a static asset file into the library, to be associated with the specified XBlock. Will silently overwrite an existing file of the same name.
- file_name should be a name like “doc.pdf”. It may optionally contain slashes
like ‘en/doc.pdf’
file_content should be a binary string.
Returns a LibraryXBlockStaticFile object.
Sends a LIBRARY_BLOCK_UPDATED event.
Example
video_block = UsageKey.from_string(“lb:VideoTeam:python-intro:video:1”) add_library_block_static_asset_file(video_block, “subtitles-en.srt”, subtitles.encode(‘utf-8’))
- openedx.core.djangoapps.content_libraries.api.create_library(org, slug, title, description='', allow_public_learning=False, allow_public_read=False, library_license='', library_type='complex')#
Create a new content library.
org: an organizations.models.Organization instance
slug: a slug for this library like ‘physics-problems’
title: title for this library
description: description of this library
allow_public_learning: Allow anyone to read/learn from blocks in the LMS
allow_public_read: Allow anyone to view blocks (including source) in Studio?
library_type: Deprecated parameter, not really used. Set to COMPLEX.
Returns a ContentLibraryMetadata instance.
- openedx.core.djangoapps.content_libraries.api.create_library_block(library_key, block_type, definition_id)#
Create a new XBlock in this library of the specified type (e.g. “html”).
- openedx.core.djangoapps.content_libraries.api.delete_library(library_key)#
Delete a content library
- openedx.core.djangoapps.content_libraries.api.delete_library_block(usage_key, remove_from_parent=True)#
Delete the specified block from this library (soft delete).
- openedx.core.djangoapps.content_libraries.api.delete_library_block_static_asset_file(usage_key, file_name)#
Delete a static asset file from the library.
Sends a LIBRARY_BLOCK_UPDATED event.
Example
video_block = UsageKey.from_string(“lb:VideoTeam:python-intro:video:1”) delete_library_block_static_asset_file(video_block, “subtitles-en.srt”)
- openedx.core.djangoapps.content_libraries.api.get_allowed_block_types(library_key)#
Get a list of XBlock types that can be added to the specified content library.
- openedx.core.djangoapps.content_libraries.api.get_libraries_for_user(user, org=None, library_type=None, text_search=None)#
Return content libraries that the user has permission to view.
- openedx.core.djangoapps.content_libraries.api.get_library(library_key)#
Get the library with the specified key. Does not check permissions. returns a ContentLibraryMetadata instance.
Raises ContentLibraryNotFound if the library doesn’t exist.
- openedx.core.djangoapps.content_libraries.api.get_library_block(usage_key) LibraryXBlockMetadata#
Get metadata about (the draft version of) one specific XBlock in a library.
This will raise ContentLibraryBlockNotFound if there is no draft version of this block (i.e. it’s been soft-deleted from Studio), even if there is a live published version of it in the LMS.
- openedx.core.djangoapps.content_libraries.api.get_library_block_static_asset_files(usage_key) list[LibraryXBlockStaticFile]#
Given an XBlock in a content library, list all the static asset files associated with that XBlock.
Returns a list of LibraryXBlockStaticFile objects, sorted by path.
TODO: This is not yet implemented for Learning Core backed libraries. TODO: Should this be in the general XBlock API rather than the libraries API?
- openedx.core.djangoapps.content_libraries.api.get_library_components(library_key, text_search=None, block_types=None) QuerySet#
Get the library components and filter.
TODO: Full text search needs to be implemented as a custom lookup for MySQL, but it should have a fallback to still work in SQLite.
- openedx.core.djangoapps.content_libraries.api.get_library_team(library_key)#
Get the list of users/groups granted permission to use this library.
- openedx.core.djangoapps.content_libraries.api.get_library_user_permissions(library_key, user)#
Fetch the specified user’s access information. Will return None if no permissions have been granted.
- openedx.core.djangoapps.content_libraries.api.get_metadata(queryset, text_search=None)#
Take a list of ContentLibrary objects and return metadata from Learning Core.
- openedx.core.djangoapps.content_libraries.api.get_or_create_olx_media_type(block_type: str) MediaType#
Get or create a MediaType for the block type.
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.
- openedx.core.djangoapps.content_libraries.api.get_v1_or_v2_library(library_id: str | LibraryLocatorV1 | LibraryLocatorV2, version: str | int | None) LibraryRootV1 | ContentLibraryMetadata | None#
Fetch either a V1 or V2 content library from a V1/V2 key (or key string) and version.
V1 library versions are Mongo ObjectID strings. V2 library versions can be positive ints, or strings of positive ints. Passing version=None will return the latest version the library.
Returns None if not found. If key is invalid, raises InvalidKeyError. For V1, if key has a version, it is ignored in favor of version. For V2, if version is provided but it isn’t an int or parseable to one, we raise a ValueError.
Examples: * get_v1_or_v2_library(“library-v1:ProblemX+PR0B”, None) -> <LibraryRootV1> * get_v1_or_v2_library(“library-v1:ProblemX+PR0B”, “65ff…”) -> <LibraryRootV1> * get_v1_or_v2_library(“lib:RG:rg-1”, None) -> <ContentLibraryMetadata> * get_v1_or_v2_library(“lib:RG:rg-1”, “36”) -> <ContentLibraryMetadata> * get_v1_or_v2_library(“lib:RG:rg-1”, “xyz”) -> <ValueError> * get_v1_or_v2_library(“notakey”, “xyz”) -> <InvalidKeyError>
If you just want to get a V2 library, use get_library instead.
- openedx.core.djangoapps.content_libraries.api.import_blocks_create_task(library_key, course_key, use_course_key_as_block_id_suffix=True)#
Create a new import block task.
This API will schedule a celery task to perform the import, and it returns a import task object for polling.
- openedx.core.djangoapps.content_libraries.api.publish_changes(library_key)#
Publish all pending changes to the specified library.
- openedx.core.djangoapps.content_libraries.api.require_permission_for_library_key(library_key, user, permission)#
Given any of the content library permission strings defined in openedx.core.djangoapps.content_libraries.permissions, check if the given user has that permission for the library with the specified library ID.
Raises django.core.exceptions.PermissionDenied if the user doesn’t have permission.
- openedx.core.djangoapps.content_libraries.api.revert_changes(library_key)#
Revert all pending changes to the specified library, restoring it to the last published version.
- openedx.core.djangoapps.content_libraries.api.set_library_block_olx(usage_key, new_olx_str)#
Replace the OLX source of the given XBlock.
This is only meant for use by developers or API client applications, as very little validation is done and this can easily result in a broken XBlock that won’t load.
- openedx.core.djangoapps.content_libraries.api.set_library_group_permissions(library_key, group, access_level)#
Change the specified group’s level of access to this library.
access_level should be one of the AccessLevel values defined above.
- openedx.core.djangoapps.content_libraries.api.set_library_user_permissions(library_key, user, access_level)#
Change the specified user’s level of access to this library.
access_level should be one of the AccessLevel values defined above.
- openedx.core.djangoapps.content_libraries.api.update_library(library_key, title=None, description=None, allow_public_learning=None, allow_public_read=None, library_type=None, library_license=None)#
Update a library’s metadata (Slug cannot be changed as it would break IDs throughout the system.)
A value of None means “don’t change”.
openedx.core.djangoapps.content_libraries.apps module#
Django AppConfig for Content Libraries Implementation
- class openedx.core.djangoapps.content_libraries.apps.ContentLibrariesConfig(app_name, app_module)#
Bases:
AppConfigDjango AppConfig for Content Libraries Implementation
- name = 'openedx.core.djangoapps.content_libraries'#
- plugin_app = {'settings_config': {'cms.djangoapp': {}}, 'url_config': {'cms.djangoapp': {'namespace': 'content_libraries'}}}#
- ready()#
Import signal handler’s module to ensure they are registered.
- verbose_name = 'Content Libraries (Blockstore-based)'#
openedx.core.djangoapps.content_libraries.auth module#
Content Library LTI authentication.
This module offers an authentication backend to support LTI launches within content libraries.
- class openedx.core.djangoapps.content_libraries.auth.LtiAuthenticationBackend#
Bases:
ModelBackendAuthenticate based on content library LTI profile.
The backend assumes the profile was previously created and its presence is enough to assume the launch claims are valid.
- authenticate(request, iss=None, aud=None, sub=None, **kwargs)#
Authenticate if the user in the request has an LTI profile.
openedx.core.djangoapps.content_libraries.constants module#
Constants used for the content libraries.
openedx.core.djangoapps.content_libraries.library_context module#
Definition of “Library” as a learning context.
- class openedx.core.djangoapps.content_libraries.library_context.LibraryContextImpl(**kwargs)#
Bases:
LearningContextImplements content libraries as a learning context.
This is the new content libraries based on Blockstore, not the old content libraries based on modulestore.
- block_exists(usage_key)#
Does the block for this usage_key exist in this Library?
Note that this applies to all versions, i.e. you can put a usage key for a piece of content that has been soft-deleted (removed from Drafts), and it will still return True here. That’s because for the purposes of permission checking, we just want to know whether that block has ever existed in this Library, because we could be looking at any older version of it.
- can_edit_block(user, usage_key)#
Does the specified usage key exist in its context, and if so, does the specified user have permission to edit it (make changes to the authored data store)?
user: a Django User object (may be an AnonymousUser)
usage_key: the UsageKeyV2 subclass used for this learning context
Must return a boolean.
- can_view_block(user, usage_key)#
Does the specified usage key exist in its context, and if so, does the specified user have permission to view it and interact with it (call handlers, save user state, etc.)?
user: a Django User object (may be an AnonymousUser)
usage_key: the UsageKeyV2 subclass used for this learning context
Must return a boolean.
openedx.core.djangoapps.content_libraries.models module#
Content Libraries Models#
This module contains the models for new Content Libraries.
LTI 1.3 Models#
Content Libraries serves blockstore-based content through LTI 1.3 launches. The interface supports resource link launches and grading services. Two use cases justify the current data model to support LTI launches. They are:
Authentication and authorization. This use case demands management of user lifecycle to authorize access to content and grade submission, and it introduces a model to own the authentication business logic related to LTI.
Grade and assignments. When AGS is supported, content libraries store additional information concerning the launched resource so that, once the grading sub-system submits the score, it can retrieve them to propagate the score update into the LTI platform’s grade book.
Relationship with LMS’s lti_provider` models#
The data model above is similar to the one provided by the current LTI 1.1 implementation for modulestore and courseware content. But, Content Libraries is orthogonal. Its use-case is to offer standalone, embedded content from a specific backend (blockstore). As such, it decouples from LTI 1.1. and the logic assume no relationship or impact across the two applications. The same reasoning applies to steps beyond the data model, such as at the XBlock runtime, authentication, and score handling, etc.
- class openedx.core.djangoapps.content_libraries.models.ContentLibrary(*args, **kwargs)#
Bases:
ModelA Content Library is a collection of content (XBlocks and/or static assets)
All actual content is stored in Blockstore, and any data that we’d want to transfer to another instance if this library were exported and then re-imported on another Open edX instance should be kept in Blockstore. This model in Studio should only be used to track settings specific to this Open edX instance, like who has permission to edit this content library.
- exception DoesNotExist#
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned#
Bases:
MultipleObjectsReturned
- property allow_lti#
True if there is at least one LTI tool configuration associated if this library.
- allow_public_learning#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- allow_public_read#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- classmethod authorize_lti_launch(library_key, *, issuer, client_id=None)#
Check if the given Issuer and Client ID are authorized to launch content from this library.
- authorized_lti_configs#
Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.
In the example:
class Pizza(Model): toppings = ManyToManyField(Topping, related_name='pizzas')
Pizza.toppingsandTopping.pizzasareManyToManyDescriptorinstances.Most of the implementation is delegated to a dynamically defined manager class built by
create_forward_many_to_many_manager()defined below.
- bundle_uuid#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- get_license_display(*, field=<django.db.models.fields.CharField: license>)#
- get_type_display(*, field=<django.db.models.fields.CharField: type>)#
- id#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- import_tasks#
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Parent.childrenis aReverseManyToOneDescriptorinstance.Most of the implementation is delegated to a dynamically defined manager class built by
create_forward_many_to_many_manager()defined below.
- learning_package#
Accessor to the related object on the forward side of a one-to-one relation.
In the example:
class Restaurant(Model): place = OneToOneField(Place, related_name='restaurant')
Restaurant.placeis aForwardOneToOneDescriptorinstance.
- learning_package_id#
- property library_key#
Get the LibraryLocatorV2 opaque key for this library
- license#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- objects: ContentLibraryManager = <openedx.core.djangoapps.content_libraries.models.ContentLibraryManager object>#
- org#
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- org_id#
- permission_grants#
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Parent.childrenis aReverseManyToOneDescriptorinstance.Most of the implementation is delegated to a dynamically defined manager class built by
create_forward_many_to_many_manager()defined below.
- slug#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- type#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- class openedx.core.djangoapps.content_libraries.models.ContentLibraryBlockImportTask(*args, **kwargs)#
Bases:
ModelModel of a task to import blocks from an external source (e.g. modulestore).
- exception DoesNotExist#
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned#
Bases:
MultipleObjectsReturned
- TASK_CREATED = 'created'#
- TASK_FAILED = 'failed'#
- TASK_PENDING = 'pending'#
- TASK_RUNNING = 'running'#
- TASK_STATE_CHOICES = (('created', 'Task was created, but not queued to run.'), ('pending', 'Task was created and queued to run.'), ('running', 'Task is running.'), ('failed', 'Task finished, but some blocks failed to import.'), ('successful', 'Task finished successfully.'))#
- TASK_SUCCESSFUL = 'successful'#
- course_id#
DO NOT REUSE THIS CLASS. Provided for backwards compatibility only!
A placeholder class that provides a way to set the attribute on the model.
- created_at#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- classmethod execute(import_task_id)#
A context manager to manage a task that is being executed.
- get_next_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=True, **kwargs)#
- get_next_by_updated_at(*, field=<django.db.models.fields.DateTimeField: updated_at>, is_next=True, **kwargs)#
- get_previous_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=False, **kwargs)#
- get_previous_by_updated_at(*, field=<django.db.models.fields.DateTimeField: updated_at>, is_next=False, **kwargs)#
- get_state_display(*, field=<django.db.models.fields.CharField: state>)#
- id#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- library#
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- library_id#
- objects = <django.db.models.manager.Manager object>#
- progress#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- save_progress(progress)#
- state#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- updated_at#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- class openedx.core.djangoapps.content_libraries.models.ContentLibraryManager(*args, **kwargs)#
Bases:
ManagerCustom manager for ContentLibrary class.
- get_by_key(library_key)#
Get the ContentLibrary for the given LibraryLocatorV2 key.
- class openedx.core.djangoapps.content_libraries.models.ContentLibraryPermission(*args, **kwargs)#
Bases:
ModelRow recording permissions for a content library
- ACCESS_LEVEL_CHOICES = (('admin', 'Administer users and author content'), ('author', 'Author content'), ('read', 'Read-only'))#
- ADMIN_LEVEL = 'admin'#
- AUTHOR_LEVEL = 'author'#
- exception DoesNotExist#
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned#
Bases:
MultipleObjectsReturned
- READ_LEVEL = 'read'#
- access_level#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- get_access_level_display(*, field=<django.db.models.fields.CharField: access_level>)#
- group#
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- group_id#
- id#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- library#
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- library_id#
- objects = <django.db.models.manager.Manager object>#
- save(*args, **kwargs)#
Validate any constraints on the model.
We can remove this and replace it with a proper database constraint once we’re upgraded to Django 2.2+
- user#
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- user_id#
- class openedx.core.djangoapps.content_libraries.models.LtiGradedResource(*args, **kwargs)#
Bases:
ModelA content libraries resource launched through LTI with AGS enabled.
Essentially, an instance of this model represents a successful LTI AGS launch. This model links the profile that launched the resource with the resource itself, allowing identifcation of the link through its usage key string and user id.
- exception DoesNotExist#
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned#
Bases:
MultipleObjectsReturned
- ags_lineitem#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- id#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- objects = <openedx.core.djangoapps.content_libraries.models.LtiGradedResourceManager object>#
- profile#
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- profile_id#
- resource_id#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- resource_title#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- update_score(weighted_earned, weighted_possible, timestamp)#
Use LTI’s score service to update the LTI platform’s gradebook.
This method synchronously send a request to the LTI platform to update the assignment score.
- usage_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.
- class openedx.core.djangoapps.content_libraries.models.LtiGradedResourceManager(*args, **kwargs)#
Bases:
ManagerA custom manager for the graded resources model.
- get_from_user_id(user_id, **kwds)#
Retrieve a resource for a given user id holding an lti profile.
- upsert_from_ags_launch(user, block, resource_endpoint, resource_link)#
Update or create a graded resource at AGS launch.
- class openedx.core.djangoapps.content_libraries.models.LtiProfile(*args, **kwargs)#
Bases:
ModelContent Libraries LTI’s profile for Open edX users.
Unless Anonymous, this should be a unique representation of the LTI subject (as per the client token
subidentify claim) that initiated an LTI launch through Content Libraries.- exception DoesNotExist#
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned#
Bases:
MultipleObjectsReturned
- client_id#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- created_at#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- get_next_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=True, **kwargs)#
- get_previous_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=False, **kwargs)#
- id#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- lti_resources#
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Parent.childrenis aReverseManyToOneDescriptorinstance.Most of the implementation is delegated to a dynamically defined manager class built by
create_forward_many_to_many_manager()defined below.
- objects = <openedx.core.djangoapps.content_libraries.models.LtiProfileManager object>#
- platform_id#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- save(*args, **kwds)#
Get or create an edx user on save.
- subject_id#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- property subject_url#
An local URL that is known to uniquely identify this profile.
We take advantage of the fact that platform id is required to be an URL and append paths with the reamaining keys to it.
- user#
Accessor to the related object on the forward side of a one-to-one relation.
In the example:
class Restaurant(Model): place = OneToOneField(Place, related_name='restaurant')
Restaurant.placeis aForwardOneToOneDescriptorinstance.
- user_id#
- class openedx.core.djangoapps.content_libraries.models.LtiProfileManager(*args, **kwargs)#
Bases:
ManagerCustom manager of LtiProfile mode.
- get_from_claims(*, iss, aud, sub)#
Get the an instance from a LTI launch claims.
- get_or_create_from_claims(*, iss, aud, sub)#
Get or create an instance from a LTI launch claims.
openedx.core.djangoapps.content_libraries.permissions module#
Permissions for Content Libraries (v2, Blockstore-based)
openedx.core.djangoapps.content_libraries.serializers module#
Serializers for the content libraries REST API
- class openedx.core.djangoapps.content_libraries.serializers.BaseFilterSerializer(*args, **kwargs)#
Bases:
SerializerBase serializer for filtering listings on the content library APIs.
- class openedx.core.djangoapps.content_libraries.serializers.ContentLibraryAddPermissionByEmailSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for adding a new user and granting their access level via their email address.
- class openedx.core.djangoapps.content_libraries.serializers.ContentLibraryBlockImportTaskCreateSerializer(*args, **kwargs)#
Bases:
SerializerSerializer to create a new block import task.
The serializer accepts the following parameter:
The courseware course key to import blocks from.
- class openedx.core.djangoapps.content_libraries.serializers.ContentLibraryBlockImportTaskSerializer(*args, **kwargs)#
Bases:
ModelSerializerSerializer for a Content Library block import task.
- class Meta#
Bases:
object- fields = '__all__'#
- model#
alias of
ContentLibraryBlockImportTask
- get_org(obj)#
- class openedx.core.djangoapps.content_libraries.serializers.ContentLibraryFilterSerializer(*args, **kwargs)#
Bases:
BaseFilterSerializerSerializer for filtering library listings.
- class openedx.core.djangoapps.content_libraries.serializers.ContentLibraryMetadataSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for ContentLibraryMetadata
- class openedx.core.djangoapps.content_libraries.serializers.ContentLibraryPermissionLevelSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for the “Access Level” of a ContentLibraryPermission object.
This is used when updating a user or group’s permissions re some content library.
- class openedx.core.djangoapps.content_libraries.serializers.ContentLibraryPermissionSerializer(*args, **kwargs)#
Bases:
ContentLibraryPermissionLevelSerializerSerializer for a ContentLibraryPermission object, which grants either a user or a group permission to view a content library.
- class openedx.core.djangoapps.content_libraries.serializers.ContentLibraryUpdateSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for updating an existing content library
- class openedx.core.djangoapps.content_libraries.serializers.LibraryXBlockCreationSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for adding a new XBlock to a content library
- class openedx.core.djangoapps.content_libraries.serializers.LibraryXBlockMetadataSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for LibraryXBlockMetadata
- class openedx.core.djangoapps.content_libraries.serializers.LibraryXBlockOlxSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for representing an XBlock’s OLX
- class openedx.core.djangoapps.content_libraries.serializers.LibraryXBlockStaticFileSerializer(*args, **kwargs)#
Bases:
SerializerSerializer representing a static file associated with an XBlock
Serializes a LibraryXBlockStaticFile (or a BundleFile)
- to_representation(instance)#
Generate the serialized representation of this static asset file.
- class openedx.core.djangoapps.content_libraries.serializers.LibraryXBlockStaticFilesSerializer(*args, **kwargs)#
Bases:
SerializerSerializer representing a static file associated with an XBlock
Serializes a LibraryXBlockStaticFile (or a BundleFile)
- class openedx.core.djangoapps.content_libraries.serializers.LibraryXBlockTypeSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for LibraryXBlockType
openedx.core.djangoapps.content_libraries.signal_handlers module#
Content library signal handlers.
- openedx.core.djangoapps.content_libraries.signal_handlers.score_changed_handler(sender, **kwargs)#
Match the score event to an LTI resource and update.
openedx.core.djangoapps.content_libraries.tasks module#
Celery tasks for Content Libraries.
Architecture note:
Several functions in this file manage the copying/updating of blocks in modulestore and blockstore. These operations should only be performed within the context of CMS. However, due to existing edx-platform code structure, we’ve had to define the functions in shared source tree (openedx/) and the tasks are registered in both LMS and CMS.
To ensure that we’re not accidentally importing things from blockstore in the LMS context, we use ensure_cms throughout this module.
A longer-term solution to this issue would be to move the content_libraries app to cms: openedx/edx-platform#33428
- class openedx.core.djangoapps.content_libraries.tasks.LibrarySyncChildrenTask#
Bases:
UserTaskBase class for tasks which operate upon library_content children.
- classmethod generate_name(arguments_dict) str#
Create a name for this particular import task instance.
Should be both: a. semi human-friendly b. something we can query in order to determine whether the dest block has a task in progress
- Parameters:
arguments_dict (dict) – The arguments given to the task function
- ignore_result = False#
If enabled the worker won’t store task state and return values for this task. Defaults to the :setting:`task_ignore_result` setting.
- priority = None#
Default task priority.
- rate_limit = None#
None(no rate limit), ‘100/s’ (hundred tasks a second), ‘100/m’ (hundred tasks a minute),`’100/h’` (hundred tasks an hour)- Type:
Rate limit for this task type. Examples
- reject_on_worker_lost = None#
Even if
acks_lateis enabled, the worker will acknowledge tasks when the worker process executing them abruptly exits or is signaled (e.g., :sig:`KILL`/:sig:`INT`, etc).Setting this to true allows the message to be re-queued instead, so that the task will execute again by the same worker, or another worker.
Warning: Enabling this can cause message loops; make sure you know what you’re doing.
- request_stack = <celery.utils.threads._LocalStack object>#
Task request stack, the current request will be the topmost.
- serializer = 'json'#
The name of a serializer that are registered with
kombu.serialization.registry. Default is ‘json’.
- store_errors_even_if_ignored = True#
When enabled errors will be stored even if the task is otherwise configured to ignore results.
- track_started = True#
If enabled the task will report its status as ‘started’ when the task is executed by a worker. Disabled by default as the normal behavior is to not report that level of granularity. Tasks are either pending, finished, or waiting to be retried.
Having a ‘started’ status can be useful for when there are long running tasks and there’s a need to report what task is currently running.
The application default can be overridden using the :setting:`task_track_started` setting.
- typing = True#
Enable argument checking. You can set this to false if you don’t want the signature to be checked when calling the task. Defaults to
app.strict_typing.
openedx.core.djangoapps.content_libraries.urls module#
URL configuration for Studio’s Content Libraries REST API
openedx.core.djangoapps.content_libraries.views module#
Content Libraries Views#
This module contains the REST APIs for Learning Core-based content libraries, and LTI 1.3 views (though I’m not sure how functional the LTI piece of this is right now).
Most of the real work is intended to happen in the api.py module. The views are intended to be thin ones that do:
Permissions checking
Input/output data conversion via serializers
Pagination
Everything else should be delegated to api.py for the actual business logic. If you see business logic happening in these views, consider refactoring them into the api module instead.
Warning
NOTICE: DO NOT USE THE @atomic DECORATOR FOR THESE VIEWS!!!
- Views in ths module are decorated with:
@method_decorator(non_atomic_requests, name=”dispatch”)
This forces the views to execute without an implicit view-level transaction, even if the project is configured to use view-level transactions by default. (So no matter what you set the ATOMIC_REQUESTS setting to.)
We must use manual transactions for content libraries related views, or we’ll run into mysterious race condition bugs. We should NOT use the @atomic decorator over any of these views.
The problem is this: Code outside of this app will want to listen for
content lifecycle events like LIBRARY_BLOCK_CREATED and take certain
actions based on them. We see this pattern used extensively with courses.
Another common pattern is to use celery to queue up an asynchronous task to
do that work.
If there is an implicit database transaction around the entire view execution, the celery task may start up just before the view finishes executing. When that happens, the celery task doesn’t see the new content change, because the view transaction hasn’t finished committing it to the database yet.
The worst part of this is that dev environments and tests often won’t catch this because celery is typically configured to run in-process in those situations. When it’s run in-process, celery is already inside the view’s transaction so it will “see” the new changes and everything will appear to be fine–only to fail intermittently when deployed to production.
We can and should continue to use atomic() as a context manager when we want to make changes to multiple models. But this should happen at the api module layer, not in the view. Other apps are permitted to call functions in the public api.py module, and we want to make sure those api calls manage their own transactions and don’t assume that they’re being called in an atomic block.
Historical note: These views used to be wrapped with @atomic because we wanted to make all views that operated on Blockstore data atomic:
- class openedx.core.djangoapps.content_libraries.views.LibraryApiPagination#
Bases:
PageNumberPaginationPaginates over ContentLibraryMetadata objects.
- apidoc_params = [Parameter([('name', 'pagination'), ('in', 'query'), ('description', 'Enables paginated schema'), ('type', 'boolean')]), Parameter([('name', 'page'), ('in', 'query'), ('description', 'Page number of result. Defaults to 1'), ('type', 'integer')]), Parameter([('name', 'page_size'), ('in', 'query'), ('description', 'Page size of the result. Defaults to 50'), ('type', 'integer')])]#
- page_size = 50#
- page_size_query_param = 'page_size'#
- class openedx.core.djangoapps.content_libraries.views.LibraryBlockAssetListView(**kwargs)#
Bases:
APIViewViews to list an existing XBlock’s static asset files
- 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'>)#
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- get(request, usage_key_str)#
List the static asset files belonging to this block.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- class openedx.core.djangoapps.content_libraries.views.LibraryBlockAssetView(**kwargs)#
Bases:
APIViewViews to work with an existing XBlock’s static asset files
- 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'>)#
- delete(request, usage_key_str, file_path)#
Delete a static asset file belonging to this block.
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- get(request, usage_key_str, file_path)#
Get a static asset file belonging to this block.
- parser_classes = (<class 'rest_framework.parsers.MultiPartParser'>,)#
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- put(request, usage_key_str, file_path)#
Replace a static asset file belonging to this block.
- class openedx.core.djangoapps.content_libraries.views.LibraryBlockLtiUrlView(**kwargs)#
Bases:
APIViewViews to generate LTI URL for existing XBlocks in a content library.
Returns 404 in case the block not found by the given key.
- 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'>)#
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- get(request, usage_key_str)#
Get the LTI launch URL for the XBlock.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- class openedx.core.djangoapps.content_libraries.views.LibraryBlockOlxView(**kwargs)#
Bases:
APIViewViews to work with an existing XBlock’s OLX
- 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'>)#
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- get(request, usage_key_str)#
Get the block’s OLX
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- post(request, usage_key_str)#
Replace the block’s OLX.
This API is only meant for use by developers or API client applications. Very little validation is done.
- class openedx.core.djangoapps.content_libraries.views.LibraryBlockTypesView(**kwargs)#
Bases:
APIViewView to get the list of XBlock types that can be added to this library
- 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'>)#
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- get(request, lib_key_str)#
Get the list of XBlock types that can be added to this library
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- class openedx.core.djangoapps.content_libraries.views.LibraryBlockView(**kwargs)#
Bases:
APIViewViews to work with an existing XBlock in a content library.
- 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'>)#
- delete(request, usage_key_str)#
Delete a usage of a block from the library (and any children it has).
If this is the only usage of the block’s definition within this library, both the definition and the usage will be deleted. If this is only one of several usages, the definition will be kept. Usages by linked bundles are ignored and will not prevent deletion of the definition.
If the usage points to a definition in a linked bundle, the usage will be deleted but the link and the linked bundle will be unaffected.
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- get(request, usage_key_str)#
Get metadata about an existing XBlock in the content library
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- class openedx.core.djangoapps.content_libraries.views.LibraryBlocksView(**kwargs)#
Bases:
APIViewViews to work with XBlocks in a specific content library.
- 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'>)#
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- get(request, lib_key_str)#
Get the list of all top-level blocks in this content library
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- post(request, lib_key_str)#
Add a new XBlock to this content library
- class openedx.core.djangoapps.content_libraries.views.LibraryCommitView(**kwargs)#
Bases:
APIViewCommit/publish or revert all of the draft changes made to the library.
- 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'>)#
- delete(request, lib_key_str)#
Revert the draft changes made to the specified block and its descendants. Restore it to the last published version
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- post(request, lib_key_str)#
Commit the draft changes made to the specified block and its descendants.
- class openedx.core.djangoapps.content_libraries.views.LibraryDetailsView(**kwargs)#
Bases:
APIViewViews to work with a specific content library
- 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'>)#
- delete(request, lib_key_str)#
Delete a content library
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- get(request, lib_key_str)#
Get a specific content library
- patch(request, lib_key_str)#
Update a content library
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- class openedx.core.djangoapps.content_libraries.views.LibraryImportTaskViewSet(**kwargs)#
Bases:
ViewSetImport blocks from Courseware through modulestore.
- 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'>)#
- basename = None#
- create(request, lib_key_str)#
Create and queue an import tasks for this library.
- description = None#
- detail = None#
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- list(request, lib_key_str)#
List all import tasks for this library.
- name = None#
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- retrieve(request, lib_key_str, pk=None)#
Retrieve a import task for inspection.
- suffix = None#
- class openedx.core.djangoapps.content_libraries.views.LibraryRootView(**kwargs)#
Bases:
APIViewViews to list, search for, and create content libraries.
- 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'>)#
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- get(request)#
Return a list of all content libraries that the user has permission to view.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- post(request)#
Create a new content library.
- class openedx.core.djangoapps.content_libraries.views.LibraryTeamGroupView(**kwargs)#
Bases:
APIViewView to add/remove/edit a group’s permissions for a content library.
- 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'>)#
- delete(request, lib_key_str, username)#
Remove the specified user’s permission to access or edit this content library.
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- put(request, lib_key_str, group_name)#
Add a group to this content library, with permissions specified in the request body.
- class openedx.core.djangoapps.content_libraries.views.LibraryTeamUserView(**kwargs)#
Bases:
APIViewView to add/remove/edit an individual user’s permissions for a content library.
- 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'>)#
- delete(request, lib_key_str, username)#
Remove the specified user’s permission to access or edit this content library.
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- get(request, lib_key_str, username)#
Gets the current permissions settings for a particular user.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- put(request, lib_key_str, username)#
Add a user to this content library, with permissions specified in the request body.
- class openedx.core.djangoapps.content_libraries.views.LibraryTeamView(**kwargs)#
Bases:
APIViewView to get the list of users/groups who can access and edit the content library.
Note also the ‘allow_public_’ settings which can be edited by PATCHing the library itself (LibraryDetailsView.patch).
- 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'>)#
- dispatch(request, *args, **kwargs)#
.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.
- get(request, lib_key_str)#
Get the list of users and groups who have permissions to view and edit this library.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- post(request, lib_key_str)#
Add a user to this content library via email, with permissions specified in the request body.
- class openedx.core.djangoapps.content_libraries.views.LtiToolJwksView(**kwargs)#
Bases:
LtiToolViewJSON Web Key Sets view.
- dispatch(request, *args, **kwargs)#
- get(request)#
Return the JWKS.
- class openedx.core.djangoapps.content_libraries.views.LtiToolLaunchView(**kwargs)#
Bases:
TemplateResponseMixin,LtiToolViewLTI platform tool launch view.
The launch view supports resource link launches and AGS, when enabled by the LTI platform. Other features and resouces are ignored.
- dispatch(request, *args, **kwargs)#
- get_context_data()#
Setup the template context data.
- get_launch_message()#
Return the LTI 1.3 launch message object for the current request.
- handle_ags()#
Handle AGS-enabled launches for block in the request.
- property launch_data#
- post(request)#
Process LTI platform launch requests.
- template_name = 'content_libraries/xblock_iframe.html'#
- class openedx.core.djangoapps.content_libraries.views.LtiToolLoginView(**kwargs)#
Bases:
LtiToolViewThird-party Initiated Login view.
The LTI platform will start the OpenID Connect flow by redirecting the User Agent (UA) to this view. The redirect may be a form POST or a GET. On success the view should redirect the UA to the LTI platform’s authentication URL.
- LAUNCH_URI_PARAMETER = 'target_link_uri'#
- dispatch(request, *args, **kwargs)#
- get(request)#
- post(request)#
Initialize 3rd-party login requests to redirect.
- class openedx.core.djangoapps.content_libraries.views.LtiToolView(**kwargs)#
Bases:
ViewBase LTI View initializing common attributes.
- dispatch(request, *args, **kwargs)#
- setup(request, *args, **kwds)#
Initialize attributes shared by all LTI views.
- openedx.core.djangoapps.content_libraries.views.convert_exceptions(fn)#
Catch any Content Library API exceptions that occur and convert them to DRF exceptions so DRF will return an appropriate HTTP response
- openedx.core.djangoapps.content_libraries.views.requires_lti_enabled(view_func)#
Modify the view function to raise 404 if content librarie LTI tool was not enabled.