Skip to content

create openedx envs common settings #36941

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ omit =
common/djangoapps/*/migrations/*
openedx/core/djangoapps/*/migrations/*
openedx/core/djangoapps/debug/*
openedx/envs/*
openedx/features/*/migrations/*

concurrency=multiprocessing
Expand Down
1 change: 1 addition & 0 deletions .coveragerc-local
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ omit =
common/djangoapps/*/migrations/*
openedx/core/djangoapps/*/migrations/*
openedx/core/djangoapps/debug/*
openedx/envs/*
openedx/features/*/migrations/*

concurrency=multiprocessing
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pylint-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- module-name: openedx-1
path: "openedx/core/types/ openedx/core/djangoapps/ace_common/ openedx/core/djangoapps/agreements/ openedx/core/djangoapps/api_admin/ openedx/core/djangoapps/auth_exchange/ openedx/core/djangoapps/bookmarks/ openedx/core/djangoapps/cache_toolbox/ openedx/core/djangoapps/catalog/ openedx/core/djangoapps/ccxcon/ openedx/core/djangoapps/commerce/ openedx/core/djangoapps/common_initialization/ openedx/core/djangoapps/common_views/ openedx/core/djangoapps/config_model_utils/ openedx/core/djangoapps/content/ openedx/core/djangoapps/content_libraries/ openedx/core/djangoapps/content_staging/ openedx/core/djangoapps/contentserver/ openedx/core/djangoapps/cookie_metadata/ openedx/core/djangoapps/cors_csrf/ openedx/core/djangoapps/course_apps/ openedx/core/djangoapps/course_date_signals/ openedx/core/djangoapps/course_groups/ openedx/core/djangoapps/courseware_api/ openedx/core/djangoapps/crawlers/ openedx/core/djangoapps/credentials/ openedx/core/djangoapps/credit/ openedx/core/djangoapps/dark_lang/ openedx/core/djangoapps/debug/ openedx/core/djangoapps/discussions/ openedx/core/djangoapps/django_comment_common/ openedx/core/djangoapps/embargo/ openedx/core/djangoapps/enrollments/ openedx/core/djangoapps/external_user_ids/ openedx/core/djangoapps/zendesk_proxy/ openedx/core/djangolib/ openedx/core/lib/ openedx/core/djangoapps/course_live/"
- module-name: openedx-2
path: "openedx/core/djangoapps/geoinfo/ openedx/core/djangoapps/header_control/ openedx/core/djangoapps/heartbeat/ openedx/core/djangoapps/lang_pref/ openedx/core/djangoapps/models/ openedx/core/djangoapps/monkey_patch/ openedx/core/djangoapps/oauth_dispatch/ openedx/core/djangoapps/olx_rest_api/ openedx/core/djangoapps/password_policy/ openedx/core/djangoapps/plugin_api/ openedx/core/djangoapps/plugins/ openedx/core/djangoapps/profile_images/ openedx/core/djangoapps/programs/ openedx/core/djangoapps/safe_sessions/ openedx/core/djangoapps/schedules/ openedx/core/djangoapps/service_status/ openedx/core/djangoapps/session_inactivity_timeout/ openedx/core/djangoapps/signals/ openedx/core/djangoapps/site_configuration/ openedx/core/djangoapps/system_wide_roles/ openedx/core/djangoapps/theming/ openedx/core/djangoapps/user_api/ openedx/core/djangoapps/user_authn/ openedx/core/djangoapps/util/ openedx/core/djangoapps/verified_track_content/ openedx/core/djangoapps/video_config/ openedx/core/djangoapps/video_pipeline/ openedx/core/djangoapps/waffle_utils/ openedx/core/djangoapps/xblock/ openedx/core/djangoapps/xmodule_django/ openedx/core/tests/ openedx/features/ openedx/testing/ openedx/tests/ openedx/core/djangoapps/notifications/ openedx/core/djangoapps/staticfiles/ openedx/core/djangoapps/content_tagging/"
path: "openedx/core/djangoapps/geoinfo/ openedx/core/djangoapps/header_control/ openedx/core/djangoapps/heartbeat/ openedx/core/djangoapps/lang_pref/ openedx/core/djangoapps/models/ openedx/core/djangoapps/monkey_patch/ openedx/core/djangoapps/oauth_dispatch/ openedx/core/djangoapps/olx_rest_api/ openedx/core/djangoapps/password_policy/ openedx/core/djangoapps/plugin_api/ openedx/core/djangoapps/plugins/ openedx/core/djangoapps/profile_images/ openedx/core/djangoapps/programs/ openedx/core/djangoapps/safe_sessions/ openedx/core/djangoapps/schedules/ openedx/core/djangoapps/service_status/ openedx/core/djangoapps/session_inactivity_timeout/ openedx/core/djangoapps/signals/ openedx/core/djangoapps/site_configuration/ openedx/core/djangoapps/system_wide_roles/ openedx/core/djangoapps/theming/ openedx/core/djangoapps/user_api/ openedx/core/djangoapps/user_authn/ openedx/core/djangoapps/util/ openedx/core/djangoapps/verified_track_content/ openedx/core/djangoapps/video_config/ openedx/core/djangoapps/video_pipeline/ openedx/core/djangoapps/waffle_utils/ openedx/core/djangoapps/xblock/ openedx/core/djangoapps/xmodule_django/ openedx/core/tests/ openedx/features/ openedx/testing/ openedx/tests/ openedx/envs/ openedx/core/djangoapps/notifications/ openedx/core/djangoapps/staticfiles/ openedx/core/djangoapps/content_tagging/"
- module-name: common
path: "common"
- module-name: cms
Expand Down
105 changes: 14 additions & 91 deletions cms/envs/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,83 +45,14 @@

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
# Although this module itself may not use these imported variables, other dependent modules may.
# Warning: Do NOT add any new variables to this list. This is incompatible with future plans to
# have more logical separation between LMS and Studio (CMS). It is also incompatible with the
# direction documented in OEP-45: Configuring and Operating Open edX:
# https://open-edx-proposals.readthedocs.io/en/latest/oep-0045-arch-ops-and-config.html
from lms.envs.common import (
USE_TZ, ALL_LANGUAGES, ASSET_IGNORE_REGEX,
PARENTAL_CONSENT_AGE_LIMIT, REGISTRATION_EMAIL_PATTERNS_ALLOWED,
# The following PROFILE_IMAGE_* settings are included as they are
# indirectly accessed through the email opt-in API, which is
# technically accessible through the CMS via legacy URLs.
PROFILE_IMAGE_BACKEND, PROFILE_IMAGE_DEFAULT_FILENAME, PROFILE_IMAGE_DEFAULT_FILE_EXTENSION,
PROFILE_IMAGE_HASH_SEED, PROFILE_IMAGE_MIN_BYTES, PROFILE_IMAGE_MAX_BYTES, PROFILE_IMAGE_SIZES_MAP,
# The following setting is included as it is used to check whether to
# display credit eligibility table on the CMS or not.
COURSE_MODE_DEFAULTS, DEFAULT_COURSE_ABOUT_IMAGE_URL,

# User-uploaded content
MEDIA_ROOT,
MEDIA_URL,

# Lazy Gettext
_,

# Django REST framework configuration
REST_FRAMEWORK,

STATICI18N_OUTPUT_DIR,

# Heartbeat
HEARTBEAT_CHECKS,
HEARTBEAT_EXTENDED_CHECKS,
HEARTBEAT_CELERY_TIMEOUT,
HEARTBEAT_CELERY_ROUTING_KEY,

# Default site to use if no site exists matching request headers
SITE_ID,

# constants for redirects app
REDIRECT_CACHE_TIMEOUT,
REDIRECT_CACHE_KEY_PREFIX,

# This is required for the migrations in oauth_dispatch.models
# otherwise it fails saying this attribute is not present in Settings
# Although Studio does not enable OAuth2 Provider capability, the new approach
# to generating test databases will discover and try to create all tables
# and this setting needs to be present
OAUTH2_PROVIDER_APPLICATION_MODEL,
JWT_AUTH,

USERNAME_REGEX_PARTIAL,
USERNAME_PATTERN,

# django-debug-toolbar
DEBUG_TOOLBAR_PATCH_SETTINGS,

COURSE_ENROLLMENT_MODES,
CONTENT_TYPE_GATE_GROUP_IDS,

DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH,

GENERATE_PROFILE_SCORES,

# Enterprise service settings
ENTERPRISE_CATALOG_INTERNAL_ROOT_URL,
ENTERPRISE_BACKEND_SERVICE_EDX_OAUTH2_KEY,
ENTERPRISE_BACKEND_SERVICE_EDX_OAUTH2_SECRET,
ENTERPRISE_BACKEND_SERVICE_EDX_OAUTH2_PROVIDER_URL,

# Methods to derive settings
_make_mako_template_dirs,
_make_locale_paths,

# Password Validator Settings
AUTH_PASSWORD_VALIDATORS
)

from openedx.core.constants import COURSE_KEY_REGEX, COURSE_KEY_PATTERN, COURSE_ID_PATTERN
from openedx.envs.common import * # pylint: disable=wildcard-import

from lms.envs.common import (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't move these up, since it is unclear whether they belong in the CMS long term.

# FIXME: The HIBP settings are only used in the LMS, but CMS unit tests fail
# without them. Perhaps moving some code would allow us to remove these from
Expand Down Expand Up @@ -700,7 +631,7 @@
# 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),
'DIRS': Derived(make_mako_template_dirs),
# Options specific to this backend.
'OPTIONS': {
'loaders': (
Expand All @@ -719,7 +650,7 @@
'NAME': 'mako',
'BACKEND': 'common.djangoapps.edxmako.backend.Mako',
'APP_DIRS': False,
'DIRS': Derived(_make_mako_template_dirs),
'DIRS': Derived(make_mako_template_dirs),
'OPTIONS': {
'context_processors': CONTEXT_PROCESSORS,
'debug': False,
Expand Down Expand Up @@ -823,12 +754,6 @@
}
]

# These are standard regexes for pulling out info like course_ids, usage_ids, etc.
# They are used so that URLs with deprecated-format strings still work.
from lms.envs.common import (
COURSE_KEY_PATTERN, COURSE_KEY_REGEX, COURSE_ID_PATTERN, USAGE_KEY_PATTERN, ASSET_KEY_PATTERN
)

######################### CSRF #########################################

# Forwards-compatibility with Django 1.7
Expand Down Expand Up @@ -1253,12 +1178,6 @@
CELERY_TIMEZONE = 'UTC'
TIME_ZONE = 'UTC'
LANGUAGE_CODE = 'en' # http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGES_BIDI = lms.envs.common.LANGUAGES_BIDI

LANGUAGE_COOKIE_NAME = lms.envs.common.LANGUAGE_COOKIE_NAME

LANGUAGES = lms.envs.common.LANGUAGES
LANGUAGE_DICT = dict(LANGUAGES)

# Languages supported for custom course certificate templates
CERTIFICATE_TEMPLATE_LANGUAGES = {
Expand All @@ -1272,7 +1191,7 @@
STATICI18N_FILENAME_FUNCTION = 'statici18n.utils.legacy_filename'
STATICI18N_ROOT = PROJECT_ROOT / "static"

LOCALE_PATHS = Derived(_make_locale_paths)
LOCALE_PATHS = Derived(make_locale_paths)

# Messages
MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
Expand Down Expand Up @@ -1539,6 +1458,10 @@
CELERY_BROKER_USE_SSL = False
CELERY_EVENT_QUEUE_TTL = None

############################## HEARTBEAT ######################################

HEARTBEAT_CELERY_ROUTING_KEY = HIGH_PRIORITY_QUEUE
Copy link
Contributor Author

@wgu-taylor-payne wgu-taylor-payne Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HEARTBEAT_CELERY_ROUTING_KEY has previously been imported from lms/envs/common.py, but when I was looking into it, that LMS setting can/will contain lms in this str in the event that SERVICE_VARIANT is not set (I'm not sure how rare this scenario would be).

These variables follow a similar pattern in both lms/envs/common.py and cms/envs/common.py. Here is how HEARTBEAT_CELERY_ROUTING_KEY gets its value in lms/envs/common.py:

SERVICE_VARIANT = os.environ.get('SERVICE_VARIANT', 'lms')  # 'cms' in cms/envs/common.py
CONFIG_PREFIX = SERVICE_VARIANT + "." if SERVICE_VARIANT else ""
QUEUE_VARIANT = CONFIG_PREFIX.lower()
HIGH_PRIORITY_QUEUE = f'edx.{QUEUE_VARIANT}core.high'
HEARTBEAT_CELERY_ROUTING_KEY = HIGH_PRIORITY_QUEUE

So, cms/envs/common.py has the same pattern (except it defaults to 'cms' for the SERVICE_VARIANT), but then it imports HEARTBEAT_CELERY_ROUTING_KEY from the lms settings rather than using HIGH_PRIORITY_QUEUE as the value like in lms/envs/common.py.

Is that how we should keep it, or should the HEARTBEAT_CELERY_ROUTING_KEY value in the cms settings contain 'cms' rather than 'lms' in the key when/if the SERVICE_VARIANT is unset?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing to add here is I can't find anywhere the cms uses HEARTBEAT_CELERY_ROUTING_KEY.


############################## Video ##########################################

YOUTUBE = {
Expand Down
6 changes: 6 additions & 0 deletions docs/references/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ This is the list of (non-toggle) Django settings defined in the ``common.py`` mo
.. note::
Toggle settings, which enable or disable a specific feature, are documented in the :ref:`feature toggles <featuretoggles>` section.

Open edX settings
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a good section title for the settings reference page?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call it "Platform-Wide Settings". "Open edX" includes things outside of edx-platform (and the openedx/ directory is poorly named).

-----------------

.. settings::
:folder_path: openedx/envs/common.py

LMS settings
------------

Expand Down
Loading
Loading