reflex 0.5.2a1__py3-none-any.whl → 0.5.3__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 (166) hide show
  1. reflex/.templates/web/postcss.config.js +1 -0
  2. reflex/.templates/web/styles/tailwind.css +4 -1
  3. reflex/__init__.py +298 -204
  4. reflex/__init__.pyi +196 -157
  5. reflex/app.py +13 -2
  6. reflex/compiler/compiler.py +1 -1
  7. reflex/components/__init__.py +31 -17
  8. reflex/components/__init__.pyi +26 -0
  9. reflex/components/base/__init__.py +25 -9
  10. reflex/components/base/__init__.pyi +26 -0
  11. reflex/components/base/fragment.py +3 -0
  12. reflex/components/base/fragment.pyi +2 -0
  13. reflex/components/base/head.py +3 -0
  14. reflex/components/base/head.pyi +2 -0
  15. reflex/components/base/script.py +3 -0
  16. reflex/components/base/script.pyi +2 -0
  17. reflex/components/core/__init__.py +51 -37
  18. reflex/components/core/__init__.pyi +39 -0
  19. reflex/components/core/banner.py +7 -1
  20. reflex/components/core/banner.pyi +6 -1
  21. reflex/components/core/debounce.py +3 -0
  22. reflex/components/core/debounce.pyi +2 -0
  23. reflex/components/core/foreach.py +3 -0
  24. reflex/components/core/html.py +4 -1
  25. reflex/components/core/html.pyi +2 -0
  26. reflex/components/core/match.py +3 -0
  27. reflex/components/core/responsive.py +1 -1
  28. reflex/components/core/upload.py +5 -2
  29. reflex/components/core/upload.pyi +4 -2
  30. reflex/components/datadisplay/__init__.py +17 -8
  31. reflex/components/datadisplay/__init__.pyi +14 -0
  32. reflex/components/datadisplay/code.py +3 -0
  33. reflex/components/datadisplay/code.pyi +2 -0
  34. reflex/components/datadisplay/dataeditor.py +4 -0
  35. reflex/components/datadisplay/dataeditor.pyi +3 -0
  36. reflex/components/el/__init__.py +15 -1
  37. reflex/components/el/__init__.pyi +228 -0
  38. reflex/components/el/elements/__init__.py +129 -220
  39. reflex/components/el/elements/__init__.pyi +342 -0
  40. reflex/components/el/elements/forms.py +15 -0
  41. reflex/components/el/elements/forms.pyi +14 -0
  42. reflex/components/el/elements/inline.py +30 -0
  43. reflex/components/el/elements/inline.pyi +29 -0
  44. reflex/components/el/elements/media.py +16 -0
  45. reflex/components/el/elements/media.pyi +15 -0
  46. reflex/components/el/elements/metadata.py +7 -0
  47. reflex/components/el/elements/metadata.pyi +6 -0
  48. reflex/components/el/elements/other.py +9 -0
  49. reflex/components/el/elements/other.pyi +8 -0
  50. reflex/components/el/elements/scripts.py +5 -0
  51. reflex/components/el/elements/scripts.pyi +4 -0
  52. reflex/components/el/elements/sectioning.py +17 -0
  53. reflex/components/el/elements/sectioning.pyi +16 -0
  54. reflex/components/el/elements/tables.py +12 -0
  55. reflex/components/el/elements/tables.pyi +11 -0
  56. reflex/components/el/elements/typography.py +16 -0
  57. reflex/components/el/elements/typography.pyi +15 -0
  58. reflex/components/moment/__init__.py +1 -1
  59. reflex/components/plotly/plotly.py +185 -7
  60. reflex/components/plotly/plotly.pyi +62 -4
  61. reflex/components/radix/__init__.py +14 -2
  62. reflex/components/radix/__init__.pyi +73 -0
  63. reflex/components/radix/primitives/__init__.py +13 -5
  64. reflex/components/radix/primitives/__init__.pyi +11 -0
  65. reflex/components/radix/themes/__init__.py +20 -6
  66. reflex/components/radix/themes/__init__.pyi +13 -0
  67. reflex/components/radix/themes/base.py +26 -20
  68. reflex/components/radix/themes/base.pyi +4 -1
  69. reflex/components/radix/themes/color_mode.py +3 -1
  70. reflex/components/radix/themes/color_mode.pyi +3 -1
  71. reflex/components/radix/themes/components/__init__.py +11 -79
  72. reflex/components/radix/themes/components/__init__.pyi +44 -0
  73. reflex/components/radix/themes/components/alert_dialog.py +2 -2
  74. reflex/components/radix/themes/components/alert_dialog.pyi +2 -2
  75. reflex/components/radix/themes/components/badge.py +2 -2
  76. reflex/components/radix/themes/components/badge.pyi +2 -2
  77. reflex/components/radix/themes/components/button.py +2 -2
  78. reflex/components/radix/themes/components/button.pyi +2 -2
  79. reflex/components/radix/themes/components/callout.py +4 -4
  80. reflex/components/radix/themes/components/callout.pyi +4 -4
  81. reflex/components/radix/themes/components/card.py +2 -2
  82. reflex/components/radix/themes/components/card.pyi +2 -2
  83. reflex/components/radix/themes/components/dialog.py +2 -2
  84. reflex/components/radix/themes/components/dialog.pyi +2 -2
  85. reflex/components/radix/themes/components/hover_card.py +2 -2
  86. reflex/components/radix/themes/components/hover_card.pyi +2 -2
  87. reflex/components/radix/themes/components/icon_button.py +2 -2
  88. reflex/components/radix/themes/components/icon_button.pyi +2 -2
  89. reflex/components/radix/themes/components/inset.py +2 -2
  90. reflex/components/radix/themes/components/inset.pyi +2 -2
  91. reflex/components/radix/themes/components/popover.py +2 -2
  92. reflex/components/radix/themes/components/popover.pyi +2 -2
  93. reflex/components/radix/themes/components/table.py +8 -8
  94. reflex/components/radix/themes/components/table.pyi +8 -8
  95. reflex/components/radix/themes/components/text_area.py +11 -2
  96. reflex/components/radix/themes/components/text_area.pyi +18 -3
  97. reflex/components/radix/themes/components/text_field.py +3 -3
  98. reflex/components/radix/themes/components/text_field.pyi +3 -3
  99. reflex/components/radix/themes/layout/__init__.py +12 -38
  100. reflex/components/radix/themes/layout/__init__.pyi +21 -0
  101. reflex/components/radix/themes/layout/box.py +5 -2
  102. reflex/components/radix/themes/layout/box.pyi +4 -2
  103. reflex/components/radix/themes/layout/center.py +3 -0
  104. reflex/components/radix/themes/layout/center.pyi +2 -0
  105. reflex/components/radix/themes/layout/container.py +5 -2
  106. reflex/components/radix/themes/layout/container.pyi +4 -2
  107. reflex/components/radix/themes/layout/flex.py +5 -2
  108. reflex/components/radix/themes/layout/flex.pyi +4 -2
  109. reflex/components/radix/themes/layout/grid.py +5 -2
  110. reflex/components/radix/themes/layout/grid.pyi +4 -2
  111. reflex/components/radix/themes/layout/list.py +14 -0
  112. reflex/components/radix/themes/layout/list.pyi +3 -0
  113. reflex/components/radix/themes/layout/section.py +7 -4
  114. reflex/components/radix/themes/layout/section.pyi +5 -3
  115. reflex/components/radix/themes/layout/spacer.py +3 -0
  116. reflex/components/radix/themes/layout/spacer.pyi +2 -0
  117. reflex/components/radix/themes/layout/stack.py +5 -0
  118. reflex/components/radix/themes/layout/stack.pyi +4 -0
  119. reflex/components/radix/themes/typography/__init__.py +11 -16
  120. reflex/components/radix/themes/typography/__init__.pyi +12 -0
  121. reflex/components/radix/themes/typography/blockquote.py +5 -2
  122. reflex/components/radix/themes/typography/blockquote.pyi +4 -2
  123. reflex/components/radix/themes/typography/code.py +5 -2
  124. reflex/components/radix/themes/typography/code.pyi +4 -2
  125. reflex/components/radix/themes/typography/heading.py +5 -2
  126. reflex/components/radix/themes/typography/heading.pyi +4 -2
  127. reflex/components/radix/themes/typography/link.py +3 -0
  128. reflex/components/radix/themes/typography/link.pyi +2 -0
  129. reflex/components/radix/themes/typography/text.py +6 -6
  130. reflex/components/radix/themes/typography/text.pyi +6 -6
  131. reflex/components/recharts/__init__.py +114 -104
  132. reflex/components/recharts/__init__.pyi +106 -0
  133. reflex/components/recharts/cartesian.py +17 -0
  134. reflex/components/recharts/cartesian.pyi +16 -0
  135. reflex/components/recharts/charts.py +12 -0
  136. reflex/components/recharts/charts.pyi +11 -0
  137. reflex/components/recharts/general.py +7 -0
  138. reflex/components/recharts/general.pyi +6 -0
  139. reflex/components/recharts/polar.py +11 -0
  140. reflex/components/recharts/polar.pyi +9 -0
  141. reflex/config.py +3 -0
  142. reflex/constants/__init__.py +0 -2
  143. reflex/constants/base.py +5 -1
  144. reflex/constants/installer.py +2 -1
  145. reflex/experimental/__init__.py +2 -0
  146. reflex/experimental/assets.py +56 -0
  147. reflex/experimental/client_state.py +4 -2
  148. reflex/experimental/hooks.py +8 -6
  149. reflex/experimental/layout.py +3 -1
  150. reflex/state.py +54 -4
  151. reflex/utils/exec.py +8 -0
  152. reflex/utils/format.py +8 -4
  153. reflex/utils/lazy_loader.py +33 -0
  154. reflex/utils/prerequisites.py +1 -14
  155. reflex/utils/pyi_generator.py +71 -20
  156. reflex/utils/serializers.py +9 -4
  157. reflex/utils/types.py +3 -1
  158. reflex/vars.py +92 -6
  159. reflex/vars.pyi +16 -0
  160. {reflex-0.5.2a1.dist-info → reflex-0.5.3.dist-info}/METADATA +2 -1
  161. {reflex-0.5.2a1.dist-info → reflex-0.5.3.dist-info}/RECORD +164 -151
  162. reflex/config.pyi +0 -112
  163. reflex/constants/base.pyi +0 -94
  164. {reflex-0.5.2a1.dist-info → reflex-0.5.3.dist-info}/LICENSE +0 -0
  165. {reflex-0.5.2a1.dist-info → reflex-0.5.3.dist-info}/WHEEL +0 -0
  166. {reflex-0.5.2a1.dist-info → reflex-0.5.3.dist-info}/entry_points.txt +0 -0
