openedx.core.djangoapps.xblock package#
Subpackages#
- openedx.core.djangoapps.xblock.learning_context package
- openedx.core.djangoapps.xblock.rest_api package
- openedx.core.djangoapps.xblock.runtime package
- Submodules
- openedx.core.djangoapps.xblock.runtime.ephemeral_field_data module
- openedx.core.djangoapps.xblock.runtime.id_managers module
- openedx.core.djangoapps.xblock.runtime.learning_core_runtime module
- openedx.core.djangoapps.xblock.runtime.mixin module
- openedx.core.djangoapps.xblock.runtime.runtime module
XBlockRuntimeXBlockRuntime.add_node_as_child()XBlockRuntime.applicable_aside_types()XBlockRuntime.block_field_datasXBlockRuntime.django_field_data_cachesXBlockRuntime.get_event_handler()XBlockRuntime.handle_completion_event()XBlockRuntime.handle_grade_event()XBlockRuntime.handler_url()XBlockRuntime.local_resource_url()XBlockRuntime.log_event_to_tracking_log()XBlockRuntime.parse_xml_file()XBlockRuntime.publish()XBlockRuntime.render()XBlockRuntime.resource_url()XBlockRuntime.service()XBlockRuntime.suppports_state_for_anonymous_usersXBlockRuntime.userXBlockRuntime.view_name
XBlockRuntimeSystemmake_track_function()
- openedx.core.djangoapps.xblock.runtime.shims module
RuntimeShimRuntimeShim.STATIC_URLRuntimeShim.anonymous_student_idRuntimeShim.cacheRuntimeShim.can_execute_unsafe_codeRuntimeShim.course_idRuntimeShim.error_trackerRuntimeShim.export_fsRuntimeShim.filestoreRuntimeShim.get_field_provenance()RuntimeShim.get_policy()RuntimeShim.get_python_lib_zip()RuntimeShim.handle()RuntimeShim.process_xml()RuntimeShim.render()RuntimeShim.render_template()RuntimeShim.resources_fsRuntimeShim.seedRuntimeShim.user_is_staffRuntimeShim.user_locationRuntimeShim.xqueue
XBlockShim
- Module contents
Submodules#
openedx.core.djangoapps.xblock.api module#
Python API for interacting with edx-platform’s new XBlock Runtime.
For content in modulestore (currently all course content), you’ll need to use the older runtime.
Note that these views are only for interacting with existing blocks. Other Studio APIs cover use cases like adding/deleting/editing blocks.
- openedx.core.djangoapps.xblock.api.get_block_display_name(block: XBlock) str#
Get the display name from an instatiated XBlock, falling back to the XBlock-type-defined-default.
- openedx.core.djangoapps.xblock.api.get_block_draft_olx(usage_key: UsageKeyV2) str#
Get the OLX source of the draft version of the given Learning-Core-backed XBlock.
- openedx.core.djangoapps.xblock.api.get_block_metadata(block, includes=())#
Get metadata about the specified XBlock.
This metadata is the same for all users. Any data which varies per-user must be served from a different API.
- Optionally provide a list or set of metadata keys to include. Valid keys are:
- index_dictionary: a dictionary of data used to add this XBlock’s content
to a search index.
- student_view_data: data needed to render the XBlock on mobile or in
custom frontends.
children: list of usage keys of the XBlock’s children editable_children: children in the same bundle, as opposed to linked
children in other bundles.
- openedx.core.djangoapps.xblock.api.get_component_from_usage_key(usage_key: UsageKeyV2) Component#
Fetch the Component object for a given usage key.
Raises a ObjectDoesNotExist error if no such Component exists.
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).
- openedx.core.djangoapps.xblock.api.get_handler_url(usage_key, handler_name, user)#
A method for getting the URL to any XBlock handler. The URL must be usable without any authentication (no cookie, no OAuth/JWT), and may expire. (So that we can render the XBlock in a secure IFrame without any access to existing cookies.)
The returned URL will contain the provided handler_name, but is valid for any other handler on the same XBlock. Callers may replace any occurrences of the handler name in the resulting URL with the name of any other handler and the URL will still work. (This greatly reduces the number of calls to this API endpoint that are needed to interact with any given XBlock.)
- Params:
usage_key - Usage Key (Opaque Key object or string) handler_name - Name of the handler or a dummy name like ‘any_handler’ user - Django User (registered or anonymous)
This view does not check/care if the XBlock actually exists.
- openedx.core.djangoapps.xblock.api.get_runtime_system()#
Return a new XBlockRuntimeSystem.
TODO: Refactor to get rid of the XBlockRuntimeSystem entirely and just create the LearningCoreXBlockRuntime and return it. We used to want to keep around a long lived runtime system (a factory that returns runtimes) for caching purposes, and have it dynamically construct a runtime on request. Now we’re just re-constructing both the system and the runtime in this call and returning it every time, because:
We no longer have slow, Blockstore-style definitions to cache, so the performance of this is perfectly acceptable.
Having a singleton increases complexity and the chance of bugs.
Creating the XBlockRuntimeSystem every time only takes about 10-30 µs.
Given that, the extra XBlockRuntimeSystem class just adds confusion. But despite that, it’s tested, working code, and so I’m putting off refactoring for now.
- openedx.core.djangoapps.xblock.api.load_block(usage_key, user)#
Load the specified XBlock for the given user.
Returns an instantiated XBlock.
- Exceptions:
- NotFound - if the XBlock doesn’t exist or if the user doesn’t have the
necessary permissions
- Parameters:
usage_key (OpaqueKey) – block identifier
user (User) – user requesting the block
- openedx.core.djangoapps.xblock.api.render_block_view(block, view_name, user)#
Get the HTML, JS, and CSS needed to render the given XBlock view.
- The only difference between this method and calling
load_block().render(view_name)
is that this method can fall back from ‘author_view’ to ‘student_view’
Returns a Fragment.
- openedx.core.djangoapps.xblock.api.xblock_type_display_name(block_type)#
Get the display name for the specified XBlock class.
openedx.core.djangoapps.xblock.apps module#
Django app configuration for the XBlock Runtime django app
- class openedx.core.djangoapps.xblock.apps.LmsXBlockAppConfig(app_name, app_module)#
Bases:
XBlockAppConfigLMS-specific configuration of the XBlock Runtime django app.
- get_runtime_system_params()#
Get the XBlockRuntimeSystem parameters appropriate for viewing and/or editing XBlock content in the LMS
- get_site_root_url()#
Get the absolute root URL to this site, e.g. ‘https://courses.example.com’ Should not have any trailing slash.
- class openedx.core.djangoapps.xblock.apps.StudioXBlockAppConfig(app_name, app_module)#
Bases:
XBlockAppConfigStudio-specific configuration of the XBlock Runtime django app.
- BLOCKSTORE_DRAFT_NAME = 'studio_draft'#
- get_learning_context_params()#
Get additional kwargs that are passed to learning context implementations (LearningContext subclass constructors). For example, this can be used to specify that the course learning context should load the course’s list of blocks from the _draft_ version of the course in studio, but from the published version of the course in the LMS.
- get_runtime_system_params()#
Get the XBlockRuntimeSystem parameters appropriate for viewing and/or editing XBlock content in Studio
- get_site_root_url()#
Get the absolute root URL to this site, e.g. ‘https://studio.example.com’ Should not have any trailing slash.
- class openedx.core.djangoapps.xblock.apps.XBlockAppConfig(app_name, app_module)#
Bases:
AppConfigDjango app configuration for the new XBlock Runtime django app
- get_learning_context_params()#
Get additional kwargs that are passed to learning context implementations (LearningContext subclass constructors). For example, this can be used to specify that the course learning context should load the course’s list of blocks from the _draft_ version of the course in studio, but from the published version of the course in the LMS.
- get_runtime_system_params()#
Get the XBlockRuntimeSystem parameters appropriate for viewing and/or editing XBlock content.
- get_site_root_url()#
Get the absolute root URL to this site, e.g. ‘https://courses.example.com’ Should not have any trailing slash.
- label = 'xblock_new'#
- name = 'openedx.core.djangoapps.xblock'#
- verbose_name = 'New XBlock Runtime'#
- openedx.core.djangoapps.xblock.apps.get_xblock_app_config()#
Get whichever of the above AppConfig subclasses is active.
openedx.core.djangoapps.xblock.data module#
Data structures for the XBlock Django app’s python APIs
- class openedx.core.djangoapps.xblock.data.StudentDataMode(value)#
Bases:
EnumIs student data (like which answer was selected) persisted in the DB or just stored temporarily in the session? Generally, the LMS uses persistence and Studio uses ephemeral data.
- Ephemeral = 'ephemeral'#
- Persisted = 'persisted'#
openedx.core.djangoapps.xblock.utils module#
Useful helper methods related to the XBlock runtime
- openedx.core.djangoapps.xblock.utils.get_secure_token_for_xblock_handler(user_id, block_key_str, time_idx=0)#
Get a secure token (one-way hash) used to authenticate XBlock handler requests. This token replaces both the session ID cookie (or OAuth bearer token) and the CSRF token for such requests.
The token is specific to one user and one XBlock usage ID, though may be used for any handler. It expires and is only valid for 2-4 days (our current best guess at a reasonable trade off between “what if the user left their browser open overnight and tried to continue the next day” which should work vs. “for security, tokens should not last too long”)
We use this token because XBlocks may sometimes be sandboxed (run in a client-side JavaScript environment with no access to cookies) and because the XBlock python and JavaScript handler_url APIs do not provide any way of authenticating the handler requests, other than assuming cookies are present or including this sort of secure token in the handler URL.
For security, we need these tokens to have an expiration date. So: the hash incorporates the current time, rounded to the lowest TOKEN_PERIOD value. When checking this, you should check both time_idx=0 and time_idx=-1 in case we just recently moved from one time period to another (i.e. at the stroke of midnight UTC or similar). The effect of this is that each token is valid for 2-4 days.
(Alternatively, we could make each token expire after exactly X days, but that requires storing the expiration date of each token on the server side, making the implementation needlessly complex. The “time window” approach we are using here also has the advantage that throughout a typical day, the token each user gets for a given XBlock doesn’t change, which makes debugging and reasoning about the system simpler.)
- openedx.core.djangoapps.xblock.utils.get_xblock_id_for_anonymous_user(user)#
Get a unique string that identifies the current anonymous (not logged in) user. (This is different than the “anonymous user ID”, which is an anonymized identifier for a logged in user.)
Note that this ID is a string, not an int. It is guaranteed to be in a unique namespace that won’t collide with “normal” user IDs, even when they are converted to a string.
- openedx.core.djangoapps.xblock.utils.validate_secure_token_for_xblock_handler(user_id, block_key_str, token)#
Returns True if the specified handler authentication token is valid for the given Xblock ID and user ID. Otherwise returns false.
See get_secure_token_for_xblock_handler
Module contents#
The new XBlock runtime and related code.