reflex 0.8.0a4__py3-none-any.whl → 0.8.0a6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of reflex might be problematic. Click here for more details.

Files changed (163) hide show
  1. reflex/.templates/jinja/web/pages/_app.js.jinja2 +1 -1
  2. reflex/.templates/jinja/web/styles/styles.css.jinja2 +1 -0
  3. reflex/.templates/web/app/routes.js +3 -3
  4. reflex/.templates/web/utils/client_side_routing.js +1 -1
  5. reflex/.templates/web/utils/state.js +110 -52
  6. reflex/__init__.pyi +327 -188
  7. reflex/app.py +50 -48
  8. reflex/compiler/compiler.py +6 -2
  9. reflex/compiler/utils.py +32 -14
  10. reflex/components/__init__.pyi +34 -15
  11. reflex/components/base/__init__.pyi +30 -19
  12. reflex/components/base/app_wrap.pyi +2 -3
  13. reflex/components/base/body.pyi +2 -3
  14. reflex/components/base/document.pyi +7 -13
  15. reflex/components/base/error_boundary.pyi +2 -3
  16. reflex/components/base/fragment.pyi +2 -3
  17. reflex/components/base/link.pyi +3 -5
  18. reflex/components/base/meta.py +4 -15
  19. reflex/components/base/meta.pyi +14 -18
  20. reflex/components/base/script.pyi +2 -3
  21. reflex/components/base/strict_mode.pyi +2 -3
  22. reflex/components/core/__init__.pyi +77 -38
  23. reflex/components/core/auto_scroll.pyi +2 -3
  24. reflex/components/core/banner.pyi +8 -14
  25. reflex/components/core/client_side_routing.pyi +2 -3
  26. reflex/components/core/clipboard.pyi +2 -3
  27. reflex/components/core/debounce.pyi +2 -3
  28. reflex/components/core/foreach.py +2 -2
  29. reflex/components/core/helmet.pyi +2 -3
  30. reflex/components/core/html.pyi +2 -3
  31. reflex/components/core/match.py +3 -3
  32. reflex/components/core/sticky.pyi +4 -7
  33. reflex/components/core/upload.py +2 -1
  34. reflex/components/core/upload.pyi +5 -9
  35. reflex/components/datadisplay/__init__.pyi +13 -7
  36. reflex/components/datadisplay/code.py +12 -7
  37. reflex/components/datadisplay/code.pyi +2 -3
  38. reflex/components/datadisplay/dataeditor.pyi +33 -11
  39. reflex/components/datadisplay/shiki_code_block.py +5 -3
  40. reflex/components/datadisplay/shiki_code_block.pyi +3 -5
  41. reflex/components/el/__init__.pyi +506 -246
  42. reflex/components/el/element.pyi +2 -3
  43. reflex/components/el/elements/__init__.pyi +504 -245
  44. reflex/components/el/elements/base.pyi +2 -3
  45. reflex/components/el/elements/forms.pyi +77 -49
  46. reflex/components/el/elements/inline.pyi +29 -57
  47. reflex/components/el/elements/media.pyi +26 -51
  48. reflex/components/el/elements/metadata.pyi +7 -13
  49. reflex/components/el/elements/other.pyi +8 -15
  50. reflex/components/el/elements/scripts.pyi +4 -7
  51. reflex/components/el/elements/sectioning.pyi +16 -31
  52. reflex/components/el/elements/tables.pyi +11 -21
  53. reflex/components/el/elements/typography.pyi +16 -31
  54. reflex/components/gridjs/datatable.pyi +3 -5
  55. reflex/components/lucide/icon.pyi +4 -7
  56. reflex/components/markdown/markdown.py +5 -3
  57. reflex/components/markdown/markdown.pyi +2 -3
  58. reflex/components/moment/moment.py +1 -1
  59. reflex/components/moment/moment.pyi +2 -3
  60. reflex/components/plotly/plotly.py +12 -6
  61. reflex/components/plotly/plotly.pyi +31 -39
  62. reflex/components/radix/__init__.pyi +123 -65
  63. reflex/components/radix/primitives/__init__.pyi +6 -4
  64. reflex/components/radix/primitives/accordion.pyi +8 -15
  65. reflex/components/radix/primitives/base.pyi +3 -5
  66. reflex/components/radix/primitives/drawer.pyi +11 -21
  67. reflex/components/radix/primitives/form.pyi +22 -22
  68. reflex/components/radix/primitives/progress.pyi +5 -9
  69. reflex/components/radix/primitives/slider.pyi +6 -11
  70. reflex/components/radix/themes/__init__.pyi +5 -6
  71. reflex/components/radix/themes/base.pyi +9 -17
  72. reflex/components/radix/themes/color_mode.py +5 -6
  73. reflex/components/radix/themes/color_mode.pyi +4 -7
  74. reflex/components/radix/themes/components/__init__.pyi +75 -38
  75. reflex/components/radix/themes/components/alert_dialog.pyi +8 -15
  76. reflex/components/radix/themes/components/aspect_ratio.pyi +2 -3
  77. reflex/components/radix/themes/components/avatar.pyi +2 -3
  78. reflex/components/radix/themes/components/badge.pyi +2 -3
  79. reflex/components/radix/themes/components/button.pyi +2 -3
  80. reflex/components/radix/themes/components/callout.pyi +5 -9
  81. reflex/components/radix/themes/components/card.pyi +2 -3
  82. reflex/components/radix/themes/components/checkbox.pyi +3 -5
  83. reflex/components/radix/themes/components/checkbox_cards.pyi +3 -5
  84. reflex/components/radix/themes/components/checkbox_group.pyi +3 -5
  85. reflex/components/radix/themes/components/context_menu.pyi +14 -27
  86. reflex/components/radix/themes/components/data_list.pyi +5 -9
  87. reflex/components/radix/themes/components/dialog.pyi +7 -13
  88. reflex/components/radix/themes/components/dropdown_menu.pyi +9 -17
  89. reflex/components/radix/themes/components/hover_card.pyi +4 -7
  90. reflex/components/radix/themes/components/icon_button.pyi +2 -3
  91. reflex/components/radix/themes/components/inset.pyi +2 -3
  92. reflex/components/radix/themes/components/popover.pyi +5 -9
  93. reflex/components/radix/themes/components/progress.pyi +2 -3
  94. reflex/components/radix/themes/components/radio.pyi +2 -3
  95. reflex/components/radix/themes/components/radio_cards.pyi +3 -5
  96. reflex/components/radix/themes/components/radio_group.pyi +4 -7
  97. reflex/components/radix/themes/components/scroll_area.pyi +2 -3
  98. reflex/components/radix/themes/components/segmented_control.pyi +3 -5
  99. reflex/components/radix/themes/components/select.pyi +9 -17
  100. reflex/components/radix/themes/components/separator.pyi +2 -3
  101. reflex/components/radix/themes/components/skeleton.pyi +2 -3
  102. reflex/components/radix/themes/components/slider.pyi +12 -5
  103. reflex/components/radix/themes/components/spinner.pyi +2 -3
  104. reflex/components/radix/themes/components/switch.pyi +2 -3
  105. reflex/components/radix/themes/components/table.pyi +8 -15
  106. reflex/components/radix/themes/components/tabs.pyi +5 -9
  107. reflex/components/radix/themes/components/text_area.pyi +10 -5
  108. reflex/components/radix/themes/components/text_field.pyi +19 -9
  109. reflex/components/radix/themes/components/tooltip.pyi +2 -3
  110. reflex/components/radix/themes/layout/__init__.pyi +27 -14
  111. reflex/components/radix/themes/layout/base.pyi +2 -3
  112. reflex/components/radix/themes/layout/box.pyi +2 -3
  113. reflex/components/radix/themes/layout/center.pyi +2 -3
  114. reflex/components/radix/themes/layout/container.pyi +2 -3
  115. reflex/components/radix/themes/layout/flex.pyi +2 -3
  116. reflex/components/radix/themes/layout/grid.pyi +2 -3
  117. reflex/components/radix/themes/layout/list.pyi +5 -9
  118. reflex/components/radix/themes/layout/section.pyi +2 -3
  119. reflex/components/radix/themes/layout/spacer.pyi +2 -3
  120. reflex/components/radix/themes/layout/stack.pyi +4 -7
  121. reflex/components/radix/themes/typography/__init__.pyi +7 -5
  122. reflex/components/radix/themes/typography/blockquote.pyi +2 -3
  123. reflex/components/radix/themes/typography/code.pyi +2 -3
  124. reflex/components/radix/themes/typography/heading.pyi +2 -3
  125. reflex/components/radix/themes/typography/link.pyi +3 -5
  126. reflex/components/radix/themes/typography/text.pyi +7 -13
  127. reflex/components/react_player/audio.pyi +5 -4
  128. reflex/components/react_player/react_player.pyi +2 -3
  129. reflex/components/react_player/video.pyi +5 -4
  130. reflex/components/recharts/__init__.pyi +208 -100
  131. reflex/components/recharts/cartesian.py +8 -7
  132. reflex/components/recharts/cartesian.pyi +25 -48
  133. reflex/components/recharts/charts.pyi +13 -25
  134. reflex/components/recharts/general.pyi +7 -13
  135. reflex/components/recharts/polar.pyi +7 -13
  136. reflex/components/recharts/recharts.py +2 -2
  137. reflex/components/recharts/recharts.pyi +3 -5
  138. reflex/components/sonner/toast.py +1 -1
  139. reflex/components/sonner/toast.pyi +2 -3
  140. reflex/constants/installer.py +7 -8
  141. reflex/constants/route.py +13 -6
  142. reflex/istate/__init__.py +69 -0
  143. reflex/istate/manager.py +1 -0
  144. reflex/plugins/shared_tailwind.py +58 -1
  145. reflex/plugins/tailwind_v3.py +4 -4
  146. reflex/plugins/tailwind_v4.py +6 -5
  147. reflex/route.py +159 -71
  148. reflex/state.py +38 -16
  149. reflex/testing.py +2 -1
  150. reflex/utils/exec.py +18 -13
  151. reflex/utils/format.py +1 -5
  152. reflex/utils/imports.py +5 -12
  153. reflex/utils/misc.py +40 -0
  154. reflex/utils/prerequisites.py +7 -12
  155. reflex/utils/processes.py +8 -41
  156. reflex/utils/pyi_generator.py +23 -40
  157. reflex/utils/telemetry.py +0 -15
  158. reflex/utils/types.py +1 -1
  159. {reflex-0.8.0a4.dist-info → reflex-0.8.0a6.dist-info}/METADATA +3 -3
  160. {reflex-0.8.0a4.dist-info → reflex-0.8.0a6.dist-info}/RECORD +163 -163
  161. {reflex-0.8.0a4.dist-info → reflex-0.8.0a6.dist-info}/WHEEL +0 -0
  162. {reflex-0.8.0a4.dist-info → reflex-0.8.0a6.dist-info}/entry_points.txt +0 -0
  163. {reflex-0.8.0a4.dist-info → reflex-0.8.0a6.dist-info}/licenses/LICENSE +0 -0
