2.2.1.1. configuration.core module

2.2.1.1.1. Configuring Runestone Servers

Many things about Runestone servers are configurable. This is the place to change the configuration for most things. Private things should be configured in the environment so they are not accidentally committed to Github. Defaults provided here may be overridden by environment variables Per.

class configuration.core.BookServerConfig(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: Enum

development = 'development'
production = 'production'
test = 'test'
class configuration.core.DatabaseType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: Enum

PostgreSQL = 1
SQLite = 0
class configuration.core.Settings(_case_sensitive: bool | None = None, _nested_model_default_partial_update: bool | None = None, _env_prefix: str | None = None, _env_prefix_target: EnvPrefixTarget | None = None, _env_file: DotenvType | None = PosixPath('.'), _env_file_encoding: str | None = None, _env_ignore_empty: bool | None = None, _env_nested_delimiter: str | None = None, _env_nested_max_split: int | None = None, _env_parse_none_str: str | None = None, _env_parse_enums: bool | None = None, _cli_prog_name: str | None = None, _cli_parse_args: bool | list[str] | tuple[str, ...] | None = None, _cli_settings_source: CliSettingsSource[Any] | None = None, _cli_parse_none_str: str | None = None, _cli_hide_none_type: bool | None = None, _cli_avoid_json: bool | None = None, _cli_enforce_required: bool | None = None, _cli_use_class_docs_for_groups: bool | None = None, _cli_exit_on_error: bool | None = None, _cli_prefix: str | None = None, _cli_flag_prefix_char: str | None = None, _cli_implicit_flags: bool | Literal['dual', 'toggle'] | None = None, _cli_ignore_unknown_args: bool | None = None, _cli_kebab_case: bool | Literal['all', 'no_enums'] | None = None, _cli_shortcuts: Mapping[str, str | list[str]] | None = None, _secrets_dir: PathType | None = None, _build_sources: tuple[tuple[PydanticBaseSettingsSource, ...], dict[str, Any]] | None = None, *, google_ga: str = '', runestone_path: Path = PosixPath('/usr'), book_path: Path = PosixPath('/usr/books'), error_path: Path = PosixPath('/usr/books/tickets'), server_config: str = 'development', book_server_config: BookServerConfig = BookServerConfig.development, dburl: str = 'sqlite:////usr/runestone.db', dev_dburl: str = 'sqlite:////usr/runestone_dev.db', test_dburl: str = 'sqlite:////usr/runestone_test.db', db_echo: bool = False, redis_uri: str = 'redis://localhost:6379/0', is_exam: bool = False, login_url: str = '/auth/login', load_balancer_host: str = '', runestone_host: str = 'localhost', certbot_email: str = '', caddy_site_address: str = '', adsenseid: str = '', num_banners: int = 0, serve_ad: bool = False, academy_mode: bool = True, lti_only_mode: bool = False, telemetry_enabled: bool = True, telemetry_url: str = 'https://runestone.academy/admin/telemetry/checkin', telemetry_region: str = '', telemetry_institution: str = '', jwt_secret: bytes = b'supersecret', fernet_secret: bytes = b'6M7llOz2ztmNV_5dZ0rOsODNACMkRLLMDb9K1MLw91w=', drop_tables: str = 'No', spaces_key: str = 'key', spaces_secret: str = 'secret', region: str = 'nyc3', bucket: str = 'runestonefiles', log_level: str = 'DEBUG', jobe_key: str = '', jobe_server: str = 'http://jobe', email_sender: str = 'secure@mg.runestone.academy', mailgun_api_key: str = '', mailgun_domain: str = 'mg.runestone.academy', email_from: str = 'support@runestone.academy', email_login: str = '', email_server: str = 'smtp.mailgun.org:587', github_token: str = '', github_issue_repo: str = 'RunestoneInteractive/rs', **values: Any)

Bases: BaseSettings

Pydantic provides a wonderful utility to handle settings. The beauty of it is that you can specify variables with or without default values, and Pydantic will check your environment variables in a case-insensitive way. So that if you have PROD_DBURL` set in the environment it will be set as the value for prod_dburl` in settings. This is a really nice way to keep from committing any data you want to keep private.

academy_mode: bool
adsenseid: str
book_path: Path
book_server_config: BookServerConfig
bucket: str
caddy_site_address: str
certbot_email: str
property database_type: DatabaseType
property database_url: str
db_echo: bool
dburl: str
dev_dburl: str
drop_tables: str
email_from: str
email_login: str
email_sender: str
email_server: str
error_path: Path
fernet_secret: bytes
github_issue_repo: str
github_token: str
google_ga: str
is_exam: bool
jobe_key: str
jobe_server: str
jwt_secret: bytes
load_balancer_host: str
log_level: str
login_url: str
lti_only_mode: bool
mailgun_api_key: str
mailgun_domain: str
model_config: ClassVar[SettingsConfigDict] = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_exit_on_error': True, 'cli_flag_prefix_char': '-', 'cli_hide_none_type': False, 'cli_ignore_unknown_args': False, 'cli_implicit_flags': False, 'cli_kebab_case': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_shortcuts': None, 'cli_use_class_docs_for_groups': False, 'enable_decoding': True, 'env_file': '.env', 'env_file_encoding': 'utf-8', 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'allow', 'json_file': None, 'json_file_encoding': None, 'nested_model_default_partial_update': False, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'secrets_dir': None, 'toml_file': None, 'validate_default': True, 'yaml_config_section': None, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

num_banners: int
redis_uri: str
region: str
runestone_host: str
runestone_path: Path
serve_ad: bool
server_config: str
property server_url: str

Return the public base URL (scheme + host) for this deployment.

Prefers LOAD_BALANCER_HOST; otherwise falls back to RUNESTONE_HOST, using HTTPS only when CERTBOT_EMAIL indicates certificates are configured. This mirrors the websocket_url resolution in the web2py models.

Returns:

The base URL, e.g. https://runestone.academy.

Return type:

str

spaces_key: str
spaces_secret: str
telemetry_enabled: bool
telemetry_institution: str
telemetry_region: str
telemetry_url: str
test_dburl: str
property web2py_private_key: str

Get the web2py private key. Prefer to get it from the environment. This allows us to avoid introducing a secret into the codebase, and it also avoids the need to mount a volume to the container to store the key in a file.

Returns:

The web2py private key.

Return type:

str