openedx.core.djangoapps.xblock.runtime package

Contents

openedx.core.djangoapps.xblock.runtime package#

Submodules#

openedx.core.djangoapps.xblock.runtime.ephemeral_field_data module#

An KeyValueStore that stores data in the django cache

This is used for low-priority ephemeral student state data: * Anonymous users browsing and previewing content * Studio authors testing out XBlocks

We could also store this data in django sessions, but its a bit tricky to access session data during any requests which don’t have any cookies or other normal authentication mechanisms (like XBlock handler calls from within XBlock <iframe> sandboxes). And keeping this storage completely separate from django session data and registered user XBlock state reduces the potential for security problems. We expect the data in this store to be low-value and free of personally identifiable information (PII) so if some security bug results in one user accessing a different user’s entries in this particular store, it’s not a big deal.

class openedx.core.djangoapps.xblock.runtime.ephemeral_field_data.EphemeralKeyValueStore#

Bases: KeyValueStore

An XBlock field data key-value store that is backed by the django cache

delete(key)#

Deletes key from storage.

get(key)#

Reads the value of the given key from storage.

has(key)#

Returns whether or not key is present in storage.

set(key, value)#

Sets key equal to value in storage.

class openedx.core.djangoapps.xblock.runtime.ephemeral_field_data.NotFound#

Bases: object

This class is a unique value that can be stored in a cache to indicate “not found”

openedx.core.djangoapps.xblock.runtime.id_managers module#

Implementation of the APIs required for XBlock runtimes to work with our newer Open edX-specific opaque key formats.

class openedx.core.djangoapps.xblock.runtime.id_managers.OpaqueKeyReader#

Bases: IdReader

IdReader for DefinitionKey and :class:`UsageKey`s.

get_aside_type_from_definition(aside_id)#

Retrieve the XBlockAside aside_type associated with this aside definition id.

Parameters:

aside_id – The definition id of the XBlockAside.

Returns:

The aside_type of the aside.

get_aside_type_from_usage(aside_id)#

Retrieve the XBlockAside aside_type associated with this aside usage id.

Parameters:

aside_id – The usage id of the XBlockAside.

Returns:

The aside_type of the aside.

get_block_type(def_id)#

Retrieve the block_type of a particular definition

Parameters:

def_id – The id of the definition to query

Returns:

The block_type of the definition

get_definition_id(usage_id)#

Retrieve the definition that a usage is derived from.

Parameters:

usage_id – The id of the usage to query

Returns:

The definition_id the usage is derived from

get_definition_id_from_aside(aside_id)#

Retrieve the XBlock definition_id associated with this aside definition id.

Parameters:

aside_id – The usage id of the XBlockAside.

Returns:

The definition_id of the usage the aside is commenting on.

get_usage_id_from_aside(aside_id)#

Retrieve the XBlock usage_id associated with this aside usage id.

Parameters:

aside_id – The usage id of the XBlockAside.

Returns:

The usage_id of the usage the aside is commenting on.

openedx.core.djangoapps.xblock.runtime.mixin module#

A mixin that provides functionality and default attributes for all XBlocks in the new XBlock runtime.

class openedx.core.djangoapps.xblock.runtime.mixin.LmsBlockMixin(scope_ids, field_data=None, *, runtime, **kwargs)#

Bases: XBlockMixin

A mixin that provides functionality and default attributes for all XBlocks in the new XBlock runtime.

These are not standard XBlock attributes but are used by the LMS (and possibly Studio).

has_score = False#
public_view(_context)#

Default message for blocks that don’t implement public_view

public_view is shown when users aren’t logged in and/or are not enrolled in a particular course.

publish_completion(data, suffix='')#

Allow the frontend app that’s rendering this XBlock to mark it as completed when the user views it, if appropriate.

Copied from lms.djangoapps.lms_xblock.mixin.LmsBlockMixin

openedx.core.djangoapps.xblock.runtime.openedx_content_runtime module#

openedx_content XBlock Runtime code

class openedx.core.djangoapps.xblock.runtime.openedx_content_runtime.OpenedXContentFieldData#

Bases: FieldData

FieldData for the openedx_content XBlock Runtime

OpenedXContentFieldData only supports the content and settings scopes. Any attempt to read or write fields with other scopes will raise a NotImplementedError. This class does NOT support the parent and children scopes.

