Files
edx-platform/cms/envs/common.py
Feanil Patel d76bed4bbb style: Drop unused imports. (#37572)
* style: Drop unused imports.

I was looking at these files for some other reason and saw that these
imports were unused. Some of it looks like an artifact of the hoisting
of some settings up to the `openedx/env/common.py` file and others look
like some ancient unused imports.


Co-authored-by: Kyle McCormick <kyle@axim.org>
2025-10-30 10:55:38 -04:00

1795 lines
66 KiB
Python

"""
This is the common settings file, intended to set sane defaults. If you have a
piece of configuration that's dependent on a set of feature flags being set,
then create a function that returns the calculated value based on the value of
FEATURES[...]. Modules that extend this one can change the feature
configuration in an environment specific config file and re-calculate those
values.
We should make a method that calls all these config methods so that you just
make one call at the end of your site-specific dev file to reset all the
dependent variables (like INSTALLED_APPS) for you.
Longer TODO:
1. Right now our treatment of static content in general and in particular
course-specific static content is haphazard.
2. We should have a more disciplined approach to feature flagging, even if it
just means that we stick them in a dict called FEATURES.
3. We need to handle configuration for multiple courses. This could be as
multiple sites, but we do need a way to map their data assets.
When refering to XBlocks, we use the entry-point name. For example,
| setup(
| name='xblock-foobar',
| version='0.1',
| packages=[
| 'foobar_xblock',
| ],
| entry_points={
| 'xblock.v1': [
| 'foobar-block = foobar_xblock:FoobarBlock',
| # ^^^^^^^^^^^^ This is the one you want.
| ]
| },
| )
"""
# We intentionally define lots of variables that aren't used, and
# want to import all variables from base settings files
# pylint: disable=unused-import, useless-suppression, wrong-import-order, wrong-import-position
import importlib.util
import os
from corsheaders.defaults import default_headers as corsheaders_default_headers
from datetime import timedelta
from django.utils.translation import gettext_lazy as _
import lms.envs.common
from openedx.envs.common import * # pylint: disable=wildcard-import
from path import Path as path
from lms.djangoapps.lms_xblock.mixin import LmsBlockMixin
from cms.lib.xblock.authoring_mixin import AuthoringMixin
from cms.lib.xblock.upstream_sync import UpstreamSyncMixin
from xmodule.modulestore.edit_info import EditInfoMixin
from openedx.core.lib.derived import Derived
from openedx.core.lib.features_setting_proxy import FeaturesProxy
# A proxy for feature flags stored in the settings namespace
FEATURES = FeaturesProxy(globals())
# pylint: enable=useless-suppression
############################ FEATURE CONFIGURATION #############################
CONTACT_MAILING_ADDRESS = _('Your Contact Mailing Address Here')
# Dummy secret key for dev/test
SECRET_KEY = 'dev key'
# .. setting_name: STUDIO_NAME
# .. setting_default: Your Platform Studio
# .. setting_description: The name that will appear on the landing page of Studio, as well as in various emails and
# templates.
STUDIO_NAME = _("Your Platform Studio")
STUDIO_SHORT_NAME = _("Studio")
# FEATURES
GITHUB_PUSH = False
# email address for studio staff (eg to request course creation)
STUDIO_REQUEST_EMAIL = ''
# Segment - must explicitly turn it on for production
CMS_SEGMENT_KEY = None
# If set to True, new Studio users won't be able to author courses unless
# an Open edX admin has added them to the course creator group.
ENABLE_CREATOR_GROUP = True
# If set to True, organization staff members can create libraries for their specific
# organization and no other organizations. They do not need to be course creators,
# even when ENABLE_CREATOR_GROUP is True.
ENABLE_ORGANIZATION_STAFF_ACCESS_FOR_CONTENT_LIBRARIES = True
# Turn off account locking if failed login attempts exceeds a limit
ENABLE_MAX_FAILED_LOGIN_ATTEMPTS = False
# .. toggle_name: settings.EDITABLE_SHORT_DESCRIPTION
# .. toggle_implementation: DjangoSetting
# .. toggle_default: True
# .. toggle_description: This feature flag allows editing of short descriptions on the Schedule & Details page in
# Open edX Studio. Set to False if you want to disable the editing of the course short description.
# .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2014-02-13
# .. toggle_tickets: https://github.com/openedx/edx-platform/pull/2334
EDITABLE_SHORT_DESCRIPTION = True
# Hide any Personally Identifiable Information from application logs
SQUELCH_PII_IN_LOGS = False
# Allow creating courses with non-ascii characters in the course id
ALLOW_UNICODE_COURSE_ID = False
# Prevent concurrent logins per user
PREVENT_CONCURRENT_LOGINS = False
# Turn off Video Upload Pipeline through Studio, by default
ENABLE_VIDEO_UPLOAD_PIPELINE = False
# Show a new field in "Advanced settings" that can store custom data about a
# course and that can be read from themes
ENABLE_OTHER_COURSE_SETTINGS = False
# Enable support for content libraries. Note that content libraries are
# only supported in courses using split mongo.
ENABLE_CONTENT_LIBRARIES = True
# .. toggle_name: settings.ENABLE_CONTENT_LIBRARIES_LTI_TOOL
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: When set to True, Content Libraries in
# Studio can be used as an LTI 1.3 tool by external LTI platforms.
# .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2021-08-17
# .. toggle_tickets: https://github.com/openedx/edx-platform/pull/27411
ENABLE_CONTENT_LIBRARIES_LTI_TOOL = False
# Toggle course entrance exams feature
ENTRANCE_EXAMS = False
# Enable the courseware search functionality
ENABLE_COURSEWARE_INDEX = False
# Enable content libraries (modulestore) search functionality
ENABLE_LIBRARY_INDEX = False
# .. toggle_name: settings.ALLOW_COURSE_RERUNS
# .. toggle_implementation: DjangoSetting
# .. toggle_default: True
# .. toggle_description: This will allow staff member to re-run the course from the studio home page and will
# always use the split modulestore. When this is set to False, the Re-run Course link will not be available on
# the studio home page.
# .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2015-02-13
# .. toggle_tickets: https://github.com/openedx/edx-platform/pull/6965
ALLOW_COURSE_RERUNS = True
# Whether archived courses (courses with end dates in the past) should be
# shown in Studio in a separate list.
ENABLE_SEPARATE_ARCHIVED_COURSES = True
ENABLE_GRADE_DOWNLOADS = True
ENABLE_DISCUSSION_HOME_PANEL = True
ENABLE_COUNTRY_ACCESS = False
ENABLE_CREDIT_API = False
### ORA Feature Flags ###
# .. toggle_name: settings.DEPRECATE_OLD_COURSE_KEYS_IN_STUDIO
# .. toggle_implementation: DjangoSetting
# .. toggle_default: True
# .. toggle_description: Warn about removing support for deprecated course keys.
# To enable, set to True.
# To disable, set to False.
# To enable with a custom support deadline, set to an ISO-8601 date string:
# eg: '2020-09-01'
# .. toggle_use_cases: temporary
# .. toggle_creation_date: 2020-06-12
# .. toggle_target_removal_date: 2021-04-01
# .. toggle_warning: This can be removed once support is removed for deprecated
# course keys.
# .. toggle_tickets: https://openedx.atlassian.net/browse/DEPR-58
DEPRECATE_OLD_COURSE_KEYS_IN_STUDIO = True
# .. toggle_name: settings.DISABLE_COURSE_CREATION
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: If set to True, it disables the course creation functionality and hides the "New Course"
# button in studio.
# It is important to note that the value of this flag only affects if the user doesn't have a staff role,
# otherwise the course creation functionality will work as it should.
# .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2013-12-02
# .. toggle_warning: Another toggle DISABLE_LIBRARY_CREATION overrides DISABLE_COURSE_CREATION, if present.
DISABLE_COURSE_CREATION = False
# .. toggle_name: settings.ENABLE_LTI_PII_ACKNOWLEDGEMENT
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: Enables the lti pii acknowledgement feature for a course
# .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2023-10
# .. toggle_target_removal_date: None
# .. toggle_tickets: 'https://2u-internal.atlassian.net/browse/MST-2055'
ENABLE_LTI_PII_ACKNOWLEDGEMENT = False
# .. toggle_name: settings.DISABLE_ADVANCED_SETTINGS
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: Set to `True` to disable the advanced settings page in Studio for all users except those
# having `is_superuser` or `is_staff` set to `True`.
# .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2023-03-31
# .. toggle_tickets: https://github.com/openedx/edx-platform/pull/32015
DISABLE_ADVANCED_SETTINGS = False
# .. toggle_name: settings.ENABLE_SEND_XBLOCK_LIFECYCLE_EVENTS_OVER_BUS
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: Enables sending xblock lifecycle events over the event bus. Used to create the
# EVENT_BUS_PRODUCER_CONFIG setting
# .. toggle_use_cases: opt_in
# .. toggle_creation_date: 2023-10-10
# .. toggle_target_removal_date: 2023-10-12
# .. toggle_warning: The default may be changed in a later release. See
# https://github.com/openedx/openedx-events/issues/265
# .. toggle_tickets: https://github.com/edx/edx-arch-experiments/issues/381
ENABLE_SEND_XBLOCK_LIFECYCLE_EVENTS_OVER_BUS = False
# .. toggle_name: settings.ENABLE_HIDE_FROM_TOC_UI
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: When enabled, exposes hide_from_toc xblock attribute so course authors can configure it as
# a section visibility option in Studio.
# .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2024-02-29
# .. toggle_tickets: https://github.com/openedx/edx-platform/pull/33952
ENABLE_HIDE_FROM_TOC_UI = False
# .. toggle_name: settings.IN_CONTEXT_DISCUSSION_ENABLED_DEFAULT
# .. toggle_implementation: DjangoSetting
# .. toggle_default: True
# .. toggle_description: Set to False to disable in-context discussion for units by default.
# .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2024-09-02
IN_CONTEXT_DISCUSSION_ENABLED_DEFAULT = True
# .. toggle_name: ENABLE_COPPA_COMPLIANCE
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: When True, inforces COPPA compliance and removes YOB field from registration form and accounnt
# .. settings page. Also hide YOB banner from profile page.
# .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2021-10-27
# .. toggle_tickets: 'https://openedx.atlassian.net/browse/VAN-622'
ENABLE_COPPA_COMPLIANCE = False
ENABLE_JASMINE = False
MARKETING_EMAILS_OPT_IN = False
############################# MICROFRONTENDS ###################################
COURSE_AUTHORING_MICROFRONTEND_URL = None
############################# SOCIAL MEDIA SHARING #############################
SOCIAL_SHARING_SETTINGS = {
# Note: Ensure 'CUSTOM_COURSE_URLS' has a matching value in lms/envs/common.py
'CUSTOM_COURSE_URLS': False,
'DASHBOARD_FACEBOOK': False,
'CERTIFICATE_FACEBOOK': False,
'CERTIFICATE_TWITTER': False,
'DASHBOARD_TWITTER': False
}
############################# SET PATH INFORMATION #############################
PROJECT_ROOT = path(__file__).abspath().dirname().dirname() # /edx-platform/cms
REPO_ROOT = PROJECT_ROOT.dirname()
COMMON_ROOT = REPO_ROOT / "common"
OPENEDX_ROOT = REPO_ROOT / "openedx"
CMS_ROOT = REPO_ROOT / "cms"
LMS_ROOT = REPO_ROOT / "lms"
ENV_ROOT = REPO_ROOT.dirname() # virtualenv dir /edx-platform is in
COURSES_ROOT = ENV_ROOT / "data"
XMODULE_ROOT = REPO_ROOT / "xmodule"
GITHUB_REPO_ROOT = ENV_ROOT / "data"
# For geolocation ip database
GEOIP_PATH = REPO_ROOT / "common/static/data/geoip/GeoLite2-Country.mmdb"
DATA_DIR = COURSES_ROOT
######################## BRANCH.IO ###########################
BRANCH_IO_KEY = ''
######################## GOOGLE ANALYTICS ###########################
GOOGLE_ANALYTICS_ACCOUNT = None
######################## HOTJAR ###########################
HOTJAR_ID = 00000
############################# TEMPLATE CONFIGURATION #############################
# Mako templating
import tempfile
MAKO_MODULE_DIR = os.path.join(tempfile.gettempdir(), 'mako_cms')
MAKO_TEMPLATE_DIRS_BASE = [
PROJECT_ROOT / 'templates',
COMMON_ROOT / 'templates',
COMMON_ROOT / 'djangoapps' / 'pipeline_mako' / 'templates',
COMMON_ROOT / 'static', # required to statically include common Underscore templates
OPENEDX_ROOT / 'core' / 'djangoapps' / 'cors_csrf' / 'templates',
OPENEDX_ROOT / 'core' / 'djangoapps' / 'dark_lang' / 'templates',
OPENEDX_ROOT / 'core' / 'lib' / 'license' / 'templates',
CMS_ROOT / 'djangoapps' / 'pipeline_js' / 'templates',
]
CONTEXT_PROCESSORS = (
'django.template.context_processors.request',
'django.template.context_processors.static',
'django.contrib.messages.context_processors.messages',
'django.template.context_processors.i18n',
'django.contrib.auth.context_processors.auth', # this is required for admin
'django.template.context_processors.csrf',
'help_tokens.context_processor',
'openedx.core.djangoapps.site_configuration.context_processors.configuration_context',
)
# Django templating
TEMPLATES = [
{
'NAME': 'django',
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# Don't look for template source files inside installed applications.
'APP_DIRS': False,
# Instead, look for template source files in these dirs.
'DIRS': Derived(make_mako_template_dirs),
# Options specific to this backend.
'OPTIONS': {
'loaders': (
# We have to use mako-aware template loaders to be able to include
# mako templates inside django templates (such as main_django.html).
'openedx.core.djangoapps.theming.template_loaders.ThemeTemplateLoader',
'common.djangoapps.edxmako.makoloader.MakoFilesystemLoader',
'common.djangoapps.edxmako.makoloader.MakoAppDirectoriesLoader',
),
'context_processors': CONTEXT_PROCESSORS,
# Change 'debug' in your environment settings files - not here.
'debug': False
}
},
{
'NAME': 'mako',
'BACKEND': 'common.djangoapps.edxmako.backend.Mako',
'APP_DIRS': False,
'DIRS': Derived(make_mako_template_dirs),
'OPTIONS': {
'context_processors': CONTEXT_PROCESSORS,
'debug': False,
}
},
{
# This separate copy of the Mako backend is used to render previews using the LMS templates
'NAME': 'preview',
'BACKEND': 'common.djangoapps.edxmako.backend.Mako',
'APP_DIRS': False,
'DIRS': lms.envs.common.MAKO_TEMPLATE_DIRS_BASE,
'OPTIONS': {
'context_processors': CONTEXT_PROCESSORS,
'debug': False,
'namespace': 'lms.main',
}
},
]
DEFAULT_TEMPLATE_ENGINE = TEMPLATES[0]
#################################### AWS #######################################
AWS_SECURITY_TOKEN = None
##############################################################################
# use the ratelimit backend to prevent brute force attacks
AUTHENTICATION_BACKENDS = [
'auth_backends.backends.EdXOAuth2',
'rules.permissions.ObjectPermissionBackend',
'openedx.core.djangoapps.content_libraries.auth.LtiAuthenticationBackend',
'django.contrib.auth.backends.AllowAllUsersModelBackend',
'bridgekeeper.backends.RulePermissionBackend',
]
LMS_BASE = None
# Use LMS SSO for login, once enabled by setting LOGIN_URL (see docs/guides/studio_oauth.rst)
SOCIAL_AUTH_STRATEGY = 'auth_backends.strategies.EdxDjangoStrategy'
LOGIN_REDIRECT_URL = EDX_ROOT_URL + '/home/'
LOGIN_URL = '/login/'
FRONTEND_LOGIN_URL = LOGIN_URL
# Warning: Must have trailing slash to activate correct logout view
# (auth_backends, not LMS user_authn)
FRONTEND_LOGOUT_URL = '/logout/'
FRONTEND_REGISTER_URL = Derived(lambda settings: settings.LMS_ROOT_URL + '/register')
ENTERPRISE_API_URL = Derived(lambda settings: settings.LMS_INTERNAL_ROOT_URL + '/enterprise/api/v1/')
ENTERPRISE_CONSENT_API_URL = Derived(lambda settings: settings.LMS_INTERNAL_ROOT_URL + '/consent/api/v1/')
# Public domain name of Studio (should be resolvable from the end-user's browser)
CMS_BASE = None
CMS_ROOT_URL = None
MAINTENANCE_BANNER_TEXT = 'Sample banner message'
WIKI_ENABLED = True
CERT_QUEUE = 'certificates'
################################# Middleware ###################################
MIDDLEWARE = [
'openedx.core.lib.x_forwarded_for.middleware.XForwardedForMiddleware',
'edx_django_utils.security.csp.middleware.content_security_policy_middleware',
'crum.CurrentRequestUserMiddleware',
# Resets the request cache.
'edx_django_utils.cache.middleware.RequestCacheMiddleware',
# Various monitoring middleware
'edx_django_utils.monitoring.CookieMonitoringMiddleware',
'edx_django_utils.monitoring.DeploymentMonitoringMiddleware',
'edx_django_utils.monitoring.FrontendMonitoringMiddleware',
'edx_django_utils.monitoring.MonitoringMemoryMiddleware',
'openedx.core.djangoapps.header_control.middleware.HeaderControlMiddleware',
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sites.middleware.CurrentSiteMiddleware',
# CORS and CSRF
'django.middleware.csrf.CsrfViewMiddleware',
'corsheaders.middleware.CorsMiddleware',
'openedx.core.djangoapps.cors_csrf.middleware.CorsCSRFMiddleware',
'openedx.core.djangoapps.cors_csrf.middleware.CsrfCrossDomainCookieMiddleware',
# JWT auth
'edx_rest_framework_extensions.auth.jwt.middleware.JwtAuthCookieMiddleware',
# Allows us to define redirects via Django admin
'django_sites_extensions.middleware.RedirectMiddleware',
# Instead of SessionMiddleware, we use a more secure version
# 'django.contrib.sessions.middleware.SessionMiddleware',
'openedx.core.djangoapps.safe_sessions.middleware.SafeSessionMiddleware',
'method_override.middleware.MethodOverrideMiddleware',
# Instead of AuthenticationMiddleware, we use a cache-backed version
'openedx.core.djangoapps.cache_toolbox.middleware.CacheBackedAuthenticationMiddleware',
'common.djangoapps.student.middleware.UserStandingMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'common.djangoapps.track.middleware.TrackMiddleware',
# This is used to set or update the user language preferences.
'openedx.core.djangoapps.lang_pref.middleware.LanguagePreferenceMiddleware',
# Allows us to dark-launch particular languages
'openedx.core.djangoapps.dark_lang.middleware.DarkLangMiddleware',
'openedx.core.djangoapps.embargo.middleware.EmbargoMiddleware',
# Detects user-requested locale from 'accept-language' header in http request
'django.middleware.locale.LocaleMiddleware',
'codejail.django_integration.ConfigureCodeJailMiddleware',
# for expiring inactive sessions
'openedx.core.djangoapps.session_inactivity_timeout.middleware.SessionInactivityTimeout',
'openedx.core.djangoapps.theming.middleware.CurrentSiteThemeMiddleware',
# use Django built in clickjacking protection
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'waffle.middleware.WaffleMiddleware',
# Enables force_django_cache_miss functionality for TieredCache.
'edx_django_utils.cache.middleware.TieredCacheMiddleware',
# Adds monitoring attributes to requests.
'edx_rest_framework_extensions.middleware.RequestCustomAttributesMiddleware',
'edx_rest_framework_extensions.auth.jwt.middleware.EnsureJWTAuthSettingsMiddleware',
# Handles automatically storing user ids in django-simple-history tables when possible.
'simple_history.middleware.HistoryRequestMiddleware',
# This must be last so that it runs first in the process_response chain
'openedx.core.djangoapps.site_configuration.middleware.SessionCookieDomainOverrideMiddleware',
]
EXTRA_MIDDLEWARE_CLASSES = []
############# XBlock Configuration ##########
# Import after sys.path fixup
from xmodule.modulestore.inheritance import InheritanceMixin
from xmodule.x_module import XModuleMixin, ResourceTemplates
# These are the Mixins that will be added to every Blocklike upon instantiation.
# DO NOT EXPAND THIS LIST!! We want it eventually to be EMPTY. Why? Because dynamically adding functions/behaviors to
# objects at runtime is confusing for both developers and static tooling (pylint/mypy). Instead...
# - to add special Blocklike behaviors just for your site: override `XBLOCK_EXTRA_MIXINS` with your own XBlockMixins.
# - to add new functionality to all Blocklikes: add it to the base Blocklike class in the core openedx/XBlock repo.
XBLOCK_MIXINS = (
# TODO: For each of these, either
# (a) merge their functionality into the base Blocklike class, or
# (b) refactor their functionality out of the Blocklike objects and into the edx-platform block runtimes.
LmsBlockMixin,
InheritanceMixin,
ResourceTemplates,
XModuleMixin,
EditInfoMixin,
UpstreamSyncMixin, # Should be above AuthoringMixin for UpstreamSyncMixin.editor_saved to take effect
AuthoringMixin,
)
############################ ORA 2 ############################################
# By default, don't use a file prefix
ORA2_FILE_PREFIX = 'default_env-default_deployment/ora2'
############################ Modulestore Configuration ################################
DOC_STORE_CONFIG = {
'db': 'edxapp',
'host': 'localhost',
'replicaSet': '',
'user': 'edxapp',
'port': 27017,
'collection': 'modulestore',
'ssl': False,
# https://api.mongodb.com/python/2.9.1/api/pymongo/mongo_client.html#module-pymongo.mongo_client
# default is never timeout while the connection is open,
#this means it needs to explicitly close raising pymongo.errors.NetworkTimeout
'socketTimeoutMS': 6000,
'connectTimeoutMS': 2000, # default is 20000, I believe raises pymongo.errors.ConnectionFailure
# Not setting waitQueueTimeoutMS and waitQueueMultiple since pymongo defaults to nobody being allowed to wait
'auth_source': None,
'read_preference': 'PRIMARY'
# If 'asset_collection' defined, it'll be used
# as the collection name for asset metadata.
# Otherwise, a default collection name will be used.
}
CONTENTSTORE = {
'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
# connection strings are duplicated temporarily for
# backward compatibility
'OPTIONS': {
'db': 'edxapp',
'host': 'localhost',
'password': 'password',
'port': 27017,
'user': 'edxapp',
'ssl': False,
'auth_source': None
},
'ADDITIONAL_OPTIONS': {},
'DOC_STORE_CONFIG': DOC_STORE_CONFIG
}
MODULESTORE_BRANCH = 'draft-preferred'
MODULESTORE = {
'default': {
'ENGINE': 'xmodule.modulestore.mixed.MixedModuleStore',
'OPTIONS': {
'mappings': {},
'stores': [
{
'NAME': 'split',
'ENGINE': 'xmodule.modulestore.split_mongo.split_draft.DraftVersioningModuleStore',
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
'OPTIONS': {
'default_class': 'xmodule.hidden_block.HiddenBlock',
'fs_root': DATA_DIR,
'render_template': 'common.djangoapps.edxmako.shortcuts.render_to_string',
}
},
{
'NAME': 'draft',
'ENGINE': 'xmodule.modulestore.mongo.DraftMongoModuleStore',
'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
'OPTIONS': {
'default_class': 'xmodule.hidden_block.HiddenBlock',
'fs_root': DATA_DIR,
'render_template': 'common.djangoapps.edxmako.shortcuts.render_to_string',
}
}
]
}
}
}
# Modulestore-level field override providers. These field override providers don't
# require student context.
MODULESTORE_FIELD_OVERRIDE_PROVIDERS = ()
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
DEFAULT_HASHING_ALGORITHM = 'sha256'
#################### Python sandbox ############################################
CODE_JAIL = {
# from https://github.com/openedx/codejail/blob/master/codejail/django_integration.py#L24, '' should be same as None
'python_bin': '/edx/app/edxapp/venvs/edxapp-sandbox/bin/python',
# User to run as in the sandbox.
'user': 'sandbox',
# Configurable limits.
'limits': {
# How many CPU seconds can jailed code use?
'CPU': 1,
# Limit the memory of the jailed process to something high but not
# infinite (512MiB in bytes)
'VMEM': 536870912,
# Time in seconds that the jailed process has to run.
'REALTIME': 3,
'PROXY': 0,
# Needs to be non-zero so that jailed code can use it as their temp directory.(1MiB in bytes)
'FSIZE': 1048576,
},
# Overrides to default configurable 'limits' (above).
# Keys should be course run ids.
# Values should be dictionaries that look like 'limits'.
"limit_overrides": {},
}
############################ DJANGO_BUILTINS ################################
ROOT_URLCONF = 'cms.urls'
COURSE_IMPORT_EXPORT_BUCKET = ''
COURSE_METADATA_EXPORT_BUCKET = ''
ALTERNATE_WORKER_QUEUES = 'lms'
# .. setting_name: GIT_REPO_EXPORT_DIR
# .. setting_default: '/edx/var/edxapp/export_course_repos'
# .. setting_description: When courses are exported to git, either with the export_git management command or the git
# export view from the studio (when settings.ENABLE_EXPORT_GIT is True), they are stored in this directory, which
# must exist at the time of the export.
GIT_REPO_EXPORT_DIR = '/edx/var/edxapp/export_course_repos'
# .. setting_name: GIT_EXPORT_DEFAULT_IDENT
# .. setting_default: {'name': 'STUDIO_EXPORT_TO_GIT', 'email': 'STUDIO_EXPORT_TO_GIT@example.com'}
# .. setting_description: When courses are exported to git, commits are signed with this name/email git identity.
GIT_EXPORT_DEFAULT_IDENT = {
'name': 'STUDIO_EXPORT_TO_GIT',
'email': 'STUDIO_EXPORT_TO_GIT@example.com'
}
# Email
TECH_SUPPORT_EMAIL = 'technical@example.com'
EMAIL_FILE_PATH = Derived(lambda settings: path(settings.DATA_DIR) / "emails" / "studio")
DEFAULT_FROM_EMAIL = 'registration@example.com'
DEFAULT_FEEDBACK_EMAIL = 'feedback@example.com'
TECH_SUPPORT_EMAIL = 'technical@example.com'
CONTACT_EMAIL = 'info@example.com'
BUGS_EMAIL = 'bugs@example.com'
SERVER_EMAIL = 'devops@example.com'
UNIVERSITY_EMAIL = 'university@example.com'
PRESS_EMAIL = 'press@example.com'
# Static content
STATIC_URL = '/static/studio/'
STATIC_ROOT = os.environ.get('STATIC_ROOT_CMS', ENV_ROOT / 'staticfiles' / 'studio')
STATICFILES_DIRS = [
COMMON_ROOT / "static",
PROJECT_ROOT / "static",
# Temporarily adding the following static path as we are migrating the built-in blocks' Sass to vanilla CSS.
# Once all of the built-in blocks are extracted from edx-platform, we can remove this static path.
# Relevant ticket: https://github.com/openedx/edx-platform/issues/35300
XMODULE_ROOT / "static",
]
COURSE_IMPORT_EXPORT_STORAGE = 'django.core.files.storage.FileSystemStorage'
COURSE_METADATA_EXPORT_STORAGE = 'django.core.files.storage.FileSystemStorage'
STATICI18N_ROOT = PROJECT_ROOT / "static"
##### custom vendor plugin variables #####
############################### PIPELINE #######################################
PIPELINE = {
'PIPELINE_ENABLED': True,
# Don't use compression by default
'CSS_COMPRESSOR': None,
'JS_COMPRESSOR': None,
# Don't wrap JavaScript as there is code that depends upon updating the global namespace
'DISABLE_WRAPPER': True,
# Specify the UglifyJS binary to use
'UGLIFYJS_BINARY': 'node_modules/.bin/uglifyjs',
'COMPILERS': (),
'YUI_BINARY': 'yui-compressor',
}
STATICFILES_STORAGE_KWARGS = {}
# List of finder classes that know how to find static files in various locations.
# Note: the pipeline finder is included to be able to discover optimized files
STATICFILES_FINDERS = [
'openedx.core.djangoapps.theming.finders.ThemeFilesFinder',
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'openedx.core.lib.xblock_pipeline.finder.XBlockPipelineFinder',
'pipeline.finders.PipelineFinder',
]
PIPELINE['STYLESHEETS'] = {
'style-vendor': {
'source_filenames': [
'css/vendor/normalize.css',
'css/vendor/font-awesome.css',
'css/vendor/html5-input-polyfills/number-polyfill.css',
'js/vendor/CodeMirror/codemirror.css',
'css/vendor/ui-lightness/jquery-ui-1.8.22.custom.css',
'css/vendor/jquery.qtip.min.css',
'js/vendor/markitup/skins/simple/style.css',
'js/vendor/markitup/sets/wiki/style.css',
],
'output_filename': 'css/cms-style-vendor.css',
},
'style-vendor-tinymce-content': {
'source_filenames': [
'css/tinymce-studio-content-fonts.css',
'js/vendor/tinymce/js/tinymce/skins/ui/studio-tmce5/content.min.css',
'css/tinymce-studio-content.css'
],
'output_filename': 'css/cms-style-vendor-tinymce-content.css',
},
'style-vendor-tinymce-skin': {
'source_filenames': [
'js/vendor/tinymce/js/tinymce/skins/ui/studio-tmce5/skin.min.css'
],
'output_filename': 'css/cms-style-vendor-tinymce-skin.css',
},
'style-main-v1': {
'source_filenames': [
'css/studio-main-v1.css',
],
'output_filename': 'css/studio-main-v1.css',
},
'style-main-v1-rtl': {
'source_filenames': [
'css/studio-main-v1-rtl.css',
],
'output_filename': 'css/studio-main-v1-rtl.css',
},
'style-xmodule-annotations': {
'source_filenames': [
'css/vendor/ova/annotator.css',
'css/vendor/ova/edx-annotator.css',
'css/vendor/ova/video-js.min.css',
'css/vendor/ova/rangeslider.css',
'css/vendor/ova/share-annotator.css',
'css/vendor/ova/richText-annotator.css',
'css/vendor/ova/tags-annotator.css',
'css/vendor/ova/flagging-annotator.css',
'css/vendor/ova/diacritic-annotator.css',
'css/vendor/ova/grouping-annotator.css',
'css/vendor/ova/ova.css',
'js/vendor/ova/catch/css/main.css'
],
'output_filename': 'css/cms-style-xmodule-annotations.css',
},
'course-unit-mfe-iframe-bundle': {
'source_filenames': [
'css/course-unit-mfe-iframe-bundle.css',
],
'output_filename': 'css/course-unit-mfe-iframe-bundle.css',
},
}
base_vendor_js = [
'js/src/utility.js',
'js/src/logger.js',
'common/js/vendor/jquery.js',
'common/js/vendor/jquery-migrate.js',
'js/vendor/jquery.cookie.js',
'js/vendor/url.min.js',
'common/js/vendor/underscore.js',
'common/js/vendor/underscore.string.js',
'common/js/vendor/backbone.js',
'js/vendor/URI.min.js',
# Make some edX UI Toolkit utilities available in the global "edx" namespace
'edx-ui-toolkit/js/utils/global-loader.js',
'edx-ui-toolkit/js/utils/string-utils.js',
'edx-ui-toolkit/js/utils/html-utils.js',
# Here we were loading Bootstrap and supporting libraries, but it no longer seems to be needed for any Studio UI.
# 'common/js/vendor/bootstrap.bundle.js',
# Finally load RequireJS
'common/js/vendor/require.js'
]
# test_order: Determines the position of this chunk of javascript on
# the jasmine test page
PIPELINE['JAVASCRIPT'] = {
'base_vendor': {
'source_filenames': base_vendor_js,
'output_filename': 'js/cms-base-vendor.js',
},
}
STATICFILES_IGNORE_PATTERNS = (
"*.py",
"*.pyc",
# It would be nice if we could do, for example, "**/*.scss",
# but these strings get passed down to the `fnmatch` module,
# which doesn't support that. :(
# http://docs.python.org/2/library/fnmatch.html
"sass/*.scss",
"sass/*/*.scss",
"sass/*/*/*.scss",
"sass/*/*/*/*.scss",
# Ignore tests
"spec",
"spec_helpers",
# Symlinks used by js-test-tool
"xmodule_js",
"common_static",
)
################################# DJANGO-REQUIRE ###############################
# The name of a build profile to use for your project, relative to REQUIRE_BASE_URL.
# A sensible value would be 'app.build.js'. Leave blank to use the built-in default build profile.
# Set to False to disable running the default profile (e.g. if only using it to build Standalone
# Modules)
REQUIRE_BUILD_PROFILE = "cms/js/build.js"
# The name of the require.js script used by your project, relative to REQUIRE_BASE_URL.
REQUIRE_JS = "js/vendor/requiresjs/require.js"
########################## DJANGO WEBPACK LOADER ##############################
WEBPACK_LOADER = {
'DEFAULT': {
'BUNDLE_DIR_NAME': 'bundles/',
'STATS_FILE': os.path.join(STATIC_ROOT, 'webpack-stats.json'),
},
'WORKERS': {
'BUNDLE_DIR_NAME': 'bundles/',
'STATS_FILE': os.path.join(STATIC_ROOT, 'webpack-worker-stats.json')
}
}
############################ SERVICE_VARIANT ##################################
# SERVICE_VARIANT specifies name of the variant used, which decides what JSON
# configuration files are read during startup.
SERVICE_VARIANT = os.environ.get('SERVICE_VARIANT', 'cms')
# CONFIG_PREFIX specifies the prefix of the JSON configuration files,
# based on the service variant. If no variant is use, don't use a
# prefix.
CONFIG_PREFIX = SERVICE_VARIANT + "." if SERVICE_VARIANT else ""
################################# CELERY ######################################
# Name the exchange and queues for each variant
QUEUE_VARIANT = CONFIG_PREFIX.lower()
CELERY_DEFAULT_EXCHANGE = f'edx.{QUEUE_VARIANT}core'
HIGH_PRIORITY_QUEUE = f'edx.{QUEUE_VARIANT}core.high'
DEFAULT_PRIORITY_QUEUE = f'edx.{QUEUE_VARIANT}core.default'
LOW_PRIORITY_QUEUE = f'edx.{QUEUE_VARIANT}core.low'
CELERY_DEFAULT_QUEUE = DEFAULT_PRIORITY_QUEUE
CELERY_DEFAULT_ROUTING_KEY = DEFAULT_PRIORITY_QUEUE
CELERY_QUEUES = {
HIGH_PRIORITY_QUEUE: {},
DEFAULT_PRIORITY_QUEUE: {},
LOW_PRIORITY_QUEUE: {},
}
# Queues configuration
CLEAR_REQUEST_CACHE_ON_TASK_COMPLETION = True
BROKER_USE_SSL = Derived(lambda settings: settings.CELERY_BROKER_USE_SSL)
CELERY_ALWAYS_EAGER = False
############################## HEARTBEAT ######################################
HEARTBEAT_CELERY_ROUTING_KEY = HIGH_PRIORITY_QUEUE
############################## Video ##########################################
# Additional languages that should be supported for video transcripts, not included in ALL_LANGUAGES
EXTENDED_VIDEO_TRANSCRIPT_LANGUAGES = []
############################# SETTINGS FOR VIDEO UPLOAD PIPELINE #############################
VIDEO_UPLOAD_PIPELINE = {
'VEM_S3_BUCKET': '',
'BUCKET': '',
'ROOT_PATH': '',
'CONCURRENT_UPLOAD_LIMIT': 4,
}
############################ APPS #####################################
# The order of INSTALLED_APPS is important, when adding new apps here
# remember to check that you are not creating new
# RemovedInDjango19Warnings in the test logs.
INSTALLED_APPS = [
# Standard apps
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.humanize',
'django.contrib.redirects',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
# Tweaked version of django.contrib.staticfiles
'openedx.core.djangoapps.staticfiles.apps.EdxPlatformStaticFilesConfig',
'django_celery_results',
'method_override',
# Common Initialization
'openedx.core.djangoapps.common_initialization.apps.CommonInitializationConfig',
# Common views
'openedx.core.djangoapps.common_views',
# API access administration
'openedx.core.djangoapps.api_admin',
# CORS and cross-domain CSRF
'corsheaders',
'openedx.core.djangoapps.cors_csrf',
# Provides the 'django_markup' template library so we can use 'interpolate_html' in django templates
'xss_utils',
# History tables
'simple_history',
# Database-backed configuration
'config_models',
'openedx.core.djangoapps.config_model_utils',
'waffle',
# Monitor the status of services
'openedx.core.djangoapps.service_status',
# Video block configs (This will be moved to Video once it becomes an XBlock)
'openedx.core.djangoapps.video_config',
# edX Video Pipeline integration
'openedx.core.djangoapps.video_pipeline',
# For CMS
'cms.djangoapps.contentstore.apps.ContentstoreConfig',
'common.djangoapps.split_modulestore_django.apps.SplitModulestoreDjangoBackendAppConfig',
'openedx.core.djangoapps.contentserver',
'cms.djangoapps.course_creators',
'common.djangoapps.student.apps.StudentConfig', # misleading name due to sharing with lms
'openedx.core.djangoapps.course_groups', # not used in cms (yet), but tests run
'cms.djangoapps.xblock_config.apps.XBlockConfig',
'cms.djangoapps.export_course_metadata.apps.ExportCourseMetadataConfig',
'cms.djangoapps.modulestore_migrator',
# New (Learning-Core-based) XBlock runtime
'openedx.core.djangoapps.xblock.apps.StudioXBlockAppConfig',
'openedx.core.djangoapps.util.apps.UtilConfig',
# Tracking
'common.djangoapps.track',
'eventtracking.django.apps.EventTrackingConfig',
# For asset pipelining
'common.djangoapps.edxmako.apps.EdxMakoConfig',
'pipeline',
'common.djangoapps.static_replace',
'require',
'webpack_loader',
# Site configuration for theming and behavioral modification
'openedx.core.djangoapps.site_configuration',
# Ability to detect and special-case crawler behavior
'openedx.core.djangoapps.crawlers',
# Discussion
'openedx.core.djangoapps.django_comment_common',
# Notifications
'openedx.core.djangoapps.notifications',
# for course creator table
'django.contrib.admin',
# for managing course modes
'common.djangoapps.course_modes.apps.CourseModesConfig',
# Verified Track Content Cohorting (Beta feature that will hopefully be removed)
'openedx.core.djangoapps.verified_track_content',
# Dark-launching languages
'openedx.core.djangoapps.dark_lang',
#
# User preferences
'wiki',
'django_notify',
'lms.djangoapps.course_wiki', # Our customizations
'mptt',
'sekizai',
'openedx.core.djangoapps.user_api',
# Country embargo support
'openedx.core.djangoapps.embargo',
# Course action state
'common.djangoapps.course_action_state',
'openedx.core.djangoapps.content.course_overviews.apps.CourseOverviewsConfig',
'openedx.core.djangoapps.content.block_structure.apps.BlockStructureConfig',
# edx-milestones service
'milestones',
# Credit courses
'openedx.core.djangoapps.credit.apps.CreditConfig',
'common.djangoapps.xblock_django',
# Catalog integration
'openedx.core.djangoapps.catalog',
# Programs support
'openedx.core.djangoapps.programs.apps.ProgramsConfig',
# django-oauth-toolkit
'oauth2_provider',
# These are apps that aren't strictly needed by Studio, but are imported by
# other apps that are. Django 1.8 wants to have imported models supported
# by installed apps.
'openedx.core.djangoapps.oauth_dispatch.apps.OAuthDispatchAppConfig',
'lms.djangoapps.courseware',
'lms.djangoapps.coursewarehistoryextended',
'lms.djangoapps.survey.apps.SurveyConfig',
'lms.djangoapps.verify_student.apps.VerifyStudentConfig',
'completion',
# System Wide Roles
'openedx.core.djangoapps.system_wide_roles',
# Static i18n support
'statici18n',
# Tagging
'cms.lib.xblock.tagging',
# Enables default site and redirects
'django_sites_extensions',
# additional release utilities to ease automation
'release_util',
# rule-based authorization
'rules.apps.AutodiscoverRulesConfig',
'bridgekeeper',
# management of user-triggered async tasks (course import/export, etc.)
'user_tasks',
# CMS specific user task handling
'cms.djangoapps.cms_user_tasks.apps.CmsUserTasksConfig',
# Unusual migrations
'common.djangoapps.database_fixups',
# Customized celery tasks, including persisting failed tasks so they can
# be retried
'celery_utils',
# Waffle related utilities
'openedx.core.djangoapps.waffle_utils',
# DRF filters
'django_filters',
'cms.djangoapps.api',
# edx-drf-extensions
'csrf.apps.CsrfAppConfig', # Enables frontend apps to retrieve CSRF tokens.
# Entitlements, used in openedx tests
'common.djangoapps.entitlements',
# Asset management for mako templates
'common.djangoapps.pipeline_mako',
# API Documentation
'drf_yasg',
# Tagging
'openedx_tagging.core.tagging.apps.TaggingConfig',
'openedx.core.djangoapps.content_tagging',
# Search
'openedx.core.djangoapps.content.search',
# For Programs API
'lms.djangoapps.program_enrollments',
'openedx.features.course_duration_limits',
'openedx.features.content_type_gating',
'openedx.features.discounts',
'openedx.features.effort_estimation',
'lms.djangoapps.experiments',
'openedx.core.djangoapps.external_user_ids',
# so sample_task is available to celery workers
'openedx.core.djangoapps.heartbeat',
# signal handlers to capture course dates into edx-when
'openedx.core.djangoapps.course_date_signals',
# Management of per-user schedules
'openedx.core.djangoapps.schedules',
'rest_framework_jwt',
# Learning Sequence Navigation
'openedx.core.djangoapps.content.learning_sequences.apps.LearningSequencesConfig',
# Database-backed Organizations App (http://github.com/openedx/edx-organizations)
'organizations',
# User and group management via edx-django-utils
'edx_django_utils.user',
# Allow Studio to use LMS for SSO
'social_django',
# Content Library LTI 1.3 Support.
'pylti1p3.contrib.django.lti1p3_tool_config',
# For edx ace template tags
'edx_ace',
# alternative swagger generator for CMS API
'drf_spectacular',
'openedx_events',
# Learning Core Apps, used by v2 content libraries (content_libraries app)
"openedx_learning.apps.authoring.collections",
"openedx_learning.apps.authoring.components",
"openedx_learning.apps.authoring.contents",
"openedx_learning.apps.authoring.publishing",
"openedx_learning.apps.authoring.units",
"openedx_learning.apps.authoring.subsections",
"openedx_learning.apps.authoring.sections",
]
################# EDX MARKETING SITE ##################################
MKTG_URL_LINK_MAP = {}
ID_VERIFICATION_SUPPORT_LINK = ''
PASSWORD_RESET_SUPPORT_LINK = ''
ACTIVATION_EMAIL_SUPPORT_LINK = ''
LOGIN_ISSUE_SUPPORT_LINK = ''
############################## EVENT TRACKING #################################
TRACK_MAX_EVENT = 50000
TRACKING_BACKENDS = {
'logger': {
'ENGINE': 'common.djangoapps.track.backends.logger.LoggerBackend',
'OPTIONS': {
'name': 'tracking'
}
}
}
# We're already logging events, and we don't want to capture user
# names/passwords. Heartbeat events are likely not interesting.
TRACKING_IGNORE_URL_PATTERNS = [r'^/event', r'^/login', r'^/heartbeat']
EVENT_TRACKING_ENABLED = True
EVENT_TRACKING_BACKENDS = {
'tracking_logs': {
'ENGINE': 'eventtracking.backends.routing.RoutingBackend',
'OPTIONS': {
'backends': {
'logger': {
'ENGINE': 'eventtracking.backends.logger.LoggerBackend',
'OPTIONS': {
'name': 'tracking',
'max_event_size': TRACK_MAX_EVENT,
}
}
},
'processors': [
{'ENGINE': 'common.djangoapps.track.shim.LegacyFieldMappingProcessor'},
{'ENGINE': 'common.djangoapps.track.shim.PrefixedEventProcessor'}
]
}
},
'segmentio': {
'ENGINE': 'eventtracking.backends.routing.RoutingBackend',
'OPTIONS': {
'backends': {
'segment': {'ENGINE': 'eventtracking.backends.segment.SegmentBackend'}
},
'processors': [
{
'ENGINE': 'eventtracking.processors.whitelist.NameWhitelistProcessor',
'OPTIONS': {
'whitelist': []
}
},
{
'ENGINE': 'common.djangoapps.track.shim.GoogleAnalyticsProcessor'
}
]
}
}
}
EVENT_TRACKING_PROCESSORS = []
EVENT_TRACKING_SEGMENTIO_EMIT_WHITELIST = []
##### ACCOUNT LOCKOUT DEFAULT PARAMETERS #####
MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED = 6
MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS = 30 * 60
### Apps only installed in some instances
# The order of INSTALLED_APPS matters, so this tuple is the app name and the item in INSTALLED_APPS
# that this app should be inserted *before*. A None here means it should be appended to the list.
OPTIONAL_APPS = (
('problem_builder', 'openedx.core.djangoapps.content.course_overviews.apps.CourseOverviewsConfig'),
('edx_sga', None),
# edx-ora2
('submissions', 'openedx.core.djangoapps.content.course_overviews.apps.CourseOverviewsConfig'),
('openassessment', 'openedx.core.djangoapps.content.course_overviews.apps.CourseOverviewsConfig'),
('openassessment.assessment', 'openedx.core.djangoapps.content.course_overviews.apps.CourseOverviewsConfig'),
('openassessment.fileupload', 'openedx.core.djangoapps.content.course_overviews.apps.CourseOverviewsConfig'),
('openassessment.staffgrader', 'openedx.core.djangoapps.content.course_overviews.apps.CourseOverviewsConfig'),
('openassessment.workflow', 'openedx.core.djangoapps.content.course_overviews.apps.CourseOverviewsConfig'),
('openassessment.xblock', 'openedx.core.djangoapps.content.course_overviews.apps.CourseOverviewsConfig'),
# edxval
('edxval', 'openedx.core.djangoapps.content.course_overviews.apps.CourseOverviewsConfig'),
# Enterprise App (http://github.com/openedx/edx-enterprise)
('enterprise', None),
('consent', None),
('integrated_channels.integrated_channel', None),
('integrated_channels.degreed', None),
('integrated_channels.degreed2', None),
('integrated_channels.sap_success_factors', None),
('integrated_channels.xapi', None),
('integrated_channels.cornerstone', None),
('integrated_channels.blackboard', None),
('integrated_channels.canvas', None),
('integrated_channels.moodle', None),
)
for app_name, insert_before in OPTIONAL_APPS:
# First attempt to only find the module rather than actually importing it,
# to avoid circular references - only try to import if it can't be found
# by find_spec, which doesn't work with import hooks
if importlib.util.find_spec(app_name) is None:
try:
__import__(app_name)
except ImportError:
continue
try:
INSTALLED_APPS.insert(INSTALLED_APPS.index(insert_before), app_name)
except (IndexError, ValueError):
INSTALLED_APPS.append(app_name)
### Size of chunks into which asset uploads will be divided
UPLOAD_CHUNK_SIZE_IN_MB = 10
### Max size of asset uploads to GridFS
MAX_ASSET_UPLOAD_FILE_SIZE_IN_MB = 20
# FAQ url to direct users to if they upload
# a file that exceeds the above size
MAX_ASSET_UPLOAD_FILE_SIZE_URL = ""
### Default language for a new course
DEFAULT_COURSE_LANGUAGE = "en"
# Specify XBlocks that should be treated as advanced problems. Each entry is a
# dict:
# 'component': the entry-point name of the XBlock.
# 'boilerplate_name': an optional YAML template to be used. Specify as
# None to omit.
#
ADVANCED_PROBLEM_TYPES = [
{
'component': 'drag-and-drop-v2',
'boilerplate_name': None
},
{
'component': 'staffgradedxblock',
'boilerplate_name': None
}
]
LIBRARY_BLOCK_TYPES = [
{
'component': 'library_content',
'boilerplate_name': None
}
]
############### Settings for Retirement #####################
# See annotations in lms/envs/common.py for details.
RETIRED_USERNAME_FMT = Derived(lambda settings: settings.RETIRED_USERNAME_PREFIX + '{}')
# See annotations in lms/envs/common.py for details.
RETIRED_EMAIL_FMT = Derived(lambda settings: settings.RETIRED_EMAIL_PREFIX + '{}@' + settings.RETIRED_EMAIL_DOMAIN)
# See annotations in lms/envs/common.py for details.
RETIRED_USER_SALTS = ['abc', '123']
# See annotations in lms/envs/common.py for details.
RETIREMENT_SERVICE_WORKER_USERNAME = 'RETIREMENT_SERVICE_USER'
# Files and Uploads type filter values
FILES_AND_UPLOAD_TYPE_FILTERS = {
"Images": ['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/tiff', 'image/tif', 'image/x-icon',
'image/svg+xml', 'image/bmp', 'image/x-ms-bmp', ],
"Documents": [
'application/pdf',
'text/plain',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'application/vnd.openxmlformats-officedocument.presentationml.template',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
'application/msword',
'application/vnd.ms-excel',
'application/vnd.ms-powerpoint',
'application/csv',
'application/vnd.ms-excel.sheet.macroEnabled.12',
'text/x-tex',
'application/x-pdf',
'application/vnd.ms-excel.sheet.macroenabled.12',
'file/pdf',
'image/pdf',
'text/csv',
'text/pdf',
'text/x-sh',
'\"application/pdf\"',
],
"Audio": ['audio/mpeg', 'audio/mp3', 'audio/x-wav', 'audio/ogg', 'audio/wav', 'audio/aac', 'audio/x-m4a',
'audio/mp4', 'audio/x-ms-wma', ],
"Code": ['application/json', 'text/html', 'text/javascript', 'application/javascript', 'text/css', 'text/x-python',
'application/x-java-jnlp-file', 'application/xml', 'application/postscript', 'application/x-javascript',
'application/java-vm', 'text/x-c++src', 'text/xml', 'text/x-scss', 'application/x-python-code',
'application/java-archive', 'text/x-python-script', 'application/x-ruby', 'application/mathematica',
'text/coffeescript', 'text/x-matlab', 'application/sql', 'text/php', ]
}
ELASTIC_FIELD_MAPPINGS = {
"start_date": {
"type": "date"
}
}
XBLOCK_FS_STORAGE_BUCKET = None
XBLOCK_FS_STORAGE_PREFIX = None
############################ Global Database Configuration #####################
DATABASE_ROUTERS = [
'openedx.core.lib.django_courseware_routers.StudentModuleHistoryExtendedRouter',
]
############################ OAUTH2 Provider ###################################
# 5 minute expiration time for JWT id tokens issued for external API requests.
OAUTH_ID_TOKEN_EXPIRATION = 5 * 60
EDX_DRF_EXTENSIONS = {
# Set this value to an empty dict in order to prevent automatically updating
# user data from values in (possibly stale) JWTs.
'JWT_PAYLOAD_USER_ATTRIBUTE_MAPPING': {},
}
############## Settings for Studio Context Sensitive Help ##############
HELP_TOKENS_INI_FILE = REPO_ROOT / "cms" / "envs" / "help_tokens.ini"
############## DJANGO-USER-TASKS ##############
# How long until database records about the outcome of a task and its artifacts get deleted?
USER_TASKS_MAX_AGE = timedelta(days=7)
############################# Persistent Grades ####################################
# Queue to use for updating persistent grades
RECALCULATE_GRADES_ROUTING_KEY = DEFAULT_PRIORITY_QUEUE
# .. setting_name: DEFAULT_GRADE_DESIGNATIONS
# .. setting_default: ['A', 'B', 'C', 'D']
# .. setting_description: The default 'pass' grade cutoff designations to be used. The failure grade
# is always 'F' and should not be included in this list.
# .. setting_warning: The DEFAULT_GRADE_DESIGNATIONS list must have more than one designation,
# or else ['A', 'B', 'C', 'D'] will be used as the default grade designations. Also, only the first
# 11 grade designations are used by the UI, so it's advisable to restrict the list to 11 items.
DEFAULT_GRADE_DESIGNATIONS = ['A', 'B', 'C', 'D']
########## Settings for video transcript migration tasks ############
VIDEO_TRANSCRIPT_MIGRATIONS_JOB_QUEUE = Derived(lambda settings: settings.DEFAULT_PRIORITY_QUEUE)
########## Settings youtube thumbnails scraper tasks ############
SCRAPE_YOUTUBE_THUMBNAILS_JOB_QUEUE = Derived(lambda settings: settings.DEFAULT_PRIORITY_QUEUE)
########## Settings update search index task ############
UPDATE_SEARCH_INDEX_JOB_QUEUE = Derived(lambda settings: settings.DEFAULT_PRIORITY_QUEUE)
###################### VIDEO IMAGE STORAGE ######################
VIDEO_IMAGE_DEFAULT_FILENAME = 'images/video-images/default_video_image.png'
VIDEO_IMAGE_SUPPORTED_FILE_FORMATS = {
'.bmp': 'image/bmp',
'.bmp2': 'image/x-ms-bmp', # PIL gives x-ms-bmp format
'.gif': 'image/gif',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.png': 'image/png'
}
VIDEO_IMAGE_MAX_FILE_SIZE_MB = '2 MB'
VIDEO_IMAGE_MIN_FILE_SIZE_KB = '2 KB'
VIDEO_IMAGE_MAX_WIDTH = 1280
VIDEO_IMAGE_MAX_HEIGHT = 720
VIDEO_IMAGE_MIN_WIDTH = 640
VIDEO_IMAGE_MIN_HEIGHT = 360
VIDEO_IMAGE_ASPECT_RATIO = 16 / 9.0
VIDEO_IMAGE_ASPECT_RATIO_TEXT = '16:9'
VIDEO_IMAGE_ASPECT_RATIO_ERROR_MARGIN = 0.1
###################### ZENDESK ######################
ZENDESK_USER = ''
ZENDESK_API_KEY = ''
############## Installed Django Apps #########################
from edx_django_utils.plugins import get_plugin_apps, add_plugins
from openedx.core.djangoapps.plugins.constants import ProjectType, SettingsType
INSTALLED_APPS.extend(get_plugin_apps(ProjectType.CMS))
add_plugins(__name__, ProjectType.CMS, SettingsType.COMMON)
# Course exports streamed in blocks of this size. 8192 or 8kb is the default
# setting for the FileWrapper class used to iterate over the export file data.
# See: https://docs.python.org/2/library/wsgiref.html#wsgiref.util.FileWrapper
COURSE_EXPORT_DOWNLOAD_CHUNK_SIZE = 8192
COMMENTS_SERVICE_URL = 'http://localhost:18080'
COMMENTS_SERVICE_KEY = 'password'
EXAMS_SERVICE_URL = 'http://localhost:18740/api/v1'
EXAMS_SERVICE_USERNAME = 'edx_exams_worker'
############# CORS headers for cross-domain requests #################
# Set CORS_ALLOW_HEADERS regardless of whether we've enabled ENABLE_CORS_HEADERS
# because that decision might happen in a later config file. (The headers to
# allow is an application logic, and not site policy.)
CORS_ALLOW_HEADERS = corsheaders_default_headers + (
'use-jwt-cookie',
'content-range',
'content-disposition',
)
########################## VIDEO IMAGE STORAGE ############################
VIDEO_IMAGE_SETTINGS = dict(
VIDEO_IMAGE_MAX_BYTES=2 * 1024 * 1024, # 2 MB
VIDEO_IMAGE_MIN_BYTES=2 * 1024, # 2 KB
# Backend storage
# STORAGE_CLASS='storages.backends.s3boto3.S3Boto3Storage',
# STORAGE_KWARGS=dict(bucket='video-image-bucket'),
STORAGE_KWARGS=dict(
location=MEDIA_ROOT,
),
DIRECTORY_PREFIX='video-images/',
BASE_URL=MEDIA_URL,
)
VIDEO_IMAGE_MAX_AGE = 31536000
########################## VIDEO TRANSCRIPTS STORAGE ############################
TRANSCRIPT_LANG_CACHE_TIMEOUT = 60 * 60 * 24
##### shoppingcart Payment #####
PAYMENT_SUPPORT_EMAIL = 'billing@example.com'
################################ Bulk Email ###################################
# Parameters for breaking down course enrollment into subtasks.
BULK_EMAIL_EMAILS_PER_TASK = 500
# Suffix used to construct 'from' email address for bulk emails.
# A course-specific identifier is prepended.
BULK_EMAIL_DEFAULT_FROM_EMAIL = 'no-reply@example.com'
# Flag to indicate if individual email addresses should be logged as they are sent
# a bulk email message.
BULK_EMAIL_LOG_SENT_EMAILS = False
###################### Grade Downloads ######################
# These keys are used for all of our asynchronous downloadable files, including
# the ones that contain information other than grades.
GRADES_DOWNLOAD = {
'STORAGE_CLASS': 'django.core.files.storage.FileSystemStorage',
'STORAGE_KWARGS': {
'location': '/tmp/edx-s3/grades',
},
'STORAGE_TYPE': None,
'BUCKET': None,
'ROOT_PATH': None,
}
############### Settings swift #####################################
SWIFT_USE_TEMP_URLS = False
############### Settings for facebook ##############################
FACEBOOK_APP_ID = 'FACEBOOK_APP_ID'
FACEBOOK_APP_SECRET = 'FACEBOOK_APP_SECRET'
FACEBOOK_API_VERSION = 'v2.1'
###################### PROCTORING SETTINGS ##########################
PROCTORING_SETTINGS = {}
###################### LEARNER PORTAL ################################
LEARNER_PORTAL_URL_ROOT = 'https://learner-portal-localhost:18000'
############################ JWT #################################
REGISTRATION_EXTRA_FIELDS = {
'confirm_email': 'hidden',
'level_of_education': 'optional',
'gender': 'optional',
'year_of_birth': 'optional',
'mailing_address': 'optional',
'goals': 'optional',
'honor_code': 'required',
'terms_of_service': 'hidden',
'city': 'hidden',
'country': 'hidden',
'marketing_emails_opt_in': 'hidden',
}
EDXAPP_PARSE_KEYS = {}
PARSE_KEYS = {}
###################### DEPRECATED URLS ##########################
# .. toggle_name: DISABLE_DEPRECATED_SIGNIN_URL
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: Toggle for removing the deprecated /signin url.
# .. toggle_use_cases: temporary
# .. toggle_creation_date: 2019-12-02
# .. toggle_target_removal_date: 2020-06-01
# .. toggle_warning: This url can be removed once it no longer has any real traffic.
# .. toggle_tickets: ARCH-1253
DISABLE_DEPRECATED_SIGNIN_URL = False
# .. toggle_name: DISABLE_DEPRECATED_SIGNUP_URL
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: Toggle for removing the deprecated /signup url.
# .. toggle_use_cases: temporary
# .. toggle_creation_date: 2019-12-02
# .. toggle_target_removal_date: 2020-06-01
# .. toggle_warning: This url can be removed once it no longer has any real traffic.
# .. toggle_tickets: ARCH-1253
DISABLE_DEPRECATED_SIGNUP_URL = False
##### REGISTRATION RATE LIMIT SETTINGS #####
OPTIONAL_FIELD_API_RATELIMIT = '10/h'
######################## Setting for content libraries ########################
MAX_BLOCKS_PER_CONTENT_LIBRARY = 100_000
######################## Organizations ########################
# .. toggle_name: ORGANIZATIONS_AUTOCREATE
# .. toggle_implementation: DjangoSetting
# .. toggle_default: True
# .. toggle_description: When enabled, creating a course run or content library with
# an "org slug" that does not map to an Organization in the database will trigger the
# creation of a new Organization, with its name and short_name set to said org slug.
# When disabled, creation of such content with an unknown org slug will instead
# result in a validation error.
# If you want the Organization table to be an authoritative information source in
# Studio, then disable this; however, if you want the table to just be a reflection of
# the orgs referenced in Studio content, then leave it enabled.
# .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2020-11-02
# .. toggle_tickets: https://github.com/openedx/edx-organizations/blob/master/docs/decisions/0001-phase-in-db-backed-organizations-to-all.rst
ORGANIZATIONS_AUTOCREATE = True
################# Documentation links for course apps #################
COURSE_LIVE_HELP_URL = "https://docs.openedx.org/en/latest/educators/how-tos/course_development/add_course_live.html"
######################## Registration ########################
# Social-core setting that allows inactive users to be able to
# log in. The only case it's used is when user registering a new account through the LMS.
INACTIVE_USER_LOGIN = True
# Redirect URL for inactive user. If not set, user will be redirected to /login after the login itself (loop)
INACTIVE_USER_URL = f'http://{CMS_BASE}'
######################## Discussion Forum settings ########################
# Feedback link in upgraded discussion notification alert
DISCUSSIONS_INCONTEXT_FEEDBACK_URL = ''
# Learn More link in upgraded discussion notification alert
# pylint: disable=line-too-long
DISCUSSIONS_INCONTEXT_LEARNMORE_URL = "https://docs.openedx.org/en/latest/educators/concepts/communication/about_course_discussions.html"
# pylint: enable=line-too-long
#### Event bus producing ####
def _should_send_xblock_events(settings):
return settings.ENABLE_SEND_XBLOCK_LIFECYCLE_EVENTS_OVER_BUS
# .. setting_name: EVENT_BUS_PRODUCER_CONFIG
# .. setting_default: all events disabled
# .. setting_description: Dictionary of event_types mapped to dictionaries of topic to topic-related configuration.
# Each topic configuration dictionary contains
# * `enabled`: a toggle denoting whether the event will be published to the topic. These should be annotated
# according to
# https://docs.openedx.org/projects/edx-toggles/en/latest/how_to/documenting_new_feature_toggles.html
# * `event_key_field` which is a period-delimited string path to event data field to use as event key.
# Note: The topic names should not include environment prefix as it will be dynamically added based on
# EVENT_BUS_TOPIC_PREFIX setting.
EVENT_BUS_PRODUCER_CONFIG = {
'org.openedx.content_authoring.course.catalog_info.changed.v1': {
'course-catalog-info-changed':
{'event_key_field': 'catalog_info.course_key',
# .. toggle_name: EVENT_BUS_PRODUCER_CONFIG['org.openedx.content_authoring.course.catalog_info.changed.v1']
# ['course-catalog-info-changed']['enabled']
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: if enabled, will publish COURSE_CATALOG_INFO_CHANGED events to the event bus on
# the course-catalog-info-changed topics
# .. toggle_warning: The default may be changed in a later release. See
# https://github.com/openedx/openedx-events/issues/265
# .. toggle_use_cases: opt_in
# .. toggle_creation_date: 2023-10-10
'enabled': False},
},
'org.openedx.content_authoring.xblock.published.v1': {
'course-authoring-xblock-lifecycle':
{'event_key_field': 'xblock_info.usage_key', 'enabled': Derived(_should_send_xblock_events)},
},
'org.openedx.content_authoring.xblock.deleted.v1': {
'course-authoring-xblock-lifecycle':
{'event_key_field': 'xblock_info.usage_key', 'enabled': Derived(_should_send_xblock_events)},
},
'org.openedx.content_authoring.xblock.duplicated.v1': {
'course-authoring-xblock-lifecycle':
{'event_key_field': 'xblock_info.usage_key', 'enabled': Derived(_should_send_xblock_events)},
},
# LMS events. These have to be copied over here because lms.common adds some derived entries as well,
# and the derivation fails if the keys are missing. If we ever remove the import of lms.common, we can remove these.
'org.openedx.learning.certificate.created.v1': {
'learning-certificate-lifecycle':
{'event_key_field': 'certificate.course.course_key', 'enabled': False},
},
'org.openedx.learning.certificate.revoked.v1': {
'learning-certificate-lifecycle':
{'event_key_field': 'certificate.course.course_key', 'enabled': False},
},
"org.openedx.learning.course.passing.status.updated.v1": {
"learning-badges-lifecycle": {
"event_key_field": "course_passing_status.course.course_key",
"enabled": Derived(should_send_learning_badge_events),
},
},
"org.openedx.learning.ccx.course.passing.status.updated.v1": {
"learning-badges-lifecycle": {
"event_key_field": "course_passing_status.course.ccx_course_key",
"enabled": Derived(should_send_learning_badge_events),
},
},
}
################### Authoring API ######################
# This affects the Authoring API swagger docs but not the legacy swagger docs under /api-docs/.
REST_FRAMEWORK['DEFAULT_SCHEMA_CLASS'] = 'drf_spectacular.openapi.AutoSchema'
################### Studio Search (beta), using Meilisearch ###################
# Enable Studio search features (powered by Meilisearch) (beta, off by default)
MEILISEARCH_ENABLED = False
# Meilisearch URL that the python backend can use. Often points to another docker container or k8s service.
MEILISEARCH_URL = "http://meilisearch"
# URL that browsers (end users) can use to reach Meilisearch. Should be HTTPS in production.
MEILISEARCH_PUBLIC_URL = "http://meilisearch.example.com"
# To support multi-tenancy, you can prefix all indexes with a common key like "sandbox7-"
# and use a restricted tenant token in place of an API key, so that this Open edX instance
# can only use the index(es) that start with this prefix.
# See https://www.meilisearch.com/docs/learn/security/tenant_tokens
MEILISEARCH_INDEX_PREFIX = ""
MEILISEARCH_API_KEY = "devkey"
# .. setting_name: LIBRARY_ENABLED_BLOCKS
# .. setting_default: ['problem', 'video', 'html', 'drag-and-drop-v2']
# .. setting_description: List of block types that are ready/enabled to be created/used
# .. in libraries. Both basic blocks and advanced blocks can be included.
# .. In the future, we will support individual configuration per library - see
# .. openedx/core/djangoapps/content_libraries/api.py::get_allowed_block_types()
LIBRARY_ENABLED_BLOCKS = [
'problem',
'video',
'html',
'drag-and-drop-v2',
'openassessment',
'conditional',
'done',
'edx_sga',
'freetextresponse',
'google-calendar',
'google-document',
'invideoquiz',
'lti',
'lti_consumer',
'pdf',
'poll',
'survey',
'word_cloud',
]
# .. setting_name: DEFAULT_ORG_LOGO_URL
# .. setting_default: Derived(lambda settings: settings.STATIC_URL + 'images/logo.png')
# .. setting_description: The default logo url for organizations that do not have a logo set.
# .. setting_warning: This url is used as a placeholder for organizations that do not have a logo set.
DEFAULT_ORG_LOGO_URL = Derived(lambda settings: settings.STATIC_URL + 'images/logo.png')
# Misc
AUTHORING_API_URL = ''