reflex/vars.py CHANGED
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import contextlib
6
6
  import dataclasses
7
+ import datetime
7
8
  import dis
8
9
  import functools
9
10
  import inspect
@@ -34,7 +35,7 @@ from typing import (
34
35
 
35
36
  from reflex import constants
36
37
  from reflex.base import Base
37
- from reflex.utils import console, format, imports, serializers, types
38
+ from reflex.utils import console, imports, serializers, types
38
39
  from reflex.utils.exceptions import VarAttributeError, VarTypeError, VarValueError
39
40
 
40
41
  # This module used to export ImportVar itself, so we still import it for export here
@@ -363,6 +364,8 @@ class Var:
363
364
  Raises:
364
365
  VarTypeError: If the value is JSON-unserializable.
365
366
  """
367
+ from reflex.utils import format
368
+
366
369
  # Check for none values.
367
370
  if value is None:
368
371
  return None
@@ -542,6 +545,8 @@ class Var:
542
545
  Returns:
543
546
  The wrapped var, i.e. {state.var}.
544
547
  """
548
+ from reflex.utils import format
549
+
545
550
  out = (
546
551
  self._var_full_name
547
552
  if self._var_is_local
@@ -599,6 +604,8 @@ class Var:
599
604
  Raises:
600
605
  VarTypeError: If the var is not indexable.
601
606
  """
607
+ from reflex.utils import format
608
+
602
609
  # Indexing is only supported for strings, lists, tuples, dicts, and dataframes.
603
610
  if not (
604
611
  types._issubclass(self._var_type, Union[List, Dict, Tuple, str])
@@ -792,6 +799,8 @@ class Var:
792
799
  VarTypeError: If the operation between two operands is invalid.
793
800
  VarValueError: If flip is set to true and value of operand is not provided
794
801
  """
802
+ from reflex.utils import format
803
+
795
804
  if isinstance(other, str):
796
805
  other = Var.create(json.dumps(other))
797
806
  else:
@@ -1670,6 +1679,8 @@ class Var:
1670
1679
  Returns:
1671
1680
  The full name of the var.
1672
1681
  """
1682
+ from reflex.utils import format
1683
+
1673
1684
  if not self._var_full_name_needs_state_prefix:
1674
1685
  return self._var_name
1675
1686
  return (
@@ -1689,6 +1700,8 @@ class Var:
1689
1700
  Returns:
1690
1701
  The var with the set state.
1691
1702
  """
1703
+ from reflex.utils import format
1704
+
1692
1705
  state_name = state if isinstance(state, str) else state.get_full_name()
1693
1706
  new_var_data = VarData(
1694
1707
  state=state_name,
@@ -1873,13 +1886,26 @@ class ComputedVar(Var, property):
1873
1886
  # Whether to track dependencies and cache computed values
1874
1887
  _cache: bool = dataclasses.field(default=False)
1875
1888
 
1876
- _initial_value: Any | types.Unset = dataclasses.field(default_factory=types.Unset)
1889
+ # The initial value of the computed var
1890
+ _initial_value: Any | types.Unset = dataclasses.field(default=types.Unset())
1891
+
1892
+ # Explicit var dependencies to track
1893
+ _static_deps: set[str] = dataclasses.field(default_factory=set)
1894
+
1895
+ # Whether var dependencies should be auto-determined
1896
+ _auto_deps: bool = dataclasses.field(default=True)
1897
+
1898
+ # Interval at which the computed var should be updated
1899
+ _update_interval: Optional[datetime.timedelta] = dataclasses.field(default=None)
1877
1900
 
1878
1901
  def __init__(
1879
1902
  self,
1880
1903
  fget: Callable[[BaseState], Any],
1881
1904
  initial_value: Any | types.Unset = types.Unset(),
1882
1905
  cache: bool = False,
1906
+ deps: Optional[List[Union[str, Var]]] = None,
1907
+ auto_deps: bool = True,
1908
+ interval: Optional[Union[int, datetime.timedelta]] = None,
1883
1909
  **kwargs,
1884
1910
  ):
1885
1911
  """Initialize a ComputedVar.
@@ -1888,10 +1914,22 @@ class ComputedVar(Var, property):
1888
1914
  fget: The getter function.
1889
1915
  initial_value: The initial value of the computed var.
1890
1916
  cache: Whether to cache the computed value.
1917
+ deps: Explicit var dependencies to track.
1918
+ auto_deps: Whether var dependencies should be auto-determined.
1919
+ interval: Interval at which the computed var should be updated.
1891
1920
  **kwargs: additional attributes to set on the instance
1892
1921
  """
1893
1922
  self._initial_value = initial_value
1894
1923
  self._cache = cache
1924
+ if isinstance(interval, int):
1925
+ interval = datetime.timedelta(seconds=interval)
1926
+ self._update_interval = interval
1927
+ if deps is None:
1928
+ deps = []
1929
+ self._static_deps = {
1930
+ dep._var_name if isinstance(dep, Var) else dep for dep in deps
1931
+ }
1932
+ self._auto_deps = auto_deps
1895
1933
  property.__init__(self, fget)
1896
1934
  kwargs["_var_name"] = kwargs.pop("_var_name", fget.__name__)
1897
1935
  kwargs["_var_type"] = kwargs.pop("_var_type", self._determine_var_type())
@@ -1912,6 +1950,9 @@ class ComputedVar(Var, property):
1912
1950
  fget=kwargs.get("fget", self.fget),
1913
1951
  initial_value=kwargs.get("initial_value", self._initial_value),
1914
1952
  cache=kwargs.get("cache", self._cache),
1953
+ deps=kwargs.get("deps", self._static_deps),
1954
+ auto_deps=kwargs.get("auto_deps", self._auto_deps),
1955
+ interval=kwargs.get("interval", self._update_interval),
1915
1956
  _var_name=kwargs.get("_var_name", self._var_name),
1916
1957
  _var_type=kwargs.get("_var_type", self._var_type),
1917
1958
  _var_is_local=kwargs.get("_var_is_local", self._var_is_local),
@@ -1932,7 +1973,32 @@ class ComputedVar(Var, property):
1932
1973
  """
1933
1974
  return f"__cached_{self._var_name}"
1934
1975
 
1935
- def __get__(self, instance, owner):
1976
+ @property
1977
+ def _last_updated_attr(self) -> str:
1978
+ """Get the attribute used to store the last updated timestamp.
1979
+
1980
+ Returns:
1981
+ An attribute name.
1982
+ """
1983
+ return f"__last_updated_{self._var_name}"
1984
+
1985
+ def needs_update(self, instance: BaseState) -> bool:
1986
+ """Check if the computed var needs to be updated.
1987
+
1988
+ Args:
1989
+ instance: The state instance that the computed var is attached to.
1990
+
1991
+ Returns:
1992
+ True if the computed var needs to be updated, False otherwise.
1993
+ """
1994
+ if self._update_interval is None:
1995
+ return False
1996
+ last_updated = getattr(instance, self._last_updated_attr, None)
1997
+ if last_updated is None:
1998
+ return True
1999
+ return datetime.datetime.now() - last_updated > self._update_interval
2000
+
2001
+ def __get__(self, instance: BaseState | None, owner):
1936
2002
  """Get the ComputedVar value.
1937
2003
 
1938
2004
  If the value is already cached on the instance, return the cached value.
@@ -1948,10 +2014,13 @@ class ComputedVar(Var, property):
1948
2014
  return super().__get__(instance, owner)
1949
2015
 
1950
2016
  # handle caching
1951
- if not hasattr(instance, self._cache_attr):
2017
+ if not hasattr(instance, self._cache_attr) or self.needs_update(instance):
2018
+ # Set cache attr on state instance.
1952
2019
  setattr(instance, self._cache_attr, super().__get__(instance, owner))
1953
2020
  # Ensure the computed var gets serialized to redis.
1954
2021
  instance._was_touched = True
2022
+ # Set the last updated timestamp on the state instance.
2023
+ setattr(instance, self._last_updated_attr, datetime.datetime.now())
1955
2024
  return getattr(instance, self._cache_attr)
1956
2025
 
1957
2026
  def _deps(
@@ -1978,7 +2047,9 @@ class ComputedVar(Var, property):
1978
2047
  VarValueError: if the function references the get_state, parent_state, or substates attributes
1979
2048
  (cannot track deps in a related state, only implicitly via parent state).
1980
2049
  """
1981
- d = set()
2050
+ if not self._auto_deps:
2051
+ return self._static_deps
2052
+ d = self._static_deps.copy()
1982
2053
  if obj is None:
1983
2054
  fget = property.__getattribute__(self, "fget")
1984
2055
  if fget is not None:
@@ -2076,6 +2147,9 @@ def computed_var(
2076
2147
  fget: Callable[[BaseState], Any] | None = None,
2077
2148
  initial_value: Any | None = None,
2078
2149
  cache: bool = False,
2150
+ deps: Optional[List[Union[str, Var]]] = None,
2151
+ auto_deps: bool = True,
2152
+ interval: Optional[Union[datetime.timedelta, int]] = None,
2079
2153
  **kwargs,
2080
2154
  ) -> ComputedVar | Callable[[Callable[[BaseState], Any]], ComputedVar]:
2081
2155
  """A ComputedVar decorator with or without kwargs.
@@ -2084,19 +2158,31 @@ def computed_var(
2084
2158
  fget: The getter function.
2085
2159
  initial_value: The initial value of the computed var.
2086
2160
  cache: Whether to cache the computed value.
2161
+ deps: Explicit var dependencies to track.
2162
+ auto_deps: Whether var dependencies should be auto-determined.
2163
+ interval: Interval at which the computed var should be updated.
2087
2164
  **kwargs: additional attributes to set on the instance
2088
2165
 
2089
2166
  Returns:
2090
2167
  A ComputedVar instance.
2168
+
2169
+ Raises:
2170
+ ValueError: If caching is disabled and an update interval is set.
2091
2171
  """
2172
+ if cache is False and interval is not None:
2173
+ raise ValueError("Cannot set update interval without caching.")
2174
+
2092
2175
  if fget is not None:
2093
2176
  return ComputedVar(fget=fget, cache=cache)
2094
2177
 
2095
- def wrapper(fget):
2178
+ def wrapper(fget: Callable[[BaseState], Any]) -> ComputedVar:
2096
2179
  return ComputedVar(
2097
2180
  fget=fget,
2098
2181
  initial_value=initial_value,
2099
2182
  cache=cache,
2183
+ deps=deps,
2184
+ auto_deps=auto_deps,
2185
+ interval=interval,
2100
2186
  **kwargs,
2101
2187
  )
2102
2188
 
reflex/vars.pyi CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import datetime
5
6
  from dataclasses import dataclass
6
7
  from _typeshed import Incomplete
7
8
  from reflex import constants as constants
@@ -141,6 +142,7 @@ class ComputedVar(Var):
141
142
  def _deps(self, objclass: Type, obj: Optional[FunctionType] = ...) -> Set[str]: ...
142
143
  def _replace(self, merge_var_data=None, **kwargs: Any) -> ComputedVar: ...
143
144
  def mark_dirty(self, instance) -> None: ...
145
+ def needs_update(self, instance) -> bool: ...
144
146
  def _determine_var_type(self) -> Type: ...
145
147
  @overload
146
148
  def __init__(
@@ -155,10 +157,24 @@ class ComputedVar(Var):
155
157
  def computed_var(
156
158
  fget: Callable[[BaseState], Any] | None = None,
157
159
  initial_value: Any | None = None,
160
+ cache: bool = False,
161
+ deps: Optional[List[Union[str, Var]]] = None,
162
+ auto_deps: bool = True,
163
+ interval: Optional[Union[datetime.timedelta, int]] = None,
158
164
  **kwargs,
159
165
  ) -> Callable[[Callable[[Any], Any]], ComputedVar]: ...
160
166
  @overload
161
167
  def computed_var(fget: Callable[[Any], Any]) -> ComputedVar: ...
168
+ @overload
169
+ def cached_var(
170
+ fget: Callable[[BaseState], Any] | None = None,
171
+ initial_value: Any | None = None,
172
+ deps: Optional[List[Union[str, Var]]] = None,
173
+ auto_deps: bool = True,
174
+ interval: Optional[Union[datetime.timedelta, int]] = None,
175
+ **kwargs,
176
+ ) -> Callable[[Callable[[Any], Any]], ComputedVar]: ...
177
+ @overload
162
178
  def cached_var(fget: Callable[[Any], Any]) -> ComputedVar: ...
163
179
 
164
180
  class CallableVar(BaseVar):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: reflex
3
- Version: 0.5.2a1
3
+ Version: 0.5.3
4
4
  Summary: Web apps in pure Python.
5
5
  Home-page: https://reflex.dev
6
6
  License: Apache-2.0
@@ -25,6 +25,7 @@ Requires-Dist: fastapi (>=0.96.0,<1.0)
25
25
  Requires-Dist: gunicorn (>=20.1.0,<23.0)
26
26
  Requires-Dist: httpx (>=0.25.1,<1.0)
27
27
  Requires-Dist: jinja2 (>=3.1.2,<4.0)
28
+ Requires-Dist: lazy_loader (>=0.4)
28
29
  Requires-Dist: packaging (>=23.1,<25.0)
29
30
  Requires-Dist: platformdirs (>=3.10.0,<5.0)
30
31
  Requires-Dist: psutil (>=5.9.4,<6.0)