import os import flask # noinspection PyCompatibility from . import exceptions from ._utils import AttributeDict def load_dash_env_vars(): return AttributeDict( { var: os.getenv(var, os.getenv(var.lower())) for var in ( "DASH_APP_NAME", "DASH_URL_BASE_PATHNAME", "DASH_ROUTES_PATHNAME_PREFIX", "DASH_REQUESTS_PATHNAME_PREFIX", "DASH_SUPPRESS_CALLBACK_EXCEPTIONS", "DASH_ASSETS_EXTERNAL_PATH", "DASH_INCLUDE_ASSETS_FILES", "DASH_COMPONENTS_CACHE_MAX_AGE", "DASH_INCLUDE_ASSETS_FILES", "DASH_SERVE_DEV_BUNDLES", "DASH_DEBUG", "DASH_UI", "DASH_PROPS_CHECK", "DASH_HOT_RELOAD", "DASH_HOT_RELOAD_INTERVAL", "DASH_HOT_RELOAD_WATCH_INTERVAL", "DASH_HOT_RELOAD_MAX_RETRY", "DASH_SILENCE_ROUTES_LOGGING", "DASH_PRUNE_ERRORS", "DASH_COMPRESS", "HOST", "PORT", ) } ) DASH_ENV_VARS = load_dash_env_vars() # used in tests def get_combined_config(name, val, default=None): """Consolidate the config with priority from high to low provided init value > OS environ > default.""" if val is not None: return val env = load_dash_env_vars().get(f"DASH_{name.upper()}") if env is None: return default return env.lower() == "true" if env.lower() in {"true", "false"} else env def pathname_configs( url_base_pathname=None, routes_pathname_prefix=None, requests_pathname_prefix=None ): _pathname_config_error_message = """ {} This is ambiguous. To fix this, set `routes_pathname_prefix` instead of `url_base_pathname`. Note that `requests_pathname_prefix` is the prefix for the AJAX calls that originate from the client (the web browser) and `routes_pathname_prefix` is the prefix for the API routes on the backend (this flask server). `url_base_pathname` will set `requests_pathname_prefix` and `routes_pathname_prefix` to the same value. If you need these to be different values then you should set `requests_pathname_prefix` and `routes_pathname_prefix`, not `url_base_pathname`. """ url_base_pathname = get_combined_config("url_base_pathname", url_base_pathname) routes_pathname_prefix = get_combined_config( "routes_pathname_prefix", routes_pathname_prefix ) requests_pathname_prefix = get_combined_config( "requests_pathname_prefix", requests_pathname_prefix ) if url_base_pathname is not None and requests_pathname_prefix is not None: raise exceptions.InvalidConfig( _pathname_config_error_message.format( "You supplied `url_base_pathname` and `requests_pathname_prefix`." ) ) if url_base_pathname is not None and routes_pathname_prefix is not None: raise exceptions.InvalidConfig( _pathname_config_error_message.format( "You supplied `url_base_pathname` and `routes_pathname_prefix`." ) ) if url_base_pathname is not None and routes_pathname_prefix is None: routes_pathname_prefix = url_base_pathname elif routes_pathname_prefix is None: routes_pathname_prefix = "/" if not routes_pathname_prefix.startswith("/"): raise exceptions.InvalidConfig( "`routes_pathname_prefix` needs to start with `/`" ) if not routes_pathname_prefix.endswith("/"): raise exceptions.InvalidConfig("`routes_pathname_prefix` needs to end with `/`") app_name = load_dash_env_vars().DASH_APP_NAME if not requests_pathname_prefix and app_name: requests_pathname_prefix = "/" + app_name + routes_pathname_prefix elif requests_pathname_prefix is None: requests_pathname_prefix = routes_pathname_prefix if not requests_pathname_prefix.startswith("/"): raise exceptions.InvalidConfig( "`requests_pathname_prefix` needs to start with `/`" ) return url_base_pathname, routes_pathname_prefix, requests_pathname_prefix def pages_folder_config(name, pages_folder, use_pages): if not pages_folder: return None is_custom_folder = str(pages_folder) != "pages" pages_folder_path = os.path.join(flask.helpers.get_root_path(name), pages_folder) if (use_pages or is_custom_folder) and not os.path.isdir(pages_folder_path): error_msg = f""" A folder called `{pages_folder}` does not exist. If a folder for pages is not required in your application, set `pages_folder=""`. For example: `app = Dash(__name__, pages_folder="")` """ raise exceptions.InvalidConfig(error_msg) return pages_folder_path