reflex/utils/processes.py CHANGED
@@ -4,17 +4,17 @@ from __future__ import annotations
4
4
 
5
5
  import collections
6
6
  import contextlib
7
- import importlib.metadata
8
7
  import os
9
8
  import signal
9
+ import socket
10
10
  import subprocess
11
11
  from collections.abc import Callable, Generator, Sequence
12
12
  from concurrent import futures
13
+ from contextlib import closing
13
14
  from pathlib import Path
14
15
  from typing import Any, Literal, overload
15
16
 
16
17
  import click
17
- import psutil
18
18
  from redis.exceptions import RedisError
19
19
  from rich.progress import Progress
20
20
 
@@ -52,29 +52,6 @@ def get_num_workers() -> int:
52
52
  return (os.cpu_count() or 1) * 2 + 1
53
53
 
54
54
 
55
- def get_process_on_port(port: int) -> psutil.Process | None:
56
- """Get the process on the given port.
57
-
58
- Args:
59
- port: The port.
60
-
61
- Returns:
62
- The process on the given port.
63
- """
64
- for proc in psutil.process_iter(["pid", "name", "cmdline"]):
65
- with contextlib.suppress(
66
- psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess
67
- ):
68
- if importlib.metadata.version("psutil") >= "6.0.0":
69
- conns = proc.net_connections(kind="inet")
70
- else:
71
- conns = proc.connections(kind="inet")
72
- for conn in conns:
73
- if conn.laddr.port == int(port):
74
- return proc
75
- return None
76
-
77
-
78
55
  def is_process_on_port(port: int) -> bool:
