team-10/env/Lib/site-packages/streamlit/config_util.py

184 lines
6.1 KiB
Python
Raw Normal View History

2025-08-02 07:34:44 +02:00
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2025)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
import re
from streamlit import cli_util
from streamlit.config_option import ConfigOption
def server_option_changed(
old_options: dict[str, ConfigOption], new_options: dict[str, ConfigOption]
) -> bool:
"""Return True if and only if an option in the server section differs
between old_options and new_options.
"""
for opt_name, opt_val in old_options.items():
if not opt_name.startswith("server"):
continue
old_val = opt_val.value
new_val = new_options[opt_name].value
if old_val != new_val:
return True
return False
def show_config(
section_descriptions: dict[str, str],
config_options: dict[str, ConfigOption],
) -> None:
"""Print the given config sections/options to the terminal."""
out = []
out.append(
_clean(
"""
# Below are all the sections and options you can have in
~/.streamlit/config.toml.
"""
)
)
def append_desc(text: str) -> None:
out.append("# " + cli_util.style_for_cli(text, bold=True))
def append_comment(text: str) -> None:
out.append("# " + cli_util.style_for_cli(text))
def append_section(text: str) -> None:
out.append(cli_util.style_for_cli(text, bold=True, fg="green"))
def append_setting(text: str) -> None:
out.append(cli_util.style_for_cli(text, fg="green"))
for section in section_descriptions:
# We inject a fake config section used for unit tests that we exclude here as
# its options are often missing required properties, which confuses the code
# below.
if section == "_test":
continue
section_options = {
k: v
for k, v in config_options.items()
if v.section == section and v.visibility == "visible" and not v.is_expired()
}
# Only show config header if section is non-empty.
if len(section_options) == 0:
continue
out.append("")
append_section(f"[{section}]")
out.append("")
for option in section_options.values():
key = option.key.split(".")[-1]
description_paragraphs = _clean_paragraphs(option.description or "")
last_paragraph_idx = len(description_paragraphs) - 1
for i, paragraph in enumerate(description_paragraphs):
# Split paragraph into lines
lines = paragraph.rstrip().split(
"\n"
) # Remove trailing newline characters
# If the first line is empty, remove it
if lines and not lines[0].strip():
lines = lines[1:]
# Choose function based on whether it's the first paragraph or not
append_func = append_desc if i == 0 else append_comment
# Add comment character to each line and add to out
for line in lines:
append_func(line.lstrip())
# # Add a line break after a paragraph only if it's not the last paragraph
if i != last_paragraph_idx:
append_comment("")
if option.deprecated:
if out[-1] != "#":
append_comment("")
append_comment(
cli_util.style_for_cli("THIS IS DEPRECATED.", fg="yellow")
)
append_comment("")
for line in _clean_paragraphs(option.deprecation_text):
append_comment(line)
append_comment("")
append_comment(
f"This option will be removed on or after {option.expiration_date}."
)
import toml
toml_default = toml.dumps({"default": option.default_val})
toml_default = toml_default[10:].strip()
if len(toml_default) > 0:
# Ensure a line break before appending "Default" comment, if not already there
if out[-1] != "#":
append_comment("")
append_comment(f"Default: {toml_default}")
else:
# Don't say "Default: (unset)" here because this branch applies
# to complex config settings too.
pass
option_is_manually_set = (
option.where_defined != ConfigOption.DEFAULT_DEFINITION
)
if option_is_manually_set:
if out[-1] != "# ":
append_comment("")
append_comment(f"The value below was set in {option.where_defined}")
toml_setting = toml.dumps({key: option.value})
if len(toml_setting) == 0:
toml_setting = f"# {key} =\n"
elif not option_is_manually_set:
toml_setting = f"# {toml_setting}"
append_setting(toml_setting)
cli_util.print_to_cli("\n".join(out))
def _clean(txt: str) -> str:
"""Replace sequences of multiple spaces with a single space, excluding newlines.
Preserves leading and trailing spaces, and does not modify spaces in between lines.
"""
return re.sub(" +", " ", txt)
def _clean_paragraphs(txt: str) -> list[str]:
"""Split the text into paragraphs, preserve newlines within the paragraphs."""
# Strip both leading and trailing newlines.
txt = txt.strip("\n")
paragraphs = txt.split("\n\n")
return [
"\n".join(_clean(line) for line in paragraph.split("\n"))
for paragraph in paragraphs
]