OpenedXContentFieldData should only live for the duration of one request. The interaction between OpenedXContentRuntime and OpenedXContentFieldData is as follows:

  1. OpenedXContentRuntime knows how retrieve authored content data from the Content API in openedx_content. This content is stored as OLX, and OpenedXContentRuntime won’t know how to parse it into fields, since serialization logic can happen in the XBlock itself.

  2. OpenedXContentRuntime will then invoke the block to parse the OLX and then force_save its field data into OpenedXContentFieldData.

  3. After this point, various handler and API calls might alter fields for a given block using the XBlock.

  4. The main thing that OpenedXContentRuntime will want to know later on is whether it needs to write any changes when its save_block method is invoked. To support this, OpenedXContentFieldData needs to track which blocks have changes to any of their fields. See the marked_unchanged method docstring for more details.

delete(block, name)#

Delete a field value from a block.

get(block, name)#

Get a field value from a block.

Raises a KeyError if the value is not found. It is very common to raise this error. XBlocks have many fields with default values, and the FieldData is not expected to store those defaults (that information lives on the Field object). A FieldData subclass only has to store field values that have explicitly been set.

has_changes(block)#

Does this block have changes that need to be persisted?

mark_unchanged(block)#

Mark a block as being unchanged (i.e. no need to write this to the DB).

Calling set or delete on a field always marks the block with that field as changed, by adding its usage key to self.changed. But set() is also called at the very beginning, when a block is first loaded from the database by the OpenedXContentRuntime’s get_block call.

This method exists so that OpenedXContentRuntime can call it whenever it has either just done a get_block operation (because those set() calls represent the already-persisted content state), or a save_block operation (since those changes will have been persisted).

This is not a standard part of the FieldData interface.

set(block, name, value)#

Set a field for a block to a value.

class openedx.core.djangoapps.xblock.runtime.openedx_content_runtime.OpenedXContentRuntime(user: User | None, *, handler_url: GetHandlerFunction, student_data_mode: StudentDataMode, authored_data_mode: AuthoredDataMode, authored_data_store: FieldData, id_reader: IdReader | None = None)#

Bases: XBlockRuntime

XBlock runtime that uses openedx_content APIs (not ModuleStore).

The superclass is doing all the hard stuff. This class only only has to worry about the block storage, block serialization/de-serialization, and (eventually) asset storage.

get_block(usage_key, for_parent=None, *, version: int | LatestVersion = LatestVersion.AUTO)#

Fetch an XBlock from openedx_content data models.

This method will find the OLX for the content in openedx_content, parse it into an XBlock (with mixins) instance, and properly initialize our internal OpenedXContentFieldData instance with the field values from the parsed OLX.

get_block_assets(block, fetch_asset_data)#

Return a list of StaticFile entries.

If fetch_data is True, we will read the actual asset file data from storage and return it as part of the StaticFiles. This is expensive, and not necessary for something like writing a new version of the OLX in response to a “Save” in the editor. But it is necessary for something like serializing to the clipboard, where we make full copies of the assets.

TODO: When we want to copy a whole Section at a time, doing these lookups one by one is going to get slow. At some point we’re going to want something to look up a bunch of blocks at once.

get_component_version_from_block(block)#

Given an XBlock instance, return the openedx_content ComponentVersion.

This relies on our runtime setting the _runtime_requested_version attribute on blocks that it fetches.

save_block(block)#

Save any pending field data values to openedx_content data models.

This gets called by block.save() - do not call this directly.

openedx.core.djangoapps.xblock.runtime.runtime module#

Common base classes for all new XBlock runtimes.

class openedx.core.djangoapps.xblock.runtime.runtime.GetHandlerFunction(*args, **kwargs)#

Bases: Protocol

Type definition for our “get handler” callback

class openedx.core.djangoapps.xblock.runtime.runtime.XBlockRuntime(user: User | None, *, handler_url: GetHandlerFunction, student_data_mode: StudentDataMode, authored_data_mode: AuthoredDataMode, authored_data_store: FieldData, id_reader: IdReader | None = None)#

Bases: RuntimeShim, Runtime

This class manages one or more instantiated XBlocks for a particular user, providing those XBlocks with the standard XBlock runtime API (and some Open edX-specific additions) so that it can interact with the platform, and the platform can interact with it.

The main reason we cannot make the runtime a long-lived singleton is that the XBlock runtime API requires ‘user_id’ to be a property of the runtime, not an argument passed in when loading particular blocks.

TODO: This should probably be merged with OpenedXContentRuntime, its one and

only child class. See openedx/openedx-platform#38021

add_node_as_child(block, node)#

Called by XBlock.parse_xml to treat a child node as a child block.

applicable_aside_types(block: XBlock)#

Disable XBlock asides in this runtime

authored_data_store: FieldData#
block_field_datas: dict[ScopeIds, FieldData | None]#
django_field_data_caches: dict[LearningContextKey, FieldDataCache]#
get_event_handler(event_type: str) Callable[[XBlock, dict], None] | None#

