[1/6] refactor: define resource paths (not contents) on XModule classes - #32286
Conversation
For the XBlocks types that use legacy XModule-style assets, this is small
refactor that brings them a bit closer to being like XBlocks.
Given class attributes on those block types in the form:
SomeXModuleLikeBlock.(studio|preview)_view_(js|css)['(js|scss|css|xmodule_js)']
we make it so their value is the *path to the resource*
rather than *the actual content of the resource*.
This will make future refactorings simpler.
Part of: openedx#31624
kdmccormick
left a comment
There was a problem hiding this comment.
Notes for reviewers 👀
| resource_filename(__name__, 'js/src/collapsible.js'), | ||
| ], | ||
| 'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'), | ||
| 'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'), |
There was a problem hiding this comment.
resource_string loaded the contents of the resource. We change it to resource_filename, which just returns the absolute path to the resource.
We make this change uniformly across all XModule-like XBlocks.
There was a problem hiding this comment.
Non-blocking note: It looks like pkg_resources is deprecated and we should be using importlib.resources.path(package, resource). But annoyingly even that new way will be deprecated in Python 3.11 and replaced with a different interface.
It may be fine to leave as is for now, I've asked the setuptools community what the timeline for this deprecation is so we can plan accordingly.
| for idx, fragment in enumerate(class_css.get(filetype, [])): | ||
| for idx, fragment_path in enumerate(class_css.get(filetype, [])): | ||
| with open(fragment_path, 'rb') as fragment_file: | ||
| fragment = fragment_file.read() |
There was a problem hiding this comment.
When processing the SCSS, we now must load the files rather than just looking at the contents.
This creates a very minor build-time inefficiency: any SCSS file that is used across multiple XModules will be loaded multiple times. On the other hand, it achieves a minor run-time optimization: these SCSS files are no longer loaded along with XModule classes.
The inefficiency will be gone soon, because follow-up refactorings aim to delete this processing step entirely.
| with open(module_js.get('xmodule_js'), 'rb') as xmodule_js_file: | ||
| xmodule_js_fragment = xmodule_js_file.read() | ||
| # It will enforce 000 prefix for xmodule.js. | ||
| fragment_owners[(0, 'js', module_js.get('xmodule_js'))].append(getattr(class_, js_attribute + '_bundle_name')()) | ||
| fragment_owners[(0, 'js', xmodule_js_fragment)].append(getattr(class_, js_attribute + '_bundle_name')()) | ||
| for filetype in ('coffee', 'js'): | ||
| for idx, fragment in enumerate(module_js.get(filetype, [])): | ||
| for idx, fragment_path in enumerate(module_js.get(filetype, [])): | ||
| with open(fragment_path, 'rb') as fragment_file: | ||
| fragment = fragment_file.read() |
There was a problem hiding this comment.
(this is just the JS version of the SCSS change above; same considerations)
feanil
left a comment
There was a problem hiding this comment.
Seems reasonable to me, I tested locally by bringing up tutor and looking at the video block and seeing it rendered correctly in studio and the LMS.
| resource_filename(__name__, 'js/src/collapsible.js'), | ||
| ], | ||
| 'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'), | ||
| 'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'), |
There was a problem hiding this comment.
Non-blocking note: It looks like pkg_resources is deprecated and we should be using importlib.resources.path(package, resource). But annoyingly even that new way will be deprecated in Python 3.11 and replaced with a different interface.
It may be fine to leave as is for now, I've asked the setuptools community what the timeline for this deprecation is so we can plan accordingly.
@feanil Good point, and thanks for opening that issue. The direction that I hope we go for edx-platform XBlocks is to stop using pkg_resources and instead use the standard XBlock resource-loading framework (
|
|
Sorry, I wasn't trying to ask you to open those issues, I meant to write:
|
|
Okay, it's a little more complicated than I thought. XBlock does not provide a resource abstraction, but xblock-utils does. If everyone just used xblock-utils' abstraction, then switching off of |
|
EdX Release Notice: This PR has been deployed to the staging environment in preparation for a release to production. |
|
EdX Release Notice: This PR has been deployed to the production environment. |
Supporting information
This is a part of a series of PRs:
The previous series of PR is:
The next PR is:
Description
For the XBlocks types that use legacy XModule-style assets (specifically, those that
inherit from
HTMLSnippet), this is small refactor that brings them a bit closer to being likestandard XBlocks.
Given these class attributes:
we make it so their values are paths to the resources
rather than the actual content of the resources.
This is a no-op change, but it'll enable future XModule
asset refactorings which require us to operate on asset
paths rather than contents.
Other information
Reviewers: see #32286 (review)
Testing Instructions
Deadline
Medium-high urgency, as this is in the critical path to a long line of DevX improvement PRs.