openedx.core.lib package#
Subpackages#
- openedx.core.lib.api package
- Submodules
- openedx.core.lib.api.authentication module
- openedx.core.lib.api.fields module
- openedx.core.lib.api.mixins module
- openedx.core.lib.api.parsers module
- openedx.core.lib.api.permissions module
- openedx.core.lib.api.serializers module
- openedx.core.lib.api.test_utils module
ApiTestCaseApiTestCase.assertAllowedMethods()ApiTestCase.assertAuthDisabled()ApiTestCase.assertHttpBadRequest()ApiTestCase.assertHttpCreated()ApiTestCase.assertHttpForbidden()ApiTestCase.assertHttpMethodNotAllowed()ApiTestCase.assertHttpNotAuthorized()ApiTestCase.assertHttpOK()ApiTestCase.assertSelfReferential()ApiTestCase.basic_auth()ApiTestCase.get_json()ApiTestCase.request_with_auth()ApiTestCase.request_without_auth()
- openedx.core.lib.api.view_utils module
- Module contents
- openedx.core.lib.celery package
- openedx.core.lib.django_require package
- openedx.core.lib.gating package
- Submodules
- openedx.core.lib.gating.api module
add_prerequisite()compute_is_prereq_met()find_gating_milestones()gating_enabled()get_gated_content()get_gating_milestone()get_prerequisites()get_required_content()get_subsection_completion_percentage()get_subsection_grade_percentage()is_gate_fulfilled()is_prerequisite()remove_prerequisite()set_required_content()update_milestone()
- openedx.core.lib.gating.exceptions module
- openedx.core.lib.gating.services module
- Module contents
- openedx.core.lib.license package
- openedx.core.lib.safe_lxml package
- openedx.core.lib.x_forwarded_for package
- openedx.core.lib.xblock_pipeline package
- Submodules
- openedx.core.lib.xblock_pipeline.finder module
XBlockPackageStorageXBlockPackageStorage.RESOURCE_PREFIXXBlockPackageStorage.delete()XBlockPackageStorage.exists()XBlockPackageStorage.get_accessed_time()XBlockPackageStorage.get_created_time()XBlockPackageStorage.get_modified_time()XBlockPackageStorage.listdir()XBlockPackageStorage.open()XBlockPackageStorage.path()XBlockPackageStorage.size()XBlockPackageStorage.url()
XBlockPipelineFinder
- Module contents
- openedx.core.lib.xblock_serializer package
- Submodules
- openedx.core.lib.xblock_serializer.api module
- openedx.core.lib.xblock_serializer.block_serializer module
- openedx.core.lib.xblock_serializer.data module
- openedx.core.lib.xblock_serializer.test_api module
- openedx.core.lib.xblock_serializer.test_utils module
- openedx.core.lib.xblock_serializer.utils module
- Module contents
- openedx.core.lib.xblock_services package
- openedx.core.lib.xblock_utils package
- Module contents
add_staff_markup()get_aside_from_xblock()get_course_update_items()get_css_dependencies()get_icon()get_js_dependencies()grade_histogram()hash_resource()is_xblock_aside()request_token()sanitize_html_id()wrap_fragment()wrap_xblock()wrap_xblock_aside()xblock_local_resource_url()xblock_resource_pkg()
- Module contents
Submodules#
openedx.core.lib.cache_utils module#
Utilities related to caching.
- class openedx.core.lib.cache_utils.CacheInvalidationManager(namespace=None, model=None, cache_time=86400)#
Bases:
objectThis class provides a decorator for simple functions, which can handle invalidation.
To use, instantiate with a namespace or django model class: manager = CacheInvalidationManager(model=User) One of namespace or model should be specified, but not both.
Then use it as a decorator on functions with no arguments `@manager def get_system_user():
…
` When the User model is saved or deleted, all cache keys used by the decorator will be cleared.
- invalidate(**kwargs)#
Invalidate all keys tracked by the manager.
- class openedx.core.lib.cache_utils.CacheService(cache, **kwargs)#
Bases:
objectAn XBlock service which provides a cache.
- Parameters:
cache (object) – provides get/set functions for retrieving/storing key/value pairs.
- get(key, *args, **kwargs)#
Returns the value cached against the given key, or None.
- set(key, value, *args, **kwargs)#
Caches the value against the given key.
- openedx.core.lib.cache_utils.get_cache(name)#
Return the request cache named
name.- Parameters:
name (str) – The name of the request cache to load
Returns: dict
- class openedx.core.lib.cache_utils.process_cached(func)#
Bases:
objectDecorator to cache the result of a function for the life of a process.
If the return value of the function for the provided arguments has not yet been cached, the function will be calculated and cached. If called later with the same arguments, the cached value is returned (not reevaluated). https://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
WARNING: Only use this process_cached decorator for caching data that is constant throughout the lifetime of a gunicorn worker process, is costly to compute, and is required often. Otherwise, it can lead to unwanted memory leakage.
- openedx.core.lib.cache_utils.request_cached(namespace=None, arg_map_function=None, request_cache_getter=None)#
A function decorator that automatically handles caching its return value for the duration of the request. It returns the cached value for subsequent calls to the same function, with the same parameters, within a given request.
Notes
We convert arguments and keyword arguments to their string form to build the cache key. So if you have args/kwargs that can’t be converted to strings, you’re gonna have a bad time (don’t do it).
Cache key cardinality depends on the args/kwargs. So if you’re caching a function that takes five arguments, you might have deceptively low cache efficiency. Prefer functions with fewer arguments.
WATCH OUT: Don’t use this decorator for instance methods that take in a “self” argument that changes each time the method is called. This will result in constant cache misses and not provide the performance benefit you are looking for. Rather, change your instance method to a class method.
Benchmark, benchmark, benchmark! If you never measure, how will you know you’ve improved? or regressed?
- Parameters:
namespace (string) – An optional namespace to use for the cache. By default, we use the default request cache, not a namespaced request cache. Since the code automatically creates a unique cache key with the module and function’s name, storing the cached value in the default cache, you won’t usually need to specify a namespace value. But you can specify a namespace value here if you need to use your own namespaced cache - for example, if you want to clear out your own cache by calling RequestCache(namespace=NAMESPACE).clear(). NOTE: This argument is ignored if you supply a
request_cache_getter.(function (request_cache_getter) – arg->string): Function to use for mapping the wrapped function’s arguments to strings to use in the cache key. If not provided, defaults to force_text, which converts the given argument to a string.
(function – args, kwargs->RequestCache): Function that returns the RequestCache to use. If not provided, defaults to edx_django_utils.cache.RequestCache. If
request_cache_getterreturns None, the function’s return values are not cached.
- Returns:
- a wrapper function which will call the wrapped function, passing in the same args/kwargs,
cache the value it returns, and return that cached value for subsequent calls with the same args/kwargs within a single request.
- Return type:
func
- openedx.core.lib.cache_utils.zpickle(data)#
Given any data structure, returns a zlib compressed pickled serialization.
- openedx.core.lib.cache_utils.zunpickle(zdata)#
Given a zlib compressed pickled serialization, returns the deserialized data.
openedx.core.lib.command_utils module#
Useful utilities for management commands.
- openedx.core.lib.command_utils.get_mutually_exclusive_required_option(options, *selections)#
Validates that exactly one of the 2 given options is specified. Returns the name of the found option.
- openedx.core.lib.command_utils.parse_course_keys(course_key_strings)#
Parses and returns a list of CourseKey objects from the given list of course key strings.
- openedx.core.lib.command_utils.validate_dependent_option(options, dependent_option, depending_on_option)#
Validates that option_1 is specified if dependent_option is specified.
- openedx.core.lib.command_utils.validate_mutually_exclusive_option(options, option_1, option_2)#
Validates that both of the 2 given options are not specified.
openedx.core.lib.course_tabs module#
Tabs for courseware.
- class openedx.core.lib.course_tabs.CourseTabPluginManager#
Bases:
PluginManagerManager for all of the course tabs that have been made available.
All course tabs should implement CourseTab.
- NAMESPACE = 'openedx.course_tab'#
- classmethod get_tab_types()#
Returns the list of available course tabs in their canonical order.
openedx.core.lib.courses module#
Common utility functions related to courses.
- openedx.core.lib.courses.clean_course_id(model_form, is_required=True)#
Cleans and validates a course_id for use with a Django ModelForm.
- Parameters:
model_form (form.ModelForm) – The form that has a course_id.
is_required (Boolean) – Default True. When True, validates that the course_id is not empty. In all cases, when course_id is supplied, validates that it is a valid course.
- Returns:
(CourseKey) The cleaned and validated course_id as a CourseKey.
NOTE: Use this method in model forms instead of a custom “clean_course_id” method!
- openedx.core.lib.courses.course_image_url(course, image_key='course_image')#
Try to look up the image url for the course. If it’s not found, log an error and return the dead link. image_key can be one of the three: ‘course_image’, ‘hero_image’, ‘thumbnail_image’
- openedx.core.lib.courses.course_organization_image_url(course)#
Return the course organization image URL or the default image URL.
- openedx.core.lib.courses.create_course_image_thumbnail(course, dimensions)#
Create a course image thumbnail and return the URL.
dimensions is a tuple of (width, height)
- openedx.core.lib.courses.get_course_by_id(course_key, depth=0)#
Given a course id, return the corresponding course block.
If such a course does not exist, raises a 404.
depth: The number of levels of children for the modulestore to cache. None means infinite depth
openedx.core.lib.derived module#
Allows the registration of Django/Python settings that are derived from other settings via callable methods/lambdas. The derivation time can be controlled to happen after all other settings have been set. The derived setting can also be overridden by setting the derived setting to an actual value.
- class openedx.core.lib.derived.Derived(calculate_value: Callable[[ModuleType], T])#
Bases:
Generic[T]A temporary Django setting value, defined with a function which generates the setting’s eventual value.
Said function (calculate_value) should accept a Django settings module, and return a calculated value.
To ensure that application code does not encounter an instance of this class in your settings, be sure to call derive_settings somewhere in your terminal settings file.
- openedx.core.lib.derived.derive_settings(module_name: str) None#
In the Django settings module at module_name, replace Derived values with their cacluated values.
The replacement happens recursively for any values or containers defined by a Django setting name (which is: an uppercase top-level variable name which is not prefixed by an underscore). Within containers,
openedx.core.lib.django_courseware_routers module#
Database Routers for use with the coursewarehistoryextended django app.
- class openedx.core.lib.django_courseware_routers.StudentModuleHistoryExtendedRouter#
Bases:
objectA Database Router that separates StudentModuleHistoryExtended into its own database.
- DATABASE_NAME = 'student_module_history'#
- allow_migrate(db, app_label, model_name=None, **hints)#
Only sync StudentModuleHistoryExtended to StudentModuleHistoryExtendedRouter.DATABASE_Name
- allow_relation(obj1, obj2, **hints)#
Manage relations if the model is StudentModuleHistoryExtended.
- db_for_read(model, **hints)#
Use the StudentModuleHistoryExtendedRouter.DATABASE_NAME if the model is StudentModuleHistoryExtended.
- db_for_write(model, **hints)#
Use the StudentModuleHistoryExtendedRouter.DATABASE_NAME if the model is StudentModuleHistoryExtended.
openedx.core.lib.django_test_client_utils module#
This file includes util methods.
- openedx.core.lib.django_test_client_utils.get_absolute_url(path)#
Generate an absolute URL for a resource on the test server.
openedx.core.lib.dynamic_partitions_generators module#
A plugin manager to retrieve the dynamic course partitions generators.
openedx.core.lib.edx_api_utils module#
Helper functions to get data from APIs
- openedx.core.lib.edx_api_utils.get_api_data(api_config: Any, resource: str, api_client: session, base_api_url: str, resource_id: int | str | None = None, querystring: Dict[Any, Any] | None = None, cache_key: str | None = None, many: bool = True, traverse_pagination: bool = True, fields: List[Any] | None = None, long_term_cache: bool = False, raise_on_error: bool = False) List[Any] | Dict[Any, Any]#
GET data from an edX REST API endpoint using the API client.
DRY utility for handling caching and pagination.
- Parameters:
api_config (ConfigurationModel) – The configuration model governing interaction with the API.
resource (str) – Name of the API resource being requested.
api_client (requests.Session) – API client (either raw requests.Session or OAuthAPIClient) to use for requesting data.
base_api_url (str) – base API url, used to construct the full API URL across with resource and resource_id (if any).
- Keyword Arguments:
resource_id (int or str) – Identifies a specific resource to be retrieved.
querystring (dict) – Optional query string parameters.
cache_key (str) – Where to cache retrieved data. The cache will be ignored if this is omitted (neither inspected nor updated).
many (bool) – Whether the resource requested is a collection of objects, or a single object. If false, an empty dict will be returned in cases of failure rather than the default empty list.
traverse_pagination (bool) – Whether to traverse pagination or return paginated response..
fields (list) – Return only specific fields from the response
long_term_cache (bool) – Whether to use the long term cache ttl or the standard cache ttl
raise_on_error (bool) – Reraise errors back to the caller, instead if returning empty results.
- Returns:
Data returned by the API. When hitting a list endpoint, extracts “results” (list of dict) returned by DRF-powered APIs. By default, returns an empty result if the called API returns an error.
- openedx.core.lib.edx_api_utils.get_fields(fields, response)#
Extracts desired fields from the API response
openedx.core.lib.exceptions module#
Common Purpose Errors
- exception openedx.core.lib.exceptions.CourseNotFoundError#
Bases:
ObjectDoesNotExistCourse was not found.
- exception openedx.core.lib.exceptions.DiscussionNotFoundError#
Bases:
ObjectDoesNotExistDiscussion Block was not found.
- exception openedx.core.lib.exceptions.PageNotFoundError#
Bases:
ObjectDoesNotExistPage was not found. Used for paginated endpoint.
openedx.core.lib.extract_archive module#
Safe version of extractall which does not extract any files that would be, or symlink to a file that is, outside of the directory extracted in.
Adapted from: http://stackoverflow.com/questions/10060069/safely-extract-zip-or-tar-using-python
- openedx.core.lib.extract_archive.resolved(rpath)#
Returns the canonical absolute path of rpath.
- openedx.core.lib.extract_archive.safe_extractall(file_name, output_path)#
Extract Zip or Tar files
openedx.core.lib.features_setting_proxy module#
Features Proxy Implementation
- class openedx.core.lib.features_setting_proxy.FeaturesProxy(namespace=None)#
Bases:
MutableMappingA proxy for feature flags stored in the settings namespace.
Features: - Flattens features from configuration (e.g., YAML or env) into the local settings namespace. - Automatically updates django.conf.settings when a feature is modified. - Acts like a dict (get, set, update, etc.).
- Example usage:
fp = FeaturesProxy(LocalNamespace) fp[“NEW_FEATURE”] = True val = fp.get(“EXISTING_FLAG”, False)
- clear()#
Remove all feature flags from the namespace.
- copy()#
Return a shallow copy of the underlying namespace wrapped in a new FeaturesProxy.
- get(key, default=None)#
Standard dict-style get with default
- update(other=(), /, **kwds)#
Update multiple features at once, ensuring each goes through __setitem__ to emit deprecation warnings.
Mirrors dict.update() behavior: - If other is a mapping, uses its keys. - If other is iterable of pairs, updates from those. - Then applies any keyword arguments.
Examples
- proxy.update({‘FEATURE_A’: True})
-> other = {‘FEATURE_A’: True}
- proxy.update([(‘FEATURE_A’, True)])
-> other = [(‘FEATURE_A’, True)]
- proxy.update(FEATURE_B=False)
-> kwds = {‘FEATURE_B’: False}
- proxy.update({‘FEATURE_A’: True}, FEATURE_B=False)
-> other={‘FEATURE_A’: True}; kwds = {‘FEATURE_B’: False}
openedx.core.lib.grade_utils module#
Helpers functions for grades and scores.
- openedx.core.lib.grade_utils.compare_scores(earned1, possible1, earned2, possible2, treat_undefined_as_zero=False)#
- Returns a tuple of:
Whether the 2nd set of scores is higher than the first.
Grade percentage of 1st set of scores.
Grade percentage of 2nd set of scores.
If
treat_undefined_as_zerois True, this function will treat cases wherepossible1orpossible2is 0 as if the (earned / possible) score is 0. If this flag is false, a ZeroDivisionError is raised.
- openedx.core.lib.grade_utils.is_score_higher_or_equal(earned1, possible1, earned2, possible2, treat_undefined_as_zero=False)#
Returns whether the 2nd set of scores is higher than the first. If
treat_undefined_as_zerois True, this function will treat cases wherepossible1orpossible2is 0 as if the (earned / possible) score is 0. If this flag is false, a ZeroDivisionError is raised.
- openedx.core.lib.grade_utils.round_away_from_zero(number, digits=0)#
Round numbers using the ‘away from zero’ strategy as opposed to the ‘Banker’s rounding strategy.’ The strategy refers to how we round when a number is half way between two numbers. eg. 0.5, 1.5, etc. In python 3 numbers round towards even. So 0.5 would round to 0 but 1.5 would round to 2.
See here for more on floating point rounding strategies: https://en.wikipedia.org/wiki/IEEE_754#Rounding_rules
We want to continue to round away from zero so that student grades remain consistent and don’t suddenly change.
openedx.core.lib.graph_traversals module#
This module contains generic generator functions for traversing tree (and DAG) structures. It is agnostic to the underlying data structure and implementation of the tree object. It does this through dependency injection of the tree’s accessor functions: get_parents and get_children.
The following depth-first traversal methods are implemented:
Pre-order: Parent yielded before children; child with multiple
parents is yielded when first encountered.
Example use cases (when DAGs are not supported):
- User access. If computing a user’s access to a node relies
on the user’s access to the node’s parents, access to the parent has to be computed before access to the child can be determined. To support access chains, a user’s access on a node is actually an accumulation of accesses down from the root node through the ancestor chain to the actual node.
- Field value percolated down. If a value for a field is
dependent on a combination of the child’s and the parent’s value, the parent’s value should be computed before that of the child’s. Similar to “User access”, the value would be percolated down through the entire ancestor chain.
- Example: Start Date is
max(node’s start date, start date of each ancestor)
This takes the most restrictive value.
- Depth. When computing the depth of a tree, since a child’s
depth value is 1 + the parent’s depth value, the parent’s value should be computed before the child’s.
- Fast Subtree Deletion. If the tree is to be pruned during
traversal, an entire subtree can be deleted, without traversing the children, as soon as the parent is determined to be deleted.
Topological: Parent yielded before children; child with multiple
parents yielded only after all its parents are visited.
Example use cases (when DAGs are supported):
- User access. Similar to pre-order, except a user’s access
is now determined by taking a union of the percolated access value from each of the node’s parents combined with its own access.
- Field value percolated down. Similar to pre-order, except the
value for a node is calculated from the array of percolated values from each of its parents combined with its own.
- Example: Start Date is
max(node’s start date, min(max(ancestry of each parent))
This takes the most permissive from all ancestry chains.
- Depth. Similar to pre-order, except the depth of a node will
be 1 + the minimum (or the maximum depending on semantics) of the depth of all its parents.
- Deletion. Deletion of subtrees are not as fast as they are
for pre-order since a node can be accessed through multiple parents.
Post-order: Children yielded before its parents.
Example use cases:
- Counting. When each node wants to count the number of nodes
within its sub-structure, the count for each child has to be calculated before its parents, since a parent’s value depends on its children.
- Map function (when order doesn’t matter). If a function
needs to be evaluated for each node in a DAG and the order that the nodes are iterated doesn’t matter, then use post-order since it is faster than topological for DAGs.
- Field value percolated up. If a value for a field is based
on the value from it’s children, the children’s values need to be computed before their parents.
Example: Minimum Due Date of all nodes within the sub-structure.
Note: In-order traversal is not implemented as of yet. We can do so if/when needed.
Optimization once DAGs are not supported: Supporting Directed Acyclic Graphs (DAGs) requires us to use topological sort, which has the following negative performance implications:
For a simple tree, we can immediately skip over traversing
descendants, once it is determined that a parent is not to be yielded (based on the return value from the ‘filter_func’ function). However, since we support DAGs, we cannot simply skip over descendants since they may still be accessible through a different ancestry chain and need to be revisited once all their parents are visited.
For topological sort, we need the get_parents accessor function in
order to determine whether all of a node’s parents have been visited. This means the underlying implementation of the graph needs to have an efficient way to get a node’s parents, perhaps with back pointers to each node’s parents. This requires additional storage space, which could be eliminated if DAGs are not supported.
- openedx.core.lib.graph_traversals.get_children(parent)#
Function for traversals to get the children of a block
- openedx.core.lib.graph_traversals.leaf_filter(block)#
Filter for traversals to find leaf blocks
- openedx.core.lib.graph_traversals.traverse_post_order(start_node, get_children, filter_func=None)#
Generator for yielding nodes of a tree (or directed acyclic graph) in a post-order sort.
- Parameters:
traverse_topologically. (See description in)
- openedx.core.lib.graph_traversals.traverse_pre_order(start_node, get_children, filter_func=None)#
Generator for yielding nodes of a tree (or directed acyclic graph) in a pre-order sort.
- Parameters:
traverse_topologically. (See description in)
- openedx.core.lib.graph_traversals.traverse_topologically(start_node, get_parents, get_children, filter_func=None, yield_descendants_of_unyielded=False)#
Generator for yielding nodes of a tree (or directed acyclic graph) in a topological sort. The tree is traversed using the get_parents and get_children accessors. The filter_func function is used to limit which nodes are actually yielded.
- Parameters:
start_node (any hashable type)
traversal.
get_parents (node->[node]) – parent nodes for a given node.
get_children (node->[node]) – children nodes for a given node.
filter_func (node->boolean) – whether or not to yield the given node. If None, the True function is assumed.
yield_descendants_of_unyielded (boolean) –
- If False, descendants of an unyielded node are not
yielded.
- If True, descendants of an unyielded node are yielded even
if none of their parents were yielded.
Note: In case of a DAG, a descendant is yielded if any of its parents are yielded.
- Yields:
node – The result of the next node in the traversal.
openedx.core.lib.hash_utils module#
Utilities related to hashing
This duplicates functionality in django-oauth-provider, specifically long_token and short token functions which was used to create random tokens
- openedx.core.lib.hash_utils.create_hash256(max_length=None)#
Generate a hash that can be used as an application secret Warning: this is not sufficiently secure for tasks like encryption Currently, this is just meant to create sufficiently random tokens
- openedx.core.lib.hash_utils.short_token()#
Generates a hash of length 32 Warning: this is not sufficiently secure for tasks like encription Currently, this is just meant to create sufficiently random tokens
openedx.core.lib.html_to_text module#
Provides a function to convert html to plaintext.
- openedx.core.lib.html_to_text.html_to_text(html_message)#
Converts an html message to plaintext. Currently uses lynx in a subprocess; should be refactored to use something more pythonic.
openedx.core.lib.json_utils module#
Helpers for json serialization
- class openedx.core.lib.json_utils.EdxJSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)#
Bases:
DjangoJSONEncoderCustom JSONEncoder that handles Location and datetime.datetime objects.
`Location`s are encoded as their url string form, and `datetime`s as ISO date strings
- default(o)#
Implement this method in a subclass such that it returns a serializable object for
o, or calls the base implementation (to raise aTypeError).For example, to support arbitrary iterators, you could implement default like this:
def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Let the base class default method raise the TypeError return super().default(o)
openedx.core.lib.jwt module#
JWT Token handling and signing functions.
- openedx.core.lib.jwt.create_jwt(lms_user_id, expires_in_seconds, additional_token_claims, now=None)#
Produce an encoded JWT (string) indicating some temporary permission for the indicated user.
What permission that is must be encoded in additional_claims. :param lms_user_id: LMS user ID this token is being generated for :type lms_user_id: int :param expires_in_seconds: Time to token expiry, specified in seconds. :type expires_in_seconds: int :param additional_token_claims: Additional claims to include in the token. :type additional_token_claims: dict :param now: optional now value for testing :type now: int
- openedx.core.lib.jwt.unpack_and_verify(token)#
Unpack and verify the provided token.
The signing key and algorithm are pulled from settings.
- openedx.core.lib.jwt.unpack_jwt(token, lms_user_id, now=None)#
Unpack and verify an encoded JWT.
Validate the user and expiration.
- Parameters:
token (string) – The token to be unpacked and verified.
lms_user_id (int) – LMS user ID this token should match with.
now (int) – Optional now value for testing.
Returns a valid, decoded json payload (string).
openedx.core.lib.log_utils module#
Helper functions for logging.
- openedx.core.lib.log_utils.audit_log(name, **kwargs)#
DRY helper used to emit an INFO-level log message.
Messages logged with this function are used to construct an audit trail. Log messages should be emitted immediately after the event they correspond to has occurred and, if applicable, after the database has been updated. These log messages use a verbose key-value pair syntax to make it easier to extract fields when parsing the application’s logs.
This function is variadic, accepting a variable number of keyword arguments.
- Parameters:
name (str) – The name of the message to log. For example, ‘payment_received’.
- Keyword Arguments:
key-value (Indefinite. Keyword arguments are strung together as comma-separated)
message. (pairs ordered alphabetically by key in the resulting log)
- Returns:
None
openedx.core.lib.logsettings module#
Get log settings.
- openedx.core.lib.logsettings.get_docker_logger_config(log_dir='/var/tmp', logging_env='no_env', edx_filename='edx.log', dev_env=False, debug=False, service_variant='lms')#
Return the appropriate logging config dictionary for a docker based setup. You should assign the result of this to the LOGGING var in your settings.
- openedx.core.lib.logsettings.get_logger_config(log_dir, logging_env='no_env', local_loglevel='INFO', service_variant='')#
Return the appropriate logging config dictionary. You should assign the result of this to the LOGGING var in your settings. The reason it’s done this way instead of registering directly is because I didn’t want to worry about resetting the logging state if this is called multiple times when settings are extended.
- openedx.core.lib.logsettings.log_python_warnings()#
Stop ignoring DeprecationWarning, ImportWarning, and PendingDeprecationWarning; log all Python warnings to the main log file.
Not used in test runs, so pytest can collect the warnings triggered for each test case.
openedx.core.lib.mail_utils module#
Utilities related to mailing.
- openedx.core.lib.mail_utils.wrap_message(message, width=900)#
RFC 2822 states that line lengths in emails must be less than 998. Some MTA’s add newlines to messages if any line exceeds a certain limit (the exact limit varies). Sendmail goes so far as to add ‘!
- ‘ after the 990th character in
a line. To ensure that messages look consistent this helper function wraps long lines to a conservative length.
openedx.core.lib.mobile_utils module#
Common utilities related to the mobile apps.
- openedx.core.lib.mobile_utils.is_request_from_mobile_app(request)#
Returns whether the given request was made by an Open edX mobile app, either natively or through the mobile web view.
- Parameters:
request (HttpRequest)
openedx.core.lib.request_utils module#
Utility functions related to HTTP requests
- class openedx.core.lib.request_utils.IgnoredErrorMiddleware(get_response)#
Bases:
objectMiddleware to add logging and monitoring for ignored errors.
- process_exception(request, exception)#
Add logging and monitoring of ignored errors.
- openedx.core.lib.request_utils.clear_cached_ignored_error_settings()#
Clears the cached ignored error settings. Useful for testing.
- openedx.core.lib.request_utils.course_id_from_url(url)#
Extracts the course_id from the given url.
- openedx.core.lib.request_utils.get_request_or_stub()#
Return the current request or a stub request.
If called outside the context of a request, construct a fake request that can be used to build an absolute URI.
This is useful in cases where we need to pass in a request object but don’t have an active request (for example, in tests, celery tasks, and XBlocks).
- openedx.core.lib.request_utils.ignored_error_exception_handler(exc, context)#
Replacement for DRF’s default exception handler to enable observing ignored errors.
In addition to the default behaviour, add logging and monitoring for ignored errors.
- openedx.core.lib.request_utils.safe_get_host(request)#
Get the host name for this request, as safely as possible.
If ALLOWED_HOSTS is properly set, this calls request.get_host; otherwise, this returns whatever settings.SITE_NAME is set to.
This ensures we will never accept an untrusted value of get_host()
openedx.core.lib.rooted_paths module#
Provides rooted_glob, for finding relative glob paths in another director.
- openedx.core.lib.rooted_paths.remove_root(root, paths)#
Returns paths made relative to root
- openedx.core.lib.rooted_paths.rooted_glob(root, glob)#
Returns the results of running glob rooted in the directory root. All returned paths are relative to root.
Uses glob2 globbing
openedx.core.lib.session_serializers module#
Custom session serializer to deal with going from python2 and python3.
- class openedx.core.lib.session_serializers.PickleSerializer#
Bases:
objectSet the pickle protocol version explicitly because we don’t want to have session thrashing when we upgrade to newer versions of python.
Based on the PickleSerializer built into django: django/django
- dumps(obj)#
Return a pickled representation of object.
- loads(data)#
Return a python object from pickled data.
- protocol = 4#
openedx.core.lib.teams_config module#
Safe configuration wrapper for Course Teams feature.
- class openedx.core.lib.teams_config.TeamsConfig(data)#
Bases:
objectConfiguration for the Course Teams feature on a course run.
Takes in a configuration from a JSON-friendly dictionary, and exposes cleaned data from it.
- calc_max_team_size(teamset_id)#
Given a team-set’s ID, return the maximum allowed size of teams within it.
For ‘open’ team-sets, first regards the team-set’s max_team_size, then falls back to the course’s max_team_size. For managed team-sets, returns MANAGED_TEAM_MAX_TEAM_SIZE (a number that is big enough to never really be a limit, but does put an upper limit for safety’s sake)
Return value of None should be regarded as “no maximum size” (TODO MST-33).
- cleaned_data#
JSON-friendly dictionary containing cleaned data from this TeamsConfig.
- default_max_team_size#
The default maximum size for teams in this course.
Can be overriden by individual team sets; see calc_max_team_size.
- property is_enabled#
Whether the Course Teams feature is enabled for this course run.
- property source_data#
Dictionary containing the data from which this TeamsConfig was built.
- teamsets#
List of configurations for team-sets.
A team-set is a logical collection of teams, generally centered around a discussion topic or assignment.
A learner should be able to join one team per team-set (TODO MST-12… currently, a learner may join one team per course).
- teamsets_by_id#
- class openedx.core.lib.teams_config.TeamsetConfig(data)#
Bases:
objectConfiguration for a team-set within a course run.
Takes in a configuration from a JSON-friendly dictionary, and exposes cleaned data from it.
- cleaned_data#
JSON-friendly dictionary containing cleaned data from this TeamsConfig.
- description#
A brief description of the team-set, falling back to empty string.
- is_private_managed#
Returns true if teamsettype is private_managed
- max_team_size#
Configured maximum team size override for this team-set, falling back to None.
- name#
A human-friendly name of the team-set, falling back to teamset_id.
- property source_data#
Dictionary containing the data from which this TeamsConfig was built.
- teamset_id#
An identifier for this team-set.
Should be a URL-slug friendly string, but for a historical reasons may contain periods and spaces.
- teamset_id_regex = re.compile('^[A-Za-z0-9_. -]+$')#
- teamset_type#
Configured TeamsetType, falling back to default TeamsetType.
- user_partition_id#
The ID of the dynamic user partition for this team-set, falling back to None.
- class openedx.core.lib.teams_config.TeamsetType(*values)#
Bases:
EnumManagement and privacy scheme for teams within a team-set.
“open” team-sets allow learners to freely join, leave, and create teams.
“public_managed” team-sets forbid learners from modifying teams’ membership. Instead, instructors manage membership (TODO MST-9).
“private_managed” is like public_managed, except for that team names, team memberships, and team discussions are all private to the members of the teams (TODO MST-10).
- classmethod get_default()#
Return default TeamsetType.
- open = 'open'#
- open_managed = 'open_managed'#
- private_managed = 'private_managed'#
- public_managed = 'public_managed'#
- openedx.core.lib.teams_config.create_team_set_partition(course)#
Get the dynamic enrollment track user partition based on the team-sets of the course.
- openedx.core.lib.teams_config.create_team_set_partitions_with_course_id(course_id, team_sets=None)#
Create and return the team-set user partitions based only on course_id. If they cannot be created, None is returned.
openedx.core.lib.tempdir module#
Make temporary directories nicely.
- openedx.core.lib.tempdir.cleanup_tempdir(the_dir)#
Called on process exit to remove a temp directory.
- openedx.core.lib.tempdir.create_symlink(src, dest)#
Creates a symbolic link which will be deleted when the process ends. :param src: path to source :param dest: path to destination
- openedx.core.lib.tempdir.delete_symlink(link_path)#
Removes symbolic link for :param link_path:
- openedx.core.lib.tempdir.mkdtemp_clean(suffix='', prefix='tmp', dir=None)#
Just like mkdtemp, but the directory will be deleted when the process ends.
openedx.core.lib.time_zone_utils module#
Utilities related to timezones
- openedx.core.lib.time_zone_utils.get_display_time_zone(time_zone_name)#
Returns a formatted display time zone (e.g. ‘Asia/Tokyo (JST, UTC+0900)’)
- Parameters:
(str) (time_zone_name) – Name of Pytz time zone
- openedx.core.lib.time_zone_utils.get_time_zone_abbr(time_zone, date_time=None)#
Returns the time zone abbreviation (e.g. EST) of the time zone for given datetime
- openedx.core.lib.time_zone_utils.get_time_zone_offset(time_zone, date_time=None)#
Returns the time zone offset (e.g. -0800) of the time zone for given datetime
openedx.core.lib.url_utils module#
Contains common utilities for URL escaping.
- openedx.core.lib.url_utils.quote_slashes(text)#
Quote ‘/’ characters so that they aren’t visible to django’s url quoting, unquoting, or url regex matching.
Escapes ‘/’’ to the sequence ‘;_’, and ‘;’ to the sequence ‘;;’. By making the escape sequence fixed length, and escaping identifier character ‘;’, we are able to reverse the escaping.
- openedx.core.lib.url_utils.unquote_slashes(text)#
Unquote slashes quoted by quote_slashes
openedx.core.lib.user_util module#
Main module.
- openedx.core.lib.user_util.get_all_retired_emails(email, salt_list, retired_email_fmt='retired_email_{}@retired.edx.org')#
Returns a generator of possible retired email addresses based on the original lowercased email and all the historical salts, from oldest to current. The current salt is assumed to be the last salt in the list.
Raises
ValueErrorif the salt isn’t a list of salts.- Parameters:
email (str) – Email address of the user to be retired.
salt_list (list/tuple) – List of all historical salts.
- Yields:
Returns a generator of possible retired email addresses based on the original email and all the historical salts, including the current salt, from oldest to current.
- openedx.core.lib.user_util.get_all_retired_external_keys(external_key, salt_list, retired_external_key_fmt='retired_external_key_{}')#
Returns a generator of possible retired external user key based on the original external user key and all the historical salts, from oldest to current. The current salt is assumed to be the last salt in the list.
Raises
ValueErrorif the salt isn’t a list of salts.- Parameters:
external_key (str) – External user key of the user to be retired.
salt_list (list/tuple) – List of all historical salts.
- Yields:
Returns a generator of possible retired external user keys based on the original external key and all the historical salts, including the current salt, from oldest to current.
- openedx.core.lib.user_util.get_all_retired_usernames(username, salt_list, retired_username_fmt='retired_username_{}')#
Returns a generator of possible retired usernames based on the original lowercased username and all the historical salts, from oldest to current. The current salt is assumed to be the last salt in the list.
Raises
ValueErrorif the salt isn’t a list of salts.- Parameters:
username (str) – The name of the user to be retired.
salt_list (list/tuple) – List of all historical salts.
- Yields:
Returns a generator of possible retired usernames based on the original username and all the historical salts, including the current salt, from oldest to current.
- openedx.core.lib.user_util.get_retired_email(email, salt_list, retired_email_fmt='retired_email_{}@retired.edx.org')#
Returns a retired email address based on the original lowercased email address and the current salt. The current salt is assumed to be the last salt in the list.
Raises
ValueErrorif salt_list isn’t a list of salts.- Parameters:
email (str) – Email address of the user to be retired.
salt_list (list/tuple) – List of all historical salts.
- Yields:
Returns a retired email address based on the original email and the current salt
- openedx.core.lib.user_util.get_retired_external_key(external_key, salt_list, retired_external_key_fmt='retired_external_key_{}')#
Returns a retired external user key based on the original external key and the current salt. The current salt is assumed to be the last salt in the list.
Raises
ValueErrorif salt_list isn’t a list of salts.- Parameters:
external_key (str) – External user key of the user to be retired.
salt_list (list/tuple) – List of all historical salts.
- Yields:
Returns a retired external user key based on the original external_user_key and the current salt
- openedx.core.lib.user_util.get_retired_username(username, salt_list, retired_username_fmt='retired_username_{}')#
Returns a retired username based on the original lowercased username and all the historical salts, from oldest to current. The current salt is assumed to be the last salt in the list.
Raises
ValueErrorif the salt isn’t a list of salts.- Parameters:
username (str) – The name of the user to be retired.
salt_list (list/tuple) – List of all historical salts.
- Yields:
Returns a retired username based on the original username and all the historical salts, including the current salt.
Module contents#
This directory (openedx/core/lib) contains packages of utilities used by both LMS and CMS. Packages with models should go in openedx/core/djangoapps instead. Packages that are LMS-specific or CMS-specific should be in lms/ or cms/ instead.
This particular module contains a small handful of broadly useful utility functions.
- openedx.core.lib.ensure_cms(message: str = 'This code may only be called by CMS, but it was called by LMS')#
Assert that we’re configured as CMS.
Useful if you want to forbid authoring-oriented code from accidentally running in the LMS process.
- openedx.core.lib.ensure_lms(message: str = 'This code may only be called by LMS, but it was called by CMS')#
Assert that we’re configured as LMS.
Useful if you want to forbid learner/instructor-oriented code from accidentally running in the CMS process.