Return an appropriate function to handle the event.

Returns None if no special processing is required.

handle_completion_event(block: XBlock, event: dict)#

Submit a completion object for the block.

handle_grade_event(block: XBlock, event: dict)#

Submit a grade for the block.

handler_url(block, handler_name: str, suffix='', query='', thirdparty=False)#

Get the URL to a specific handler.

local_resource_url(block: XBlock, uri: str) str#

Get the absolute URL to a resource file (like a CSS/JS file or an image) that is part of an XBlock’s python module.

log_event_to_tracking_log(block: XBlock, event_type: str, event_data: dict) None#

Log this XBlock event to the tracking log

parse_xml_file(fileobj)#

Parse an open XML file, returning a usage id.

publish(block: XBlock, event_type: str, event_data: dict)#

Handle XBlock events like grades and completion

render(block: XBlock, view_name: str, context: dict | None = None)#

Render a specific view of an XBlock.

resource_url(resource)#

Get the URL for a static resource file.

resource is the application local path to the resource.

The return value is a complete absolute URL that will locate the resource on your runtime.

service(block: XBlock, service_name: str)#

Return a service, or None. Services are objects implementing arbitrary other interfaces.

suppports_state_for_anonymous_users = True#
user: User | None#
view_name: str | None#
openedx.core.djangoapps.xblock.runtime.runtime.make_track_function()#

Make a tracking function that logs what happened, for XBlock events.

openedx.core.djangoapps.xblock.runtime.shims module#

Code to implement backwards compatibility

class openedx.core.djangoapps.xblock.runtime.shims.RuntimeShim(*args, **kwargs)#

Bases: object

All the old/deprecated APIs that our XBlock runtime(s) need to support are captured in this mixin.

property STATIC_URL#

Get the django STATIC_URL path. Deprecated in favor of the settings.STATIC_URL configuration.

property anonymous_student_id#

Get an anonymized identifier for this user.

property cache#

Access to a cache.

Seems only to be used by capa. Remove this if capa can be refactored.

property can_execute_unsafe_code#

Determine if capa problems in this context/course are allowed to run unsafe code. See xmodule/util/sandboxing.py

Seems only to be used by capa.

property course_id#

Old API to get the course ID.

property error_tracker#

Accessor for the course’s error tracker

export_fs = <object object>#
property filestore#

Alternate name for ‘resources_fs’.

get_field_provenance(xblock, field)#

A Studio-specific method that was implemented on ModuleStoreRuntime. Used by the problem block.

For the given xblock, return a dict for the field’s current state: {

‘default_value’: what json’d value will take effect if field is unset: either the field default or inherited value, ‘explicitly_set’: boolean for whether the current value is set v default/inherited,

}

get_policy(_usage_id)#

A function that takes a usage id and returns a dict of policy to apply.

get_python_lib_zip()#

A function returning a bytestring or None. The bytestring is the contents of a zip file that should be importable by other Python code running in the module.

Only used for capa problems.

handle(block, handler_name, request, suffix='')#

Render a block by invoking its view.

process_xml(xml)#

Code to handle parsing of child XML for old blocks that use XmlMixin.

render(block, view_name, context=None)#

Render a block by invoking its view.

render_template(template_name, dictionary, namespace='main')#

Render a mako template

property resources_fs#

A filesystem that XBlocks can use to read large binary assets.

property seed#

A number to seed the random number generator. Used by capa and the randomize block.

Should be based on the user ID, per the existing implementation.

user_is_staff#

Is the current user a global staff user?

property user_location#

Old API to get the user’s country code (or None) Used by the Video XBlock to select a CDN for user.

xqueue#

An accessor for XQueue, the platform’s interface for external grader services.

Seems only to be used by capa. Remove this if capa can be refactored.

class openedx.core.djangoapps.xblock.runtime.shims.XBlockShim#

Bases: object

Mixin added to XBlock classes in this runtime, to support older/XModule APIs

always_recalculate_grades = False#
get_icon_class()#

Return a css class identifying this module in the context of an icon

property graded#

Not sure what this is or how it’s supposed to be set. Capa seems to expect a ‘graded’ attribute to be present on itself. Possibly through contentstore’s update_section_grader_type() ?

has_dynamic_children()#

Returns True if this XBlock has dynamic children for a given student when the module is created. This is deprecated and discouraged.

icon_class = 'other'#
property location#

Accessor for the usage ID

show_in_read_only_mode = False#
property system#

Accessor for the XModule runtime

Module contents#