79
56
  """Check if a process is running on the given port.
80
57
 
@@ -84,18 +61,8 @@ def is_process_on_port(port: int) -> bool:
84
61
  Returns:
85
62
  Whether a process is running on the given port.
86
63
  """
87
- return get_process_on_port(port) is not None
88
-
89
-
90
- def kill_process_on_port(port: int):
91
- """Kill the process on the given port.
92
-
93
- Args:
94
- port: The port.
95
- """
96
- if get_process_on_port(port) is not None:
97
- with contextlib.suppress(psutil.AccessDenied):
98
- get_process_on_port(port).kill() # pyright: ignore [reportOptionalMemberAccess]
64
+ with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
65
+ return sock.connect_ex(("127.0.0.1", port)) == 0
99
66
 
100
67
 
101
68
  def change_port(port: int, _type: str) -> int:
@@ -133,13 +100,13 @@ def handle_port(service_name: str, port: int, auto_increment: bool) -> int:
133
100
  Raises:
134
101
  Exit:when the port is in use.
135
102
  """
136
- if (process := get_process_on_port(port)) is None:
103
+ console.debug(f"Checking if {service_name.capitalize()} port: {port} is in use.")
104
+ if not is_process_on_port(port):
105
+ console.debug(f"{service_name.capitalize()} port: {port} is not in use.")
137
106
  return port
138
107
  if auto_increment:
139
108
  return change_port(port, service_name)
140
- console.error(
141
- f"{service_name.capitalize()} port: {port} is already in use by PID: {process.pid}."
142
- )
109
+ console.error(f"{service_name.capitalize()} port: {port} is already in use.")
143
110
  raise click.exceptions.Exit
144
111
 
145
112
 
@@ -13,7 +13,6 @@ import subprocess
13
13
  import sys
14
14
  import typing
15
15
  from collections.abc import Callable, Iterable, Sequence
16
- from fileinput import FileInput
17
16
  from hashlib import md5
18
17
  from inspect import getfullargspec
19
18
  from itertools import chain
@@ -67,7 +66,6 @@ OVERWRITE_TYPES = {
67
66
  }
68
67
 
69
68
  DEFAULT_TYPING_IMPORTS = {
70
- "overload",
71
69
  "Any",
72
70
  "Callable",
73
71
  "Dict",
@@ -677,10 +675,7 @@ def _generate_component_create_functiondef(
677
675
  value=ast.Constant(value=Ellipsis),
678
676
  ),
679
677
  ],
680
- decorator_list=[
681
- ast.Name(id="overload"),
682
- *decorator_list,
683
- ],
678
+ decorator_list=list(decorator_list),
684
679
  lineno=lineno,
685
680
  returns=ast.Constant(value=clz.__name__),
686
681
  )
@@ -896,7 +891,7 @@ class StubGenerator(ast.NodeTransformer):
896
891
  The modified ImportFrom node.
897
892
  """
898
893
  if node.module == "__future__":
899
- return None # ignore __future__ imports
894
+ return None # ignore __future__ imports: https://docs.astral.sh/ruff/rules/future-annotations-in-stub/
900
895
  return self.visit_Import(node)
901
896
 
902
897
  def visit_ClassDef(self, node: ast.ClassDef) -> ast.ClassDef:
@@ -1109,9 +1104,10 @@ class PyiGenerator:
1109
1104
 
1110
1105
  def _get_init_lazy_imports(self, mod: tuple | ModuleType, new_tree: ast.AST):
1111
1106
  # retrieve the _SUBMODULES and _SUBMOD_ATTRS from an init file if present.
1112
- sub_mods = getattr(mod, "_SUBMODULES", None)
1113
- sub_mod_attrs = getattr(mod, "_SUBMOD_ATTRS", None)
1114
- pyright_ignore_imports = getattr(mod, "_PYRIGHT_IGNORE_IMPORTS", [])
1107
+ sub_mods: set[str] | None = getattr(mod, "_SUBMODULES", None)
1108
+ sub_mod_attrs: dict[str, list[str | tuple[str, str]]] | None = getattr(
1109
+ mod, "_SUBMOD_ATTRS", None
1110
+ )
1115
1111
 
1116
1112
  if not sub_mods and not sub_mod_attrs:
1117
1113
  return None
@@ -1119,31 +1115,34 @@ class PyiGenerator:
1119
1115
  sub_mod_attrs_imports = []
1120
1116
 
1121
1117
  if sub_mods:
1122
- sub_mods_imports = [
1123
- f"from . import {mod} as {mod}" for mod in sorted(sub_mods)
1124
- ]
1118
+ sub_mods_imports = [f"from . import {mod}" for mod in sorted(sub_mods)]
1125
1119
  sub_mods_imports.append("")
1126
1120
 
1127
1121
  if sub_mod_attrs:
1128
- sub_mod_attrs = {
1129
- attr: mod for mod, attrs in sub_mod_attrs.items() for attr in attrs
1122
+ flattened_sub_mod_attrs = {
1123
+ imported: module
1124
+ for module, attrs in sub_mod_attrs.items()
1125
+ for imported in attrs
1130
1126
  }
1131
1127
  # construct the import statement and handle special cases for aliases
1132
1128
  sub_mod_attrs_imports = [
1133
- f"from .{path} import {mod if not isinstance(mod, tuple) else mod[0]} as {mod if not isinstance(mod, tuple) else mod[1]}"
1129
+ f"from .{module} import "
1134
1130
  + (
1135
- " # type: ignore"
1136
- if mod in pyright_ignore_imports
1137
- else " # noqa: F401" # ignore ruff formatting here for cases like rx.list.
1138
- if isinstance(mod, tuple)
1139
- else ""
1131
+ (
1132
+ (imported[0] + " as " + imported[1])
1133
+ if imported[0] != imported[1]
1134
+ else imported[0]
1135
+ )
1136
+ if isinstance(imported, tuple)
1137
+ else imported
1140
1138
  )
1141
- for mod, path in sub_mod_attrs.items()
1139
+ for imported, module in flattened_sub_mod_attrs.items()
1142
1140
  ]
1143
1141
  sub_mod_attrs_imports.append("")
1144
1142
 
1145
1143
  text = "\n" + "\n".join([*sub_mods_imports, *sub_mod_attrs_imports])
1146
- text += ast.unparse(new_tree) + "\n"
1144
+ text += ast.unparse(new_tree) + "\n\n"
1145
+ text += f"__all__ = {getattr(mod, '__all__', [])!r}\n"
1147
1146
  return text
1148
1147
 
1149
1148
  def _scan_file(self, module_path: Path) -> tuple[str, str] | None:
@@ -1258,10 +1257,7 @@ class PyiGenerator:
1258
1257
  if file_paths:
1259
1258
  subprocess.run(["ruff", "format", *file_paths])
1260
1259
  subprocess.run(["ruff", "check", "--fix", *file_paths])
1261
-
1262
- # For some reason, we need to format the __init__.pyi files again after fixing...
1263
- init_files = [f for f in file_paths if "/__init__.pyi" in f]
1264
- subprocess.run(["ruff", "format", *init_files])
1260
+ subprocess.run(["ruff", "format", *file_paths])
1265
1261
 
1266
1262
  if use_json:
1267
1263
  if file_paths and changed_files is None:
@@ -1327,19 +1323,6 @@ class PyiGenerator:
1327
1323
  json.dumps(pyi_hashes, indent=2, sort_keys=True) + "\n"
1328
1324
  )
1329
1325
 
1330
- # Post-process the generated pyi files to add hacky type: ignore comments
1331
- for file_path in file_paths:
1332
- with FileInput(file_path, inplace=True) as f:
1333
- for line in f:
1334
- # Hack due to ast not supporting comments in the tree.
1335
- if (
1336
- "def create(" in line
1337
- or "Var[Figure]" in line
1338
- or "Var[Template]" in line
1339
- ):
1340
- line = line.rstrip() + " # type: ignore\n"
1341
- print(line, end="") # noqa: T201
1342
-
1343
1326
 
1344
1327
  if __name__ == "__main__":
1345
1328
  import argparse
reflex/utils/telemetry.py CHANGED
@@ -13,7 +13,6 @@ from datetime import datetime, timezone
13
13
  from typing import TypedDict
14
14
 
15
15
  import httpx
16
- import psutil
17
16
 
18
17
  from reflex import constants
19
18
  from reflex.environment import environment
@@ -89,18 +88,6 @@ def get_reflex_enterprise_version() -> str | None:
89
88
  return None
90
89
 
91
90
 
92
- def get_memory() -> int:
93
- """Get the total memory in MB.
94
-
95
- Returns:
96
- The total memory in MB.
97
- """
98
- try:
99
- return psutil.virtual_memory().total >> 20
100
- except ValueError: # needed to pass ubuntu test
101
- return 0
102
-
103
-
104
91
  def _raise_on_missing_project_hash() -> bool:
105
92
  """Check if an error should be raised when project hash is missing.
106
93
 
@@ -128,7 +115,6 @@ class _Properties(TypedDict):
128
115
  bun_version: str | None
129
116
  reflex_enterprise_version: str | None
130
117
  cpu_count: int
131
- memory: int
132
118
  cpu_info: dict
133
119
 
134
120
 
@@ -182,7 +168,6 @@ def _get_event_defaults() -> _DefaultEvent | None:
182
168
  ),
183
169
  "reflex_enterprise_version": get_reflex_enterprise_version(),
184
170
  "cpu_count": get_cpu_count(),
185
- "memory": get_memory(),
186
171
  "cpu_info": dataclasses.asdict(cpuinfo) if cpuinfo else {},
187
172
  },
188
173
  }
reflex/utils/types.py CHANGED
@@ -495,7 +495,7 @@ def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None
495
495
  return list[
496
496
  get_attribute_access_type(
497
497
  attr.target_class,
498
- attr.remote_attr.key, # type: ignore[attr-defined]
498
+ attr.remote_attr.key, # pyright: ignore [reportAttributeAccessIssue]
499
499
  )
500
500
  ]
501
501
  elif isinstance(cls, type) and not is_generic_alias(cls) and issubclass(cls, Model):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reflex
3
- Version: 0.8.0a4
3
+ Version: 0.8.0a6
4
4
  Summary: Web apps in pure Python.
5
5
  Project-URL: homepage, https://reflex.dev
6
6
  Project-URL: repository, https://github.com/reflex-dev/reflex
@@ -19,14 +19,14 @@ Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Programming Language :: Python :: 3.13
20
20
  Requires-Python: <4.0,>=3.10
21
21
  Requires-Dist: alembic<2.0,>=1.15.2
22
- Requires-Dist: click>=8
22
+ Requires-Dist: click>=8.2
23
23
  Requires-Dist: fastapi>=0.115.0
24
24
  Requires-Dist: granian[reload]>=2.2.5
25
25
  Requires-Dist: httpx<1.0,>=0.28.0
26
26
  Requires-Dist: jinja2<4.0,>=3.1.2
27
27
  Requires-Dist: packaging<26,>=24.2
28
28
  Requires-Dist: platformdirs<5.0,>=4.3.7
29
- Requires-Dist: psutil<8.0,>=7.0.0
29
+ Requires-Dist: psutil<8.0,>=7.0.0; sys_platform == 'win32'
30
30
  Requires-Dist: pydantic<3.0,>=1.10.21
31
31
  Requires-Dist: python-multipart<1.0,>=0.0.20
32
32
  Requires-Dist: python-socketio<6.0,>=5.12.0