123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- """Import all classes and functions the end user will need to make an app.
- Anything imported here will be available in the default Reflex import as `rx.*`.
- To signal to typecheckers that something should be reexported,
- we use the Flask "import name as name" syntax.
- """
- from __future__ import annotations
- import importlib
- from typing import Type
- from reflex.page import page as page
- from reflex.utils import console
- from reflex.utils.format import to_snake_case
- _ALL_COMPONENTS = [
- # Core
- "color",
- "cond",
- "foreach",
- "html",
- "match",
- "color_mode_cond",
- "connection_banner",
- "connection_modal",
- "debounce_input",
- # Base
- "fragment",
- "Fragment",
- "image",
- "script",
- # Responsive
- "desktop_only",
- "mobile_and_tablet",
- "mobile_only",
- "tablet_and_desktop",
- "tablet_only",
- # Upload
- "cancel_upload",
- "clear_selected_files",
- "get_upload_dir",
- "get_upload_url",
- "selected_files",
- "upload",
- # Radix
- "accordion",
- "alert_dialog",
- "aspect_ratio",
- "avatar",
- "badge",
- "blockquote",
- "box",
- "button",
- "callout",
- "card",
- "center",
- "checkbox",
- "code",
- "container",
- "context_menu",
- "dialog",
- "divider",
- "drawer",
- "flex",
- "form",
- "grid",
- "heading",
- "hover_card",
- "hstack",
- "icon_button",
- "inset",
- "input",
- "link",
- "menu",
- "popover",
- "progress",
- "radio",
- "scroll_area",
- "section",
- "select",
- "slider",
- "spacer",
- "stack",
- "switch",
- "table",
- "tabs",
- "text",
- "text_area",
- "theme",
- "theme_panel",
- "tooltip",
- "vstack",
- # Other
- "code_block",
- "data_editor",
- "data_editor_theme",
- "data_table",
- "plotly",
- "audio",
- "video",
- "editor",
- "EditorButtonList",
- "EditorOptions",
- "icon",
- "markdown",
- "list_item",
- "unordered_list",
- "ordered_list",
- "moment",
- ]
- _MAPPING = {
- "reflex.admin": ["admin", "AdminDash"],
- "reflex.app": ["app", "App", "UploadFile"],
- "reflex.base": ["base", "Base"],
- "reflex.compiler": ["compiler"],
- "reflex.compiler.utils": ["get_asset_path"],
- "reflex.components": _ALL_COMPONENTS,
- "reflex.components.component": ["Component", "NoSSRComponent", "memo"],
- "reflex.components.chakra": ["chakra"],
- "reflex.components.el": ["el"],
- "reflex.components.lucide": ["lucide"],
- "reflex.components.next": ["next"],
- "reflex.components.radix": ["radix", "color_mode"],
- "reflex.components.recharts": ["recharts"],
- "reflex.components.moment.moment": ["MomentDelta"],
- "reflex.config": ["config", "Config", "DBConfig"],
- "reflex.constants": ["constants", "Env"],
- "reflex.event": [
- "event",
- "EventChain",
- "background",
- "call_script",
- "clear_local_storage",
- "console_log",
- "download",
- "prevent_default",
- "redirect",
- "remove_cookie",
- "remove_local_storage",
- "set_clipboard",
- "set_focus",
- "set_value",
- "stop_propagation",
- "upload_files",
- "window_alert",
- ],
- "reflex.middleware": ["middleware", "Middleware"],
- "reflex.model": ["model", "session", "Model"],
- "reflex.page": ["page"],
- "reflex.route": ["route"],
- "reflex.state": ["state", "var", "Cookie", "LocalStorage", "State"],
- "reflex.style": ["style", "toggle_color_mode"],
- "reflex.testing": ["testing"],
- "reflex.utils": ["utils"],
- "reflex.vars": ["vars", "cached_var", "Var"],
- }
- def _reverse_mapping(mapping: dict[str, list]) -> dict[str, str]:
- """Reverse the mapping used to lazy loading, and check for conflicting name.
- Args:
- mapping: The mapping to reverse.
- Returns:
- The reversed mapping.
- """
- reversed_mapping = {}
- for key, values in mapping.items():
- for value in values:
- if value not in reversed_mapping:
- reversed_mapping[value] = key
- else:
- console.warn(
- f"Key {value} is present multiple times in the imports _MAPPING: {key} / {reversed_mapping[value]}"
- )
- return reversed_mapping
- # _MAPPING = {value: key for key, values in _MAPPING.items() for value in values}
- _MAPPING = _reverse_mapping(_MAPPING)
- def _removeprefix(text, prefix):
- return text[text.startswith(prefix) and len(prefix) :]
- __all__ = [_removeprefix(mod, "reflex.") for mod in _MAPPING]
- def __getattr__(name: str) -> Type:
- """Lazy load all modules.
- Args:
- name: name of the module to load.
- Returns:
- The module or the attribute of the module.
- Raises:
- AttributeError: If the module or the attribute does not exist.
- """
- try:
- # Check for import of a module that is not in the mapping.
- if name not in _MAPPING:
- # If the name does not start with reflex, add it.
- if not name.startswith("reflex") and name != "__all__":
- name = f"reflex.{name}"
- return importlib.import_module(name)
- # Import the module.
- module = importlib.import_module(_MAPPING[name])
- # Get the attribute from the module if the name is not the module itself.
- return (
- getattr(module, name) if name != _MAPPING[name].rsplit(".")[-1] else module
- )
- except ModuleNotFoundError:
- raise AttributeError(f"module 'reflex' has no attribute {name}") from None
|