__init__.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. """Import all classes and functions the end user will need to make an app.
  2. Anything imported here will be available in the default Reflex import as `rx.*`.
  3. To signal to typecheckers that something should be reexported,
  4. we use the Flask "import name as name" syntax.
  5. """
  6. from __future__ import annotations
  7. import importlib
  8. from typing import Type
  9. from reflex.constants.colors import Color as color
  10. from reflex.page import page as page
  11. from reflex.utils import console
  12. from reflex.utils.format import to_snake_case
  13. _ALL_COMPONENTS = [
  14. "Accordion",
  15. "AccordionButton",
  16. "AccordionIcon",
  17. "AccordionItem",
  18. "AccordionPanel",
  19. "Alert",
  20. "AlertDescription",
  21. "AlertDialog",
  22. "AlertDialogBody",
  23. "AlertDialogContent",
  24. "AlertDialogFooter",
  25. "AlertDialogHeader",
  26. "AlertDialogOverlay",
  27. "AlertIcon",
  28. "AlertTitle",
  29. "AspectRatio",
  30. "Audio",
  31. "Avatar",
  32. "AvatarBadge",
  33. "AvatarGroup",
  34. "Badge",
  35. "Box",
  36. "Breadcrumb",
  37. "BreadcrumbItem",
  38. "BreadcrumbLink",
  39. "BreadcrumbSeparator",
  40. "Button",
  41. "ButtonGroup",
  42. "Card",
  43. "CardBody",
  44. "CardFooter",
  45. "CardHeader",
  46. "Center",
  47. "Checkbox",
  48. "CheckboxGroup",
  49. "CircularProgress",
  50. "CircularProgressLabel",
  51. "Circle",
  52. "Code",
  53. "CodeBlock",
  54. "Collapse",
  55. "ColorModeButton",
  56. "ColorModeIcon",
  57. "ColorModeSwitch",
  58. "Component",
  59. "Cond",
  60. "ConnectionBanner",
  61. "ConnectionModal",
  62. "Container",
  63. "DataTable",
  64. "DataEditor",
  65. "DataEditorTheme",
  66. "DatePicker",
  67. "DateTimePicker",
  68. "DebounceInput",
  69. "Divider",
  70. "Drawer",
  71. "DrawerBody",
  72. "DrawerCloseButton",
  73. "DrawerContent",
  74. "DrawerFooter",
  75. "DrawerHeader",
  76. "DrawerOverlay",
  77. "Editable",
  78. "EditableInput",
  79. "EditablePreview",
  80. "EditableTextarea",
  81. "Editor",
  82. "Email",
  83. "Fade",
  84. "Flex",
  85. "Foreach",
  86. "Form",
  87. "FormControl",
  88. "FormErrorMessage",
  89. "FormHelperText",
  90. "FormLabel",
  91. "Fragment",
  92. "Grid",
  93. "GridItem",
  94. "Heading",
  95. "Highlight",
  96. "Hstack",
  97. "Html",
  98. "Icon",
  99. "IconButton",
  100. "Image",
  101. "Input",
  102. "InputGroup",
  103. "InputLeftAddon",
  104. "InputLeftElement",
  105. "InputRightAddon",
  106. "InputRightElement",
  107. "Kbd",
  108. "Link",
  109. "LinkBox",
  110. "LinkOverlay",
  111. "List",
  112. "ListItem",
  113. "Markdown",
  114. "Match",
  115. "Menu",
  116. "MenuButton",
  117. "MenuDivider",
  118. "MenuGroup",
  119. "MenuItem",
  120. "MenuItemOption",
  121. "MenuList",
  122. "MenuOptionGroup",
  123. "Modal",
  124. "ModalBody",
  125. "ModalCloseButton",
  126. "ModalContent",
  127. "ModalFooter",
  128. "ModalHeader",
  129. "ModalOverlay",
  130. "Moment",
  131. "MultiSelect",
  132. "MultiSelectOption",
  133. "NextLink",
  134. "NumberDecrementStepper",
  135. "NumberIncrementStepper",
  136. "NumberInput",
  137. "NumberInputField",
  138. "NumberInputStepper",
  139. "Option",
  140. "OrderedList",
  141. "Password",
  142. "PinInput",
  143. "PinInputField",
  144. "Plotly",
  145. "Popover",
  146. "PopoverAnchor",
  147. "PopoverArrow",
  148. "PopoverBody",
  149. "PopoverCloseButton",
  150. "PopoverContent",
  151. "PopoverFooter",
  152. "PopoverHeader",
  153. "PopoverTrigger",
  154. "Progress",
  155. "Radio",
  156. "RadioGroup",
  157. "RangeSlider",
  158. "RangeSliderFilledTrack",
  159. "RangeSliderThumb",
  160. "RangeSliderTrack",
  161. "ResponsiveGrid",
  162. "ScaleFade",
  163. "Script",
  164. "Select",
  165. "Skeleton",
  166. "SkeletonCircle",
  167. "SkeletonText",
  168. "Slide",
  169. "SlideFade",
  170. "Slider",
  171. "SliderFilledTrack",
  172. "SliderMark",
  173. "SliderThumb",
  174. "SliderTrack",
  175. "Spacer",
  176. "Span",
  177. "Spinner",
  178. "Square",
  179. "Stack",
  180. "Stat",
  181. "StatArrow",
  182. "StatGroup",
  183. "StatHelpText",
  184. "StatLabel",
  185. "StatNumber",
  186. "Step",
  187. "StepDescription",
  188. "StepIcon",
  189. "StepIndicator",
  190. "StepNumber",
  191. "StepSeparator",
  192. "StepStatus",
  193. "StepTitle",
  194. "Stepper",
  195. "Switch",
  196. "Tab",
  197. "TabList",
  198. "TabPanel",
  199. "TabPanels",
  200. "Table",
  201. "TableCaption",
  202. "TableContainer",
  203. "Tabs",
  204. "Tag",
  205. "TagCloseButton",
  206. "TagLabel",
  207. "TagLeftIcon",
  208. "TagRightIcon",
  209. "Tbody",
  210. "Td",
  211. "Text",
  212. "TextArea",
  213. "Tfoot",
  214. "Th",
  215. "Thead",
  216. "TimePicker",
  217. "Tooltip",
  218. "Tr",
  219. "UnorderedList",
  220. "Upload",
  221. "Video",
  222. "VisuallyHidden",
  223. "Vstack",
  224. "Wrap",
  225. "WrapItem",
  226. ]
  227. _ALL_COMPONENTS += [to_snake_case(component) for component in _ALL_COMPONENTS]
  228. _ALL_COMPONENTS += [
  229. "cancel_upload",
  230. "components",
  231. "color_mode_cond",
  232. "desktop_only",
  233. "mobile_only",
  234. "tablet_only",
  235. "mobile_and_tablet",
  236. "tablet_and_desktop",
  237. "selected_files",
  238. "clear_selected_files",
  239. "EditorButtonList",
  240. "EditorOptions",
  241. "NoSSRComponent",
  242. ]
  243. _MAPPING = {
  244. "reflex.admin": ["admin", "AdminDash"],
  245. "reflex.app": ["app", "App", "UploadFile"],
  246. "reflex.base": ["base", "Base"],
  247. "reflex.compiler": ["compiler"],
  248. "reflex.compiler.utils": ["get_asset_path"],
  249. "reflex.components": _ALL_COMPONENTS + ["chakra", "next"],
  250. "reflex.components.component": ["memo"],
  251. "reflex.components.el": ["el"],
  252. "reflex.components.lucide": ["lucide"],
  253. "reflex.components.radix": ["radix"],
  254. "reflex.components.recharts": ["recharts"],
  255. "reflex.components.moment.moment": ["MomentDelta"],
  256. "reflex.config": ["config", "Config", "DBConfig"],
  257. "reflex.constants": ["constants", "Env"],
  258. "reflex.event": [
  259. "event",
  260. "EventChain",
  261. "background",
  262. "call_script",
  263. "clear_local_storage",
  264. "console_log",
  265. "download",
  266. "prevent_default",
  267. "redirect",
  268. "remove_cookie",
  269. "remove_local_storage",
  270. "set_clipboard",
  271. "set_focus",
  272. "set_value",
  273. "stop_propagation",
  274. "upload_files",
  275. "window_alert",
  276. ],
  277. "reflex.middleware": ["middleware", "Middleware"],
  278. "reflex.model": ["model", "session", "Model"],
  279. "reflex.page": ["page"],
  280. "reflex.route": ["route"],
  281. "reflex.state": ["state", "var", "Cookie", "LocalStorage", "State"],
  282. "reflex.style": ["style", "color_mode", "toggle_color_mode"],
  283. "reflex.testing": ["testing"],
  284. "reflex.utils": ["utils"],
  285. "reflex.vars": ["vars", "cached_var", "Var"],
  286. }
  287. def _reverse_mapping(mapping: dict[str, list]) -> dict[str, str]:
  288. """Reverse the mapping used to lazy loading, and check for conflicting name.
  289. Args:
  290. mapping: The mapping to reverse.
  291. Returns:
  292. The reversed mapping.
  293. """
  294. reversed_mapping = {}
  295. for key, values in mapping.items():
  296. for value in values:
  297. if value not in reversed_mapping:
  298. reversed_mapping[value] = key
  299. else:
  300. console.warn(
  301. f"Key {value} is present multiple times in the imports _MAPPING: {key} / {reversed_mapping[value]}"
  302. )
  303. return reversed_mapping
  304. # _MAPPING = {value: key for key, values in _MAPPING.items() for value in values}
  305. _MAPPING = _reverse_mapping(_MAPPING)
  306. def _removeprefix(text, prefix):
  307. return text[text.startswith(prefix) and len(prefix) :]
  308. __all__ = [_removeprefix(mod, "reflex.") for mod in _MAPPING]
  309. def __getattr__(name: str) -> Type:
  310. """Lazy load all modules.
  311. Args:
  312. name: name of the module to load.
  313. Returns:
  314. The module or the attribute of the module.
  315. Raises:
  316. AttributeError: If the module or the attribute does not exist.
  317. """
  318. try:
  319. # Check for import of a module that is not in the mapping.
  320. if name not in _MAPPING:
  321. # If the name does not start with reflex, add it.
  322. if not name.startswith("reflex") and name != "__all__":
  323. name = f"reflex.{name}"
  324. return importlib.import_module(name)
  325. # Import the module.
  326. module = importlib.import_module(_MAPPING[name])
  327. # Get the attribute from the module if the name is not the module itself.
  328. return (
  329. getattr(module, name) if name != _MAPPING[name].rsplit(".")[-1] else module
  330. )
  331. except ModuleNotFoundError:
  332. raise AttributeError(f"module 'reflex' has no attribute {name}") from None