reflex 0.7.6a0__py3-none-any.whl → 0.7.7__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.

@@ -64,6 +64,7 @@ _SUBMOD_ATTRS: dict = {
64
64
  "ResponsiveContainer",
65
65
  "legend",
66
66
  "Legend",
67
+ "tooltip",
67
68
  "graphing_tooltip",
68
69
  "GraphingTooltip",
69
70
  "label",
@@ -65,6 +65,7 @@ from .general import label as label
65
65
  from .general import label_list as label_list
66
66
  from .general import legend as legend
67
67
  from .general import responsive_container as responsive_container
68
+ from .general import tooltip as tooltip
68
69
  from .polar import Pie as Pie
69
70
  from .polar import PolarAngleAxis as PolarAngleAxis
70
71
  from .polar import PolarGrid as PolarGrid
@@ -259,7 +259,7 @@ class Cell(Recharts):
259
259
 
260
260
  responsive_container = ResponsiveContainer.create
261
261
  legend = Legend.create
262
- graphing_tooltip = GraphingTooltip.create
262
+ graphing_tooltip = tooltip = GraphingTooltip.create
263
263
  label = Label.create
264
264
  label_list = LabelList.create
265
265
  cell = Cell.create
@@ -533,7 +533,7 @@ class Cell(Recharts):
533
533
 
534
534
  responsive_container = ResponsiveContainer.create
535
535
  legend = Legend.create
536
- graphing_tooltip = GraphingTooltip.create
536
+ graphing_tooltip = tooltip = GraphingTooltip.create
537
537
  label = Label.create
538
538
  label_list = LabelList.create
539
539
  cell = Cell.create
reflex/event.py CHANGED
@@ -507,6 +507,7 @@ class JavascriptHTMLInputElement:
507
507
  """Interface for a Javascript HTMLInputElement https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement."""
508
508
 
509
509
  value: str = ""
510
+ checked: bool = False
510
511
 
511
512
 
512
513
  @dataclasses.dataclass(
@@ -545,6 +546,42 @@ def input_event(e: ObjectVar[JavascriptInputEvent]) -> tuple[Var[str]]:
545
546
  return (e.target.value,)
546
547
 
547
548
 
549
+ def int_input_event(e: ObjectVar[JavascriptInputEvent]) -> tuple[Var[int]]:
550
+ """Get the value from an input event as an int.
551
+
552
+ Args:
553
+ e: The input event.
554
+
555
+ Returns:
556
+ The value from the input event as an int.
557
+ """
558
+ return (Var("Number").to(FunctionVar).call(e.target.value).to(int),)
559
+
560
+
561
+ def float_input_event(e: ObjectVar[JavascriptInputEvent]) -> tuple[Var[float]]:
562
+ """Get the value from an input event as a float.
563
+
564
+ Args:
565
+ e: The input event.
566
+
567
+ Returns:
568
+ The value from the input event as a float.
569
+ """
570
+ return (Var("Number").to(FunctionVar).call(e.target.value).to(float),)
571
+
572
+
573
+ def checked_input_event(e: ObjectVar[JavascriptInputEvent]) -> tuple[Var[bool]]:
574
+ """Get the checked state from an input event.
575
+
576
+ Args:
577
+ e: The input event.
578
+
579
+ Returns:
580
+ The checked state from the input event.
581
+ """
582
+ return (e.target.checked,)
583
+
584
+
548
585
  class KeyInputInfo(TypedDict):
549
586
  """Information about a key input event."""
550
587
 
reflex/reflex.py CHANGED
@@ -624,19 +624,23 @@ def deploy(
624
624
  hosting_cli.deploy(
625
625
  app_name=app_name,
626
626
  app_id=app_id,
627
- export_fn=lambda zip_dest_dir,
628
- api_url,
629
- deploy_url,
630
- frontend,
631
- backend,
632
- zipping: export_utils.export(
633
- zip_dest_dir=zip_dest_dir,
634
- api_url=api_url,
635
- deploy_url=deploy_url,
636
- frontend=frontend,
637
- backend=backend,
638
- zipping=zipping,
639
- loglevel=loglevel.subprocess_level(),
627
+ export_fn=(
628
+ lambda zip_dest_dir,
629
+ api_url,
630
+ deploy_url,
631
+ frontend,
632
+ backend,
633
+ upload_db,
634
+ zipping: export_utils.export(
635
+ zip_dest_dir=zip_dest_dir,
636
+ api_url=api_url,
637
+ deploy_url=deploy_url,
638
+ frontend=frontend,
639
+ backend=backend,
640
+ zipping=zipping,
641
+ loglevel=loglevel.subprocess_level(),
642
+ upload_db_file=upload_db,
643
+ )
640
644
  ),
641
645
  regions=regions,
642
646
  envs=envs,
reflex/state.py CHANGED
@@ -48,6 +48,7 @@ from pydantic.v1.fields import ModelField
48
48
  from redis.asyncio import Redis
49
49
  from redis.asyncio.client import PubSub
50
50
  from redis.exceptions import ResponseError
51
+ from rich.markup import escape
51
52
  from sqlalchemy.orm import DeclarativeBase
52
53
  from typing_extensions import Self
53
54
 
@@ -698,7 +699,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
698
699
 
699
700
  if not _isinstance(result, of_type, nested=1, treat_var_as_type=False):
700
701
  console.warn(
701
- f"Inline ComputedVar {f} expected type {of_type}, got {type(result)}. "
702
+ f"Inline ComputedVar {f} expected type {escape(str(of_type))}, got {type(result)}. "
702
703
  "You can specify expected type with `of_type` argument."
703
704
  )
704
705
 
@@ -1364,7 +1365,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
1364
1365
  field_type = _unwrap_field_type(true_type_for_pydantic_field(field))
1365
1366
  if not _isinstance(value, field_type, nested=1, treat_var_as_type=False):
1366
1367
  console.error(
1367
- f"Expected field '{type(self).__name__}.{name}' to receive type '{field_type}',"
1368
+ f"Expected field '{type(self).__name__}.{name}' to receive type '{escape(str(field_type))}',"
1368
1369
  f" but got '{value}' of type '{type(value)}'."
1369
1370
  )
1370
1371
 
reflex/utils/decorator.py CHANGED
@@ -18,6 +18,7 @@ def once(f: Callable[[], T]) -> Callable[[], T]:
18
18
  unset = object()
19
19
  value: object | T = unset
20
20
 
21
+ @functools.wraps(f)
21
22
  def wrapper() -> T:
22
23
  nonlocal value
23
24
  value = f() if value is unset else value
@@ -26,6 +27,26 @@ def once(f: Callable[[], T]) -> Callable[[], T]:
26
27
  return wrapper
27
28
 
28
29
 
30
+ def once_unless_none(f: Callable[[], T | None]) -> Callable[[], T | None]:
31
+ """A decorator that calls the function once and caches the result unless it is None.
32
+
33
+ Args:
34
+ f: The function to call.
35
+
36
+ Returns:
37
+ A function that calls the function once and caches the result unless it is None.
38
+ """
39
+ value: T | None = None
40
+
41
+ @functools.wraps(f)
42
+ def wrapper() -> T | None:
43
+ nonlocal value
44
+ value = f() if value is None else value
45
+ return value
46
+
47
+ return wrapper
48
+
49
+
29
50
  P = ParamSpec("P")
30
51
 
31
52
 
reflex/utils/export.py CHANGED
@@ -41,10 +41,10 @@ def export(
41
41
 
42
42
  # Override the config url values if provided.
43
43
  if api_url is not None:
44
- config.api_url = str(api_url)
44
+ config._set_persistent(api_url=str(api_url))
45
45
  console.debug(f"overriding API URL: {config.api_url}")
46
46
  if deploy_url is not None:
47
- config.deploy_url = str(deploy_url)
47
+ config._set_persistent(deploy_url=str(deploy_url))
48
48
  console.debug(f"overriding deploy URL: {config.deploy_url}")
49
49
 
50
50
  # Show system info
@@ -192,13 +192,16 @@ def get_node_version() -> version.Version | None:
192
192
  return None
193
193
 
194
194
 
195
- def get_bun_version() -> version.Version | None:
195
+ def get_bun_version(bun_path: Path | None = None) -> version.Version | None:
196
196
  """Get the version of bun.
197
197
 
198
+ Args:
199
+ bun_path: The path to the bun executable.
200
+
198
201
  Returns:
199
202
  The version of bun.
200
203
  """
201
- bun_path = path_ops.get_bun_path()
204
+ bun_path = bun_path or path_ops.get_bun_path()
202
205
  if bun_path is None:
203
206
  return None
204
207
  try:
@@ -1153,13 +1156,21 @@ def install_bun():
1153
1156
  "Creating project directories in OneDrive is not recommended for bun usage on windows. This will fallback to npm."
1154
1157
  )
1155
1158
 
1159
+ bun_path = path_ops.get_bun_path()
1160
+
1156
1161
  # Skip if bun is already installed.
1157
- if (current_version := get_bun_version()) and current_version >= version.parse(
1158
- constants.Bun.MIN_VERSION
1162
+ if (
1163
+ bun_path
1164
+ and (current_version := get_bun_version(bun_path=bun_path))
1165
+ and current_version >= version.parse(constants.Bun.MIN_VERSION)
1159
1166
  ):
1160
1167
  console.debug("Skipping bun installation as it is already installed.")
1161
1168
  return
1162
1169
 
1170
+ if bun_path and path_ops.use_system_bun():
1171
+ validate_bun(bun_path=bun_path)
1172
+ return
1173
+
1163
1174
  # if unzip is installed
1164
1175
  if constants.IS_WINDOWS:
1165
1176
  processes.new_process(
@@ -1394,13 +1405,16 @@ def is_latest_template() -> bool:
1394
1405
  return app_version == constants.Reflex.VERSION
1395
1406
 
1396
1407
 
1397
- def validate_bun():
1408
+ def validate_bun(bun_path: Path | None = None):
1398
1409
  """Validate bun if a custom bun path is specified to ensure the bun version meets requirements.
1399
1410
 
1411
+ Args:
1412
+ bun_path: The path to the bun executable. If None, the default bun path is used.
1413
+
1400
1414
  Raises:
1401
1415
  Exit: If custom specified bun does not exist or does not meet requirements.
1402
1416
  """
1403
- bun_path = path_ops.get_bun_path()
1417
+ bun_path = bun_path or path_ops.get_bun_path()
1404
1418
 
1405
1419
  if bun_path is None:
1406
1420
  return
@@ -1414,14 +1428,12 @@ def validate_bun():
1414
1428
  )
1415
1429
  raise typer.Exit(1)
1416
1430
  elif bun_version < version.parse(constants.Bun.MIN_VERSION):
1417
- console.error(
1431
+ console.warn(
1418
1432
  f"Reflex requires bun version {constants.Bun.MIN_VERSION} or higher to run, but the detected version is "
1419
1433
  f"{bun_version}. If you have specified a custom bun path in your config, make sure to provide one "
1420
- f"that satisfies the minimum version requirement."
1434
+ f"that satisfies the minimum version requirement. You can upgrade bun by running [bold]bun upgrade[/bold]."
1421
1435
  )
1422
1436
 
1423
- raise typer.Exit(1)
1424
-
1425
1437
 
1426
1438
  def validate_frontend_dependencies(init: bool = True):
1427
1439
  """Validate frontend dependencies to ensure they meet requirements.
@@ -1438,15 +1450,12 @@ def validate_frontend_dependencies(init: bool = True):
1438
1450
  except FileNotFoundError as e:
1439
1451
  raise typer.Exit(1) from e
1440
1452
 
1441
- if prefer_npm_over_bun():
1442
- if not check_node_version():
1443
- node_version = get_node_version()
1444
- console.error(
1445
- f"Reflex requires node version {constants.Node.MIN_VERSION} or higher to run, but the detected version is {node_version}",
1446
- )
1447
- raise typer.Exit(1)
1448
- else:
1449
- validate_bun()
1453
+ if prefer_npm_over_bun() and not check_node_version():
1454
+ node_version = get_node_version()
1455
+ console.error(
1456
+ f"Reflex requires node version {constants.Node.MIN_VERSION} or higher to run, but the detected version is {node_version}",
1457
+ )
1458
+ raise typer.Exit(1)
1450
1459
 
1451
1460
 
1452
1461
  def ensure_reflex_installation_id() -> int | None:
@@ -1250,12 +1250,20 @@ class PyiGenerator:
1250
1250
  file_parent = file_parent.parent
1251
1251
  top_dir = top_dir.parent
1252
1252
 
1253
- (top_dir.parent / "pyi_hashes.json").write_text(
1253
+ pyi_hashes_file = top_dir / "pyi_hashes.json"
1254
+ if not pyi_hashes_file.exists():
1255
+ while top_dir.parent and not (top_dir / "pyi_hashes.json").exists():
1256
+ top_dir = top_dir.parent
1257
+ another_pyi_hashes_file = top_dir / "pyi_hashes.json"
1258
+ if another_pyi_hashes_file.exists():
1259
+ pyi_hashes_file = another_pyi_hashes_file
1260
+
1261
+ pyi_hashes_file.write_text(
1254
1262
  json.dumps(
1255
1263
  dict(
1256
1264
  zip(
1257
1265
  [
1258
- str(f.relative_to(top_dir.parent))
1266
+ str(f.relative_to(pyi_hashes_file.parent))
1259
1267
  for f in file_paths
1260
1268
  ],
1261
1269
  hashes,
@@ -1271,11 +1279,8 @@ class PyiGenerator:
1271
1279
  file_paths = list(map(Path, file_paths))
1272
1280
  pyi_hashes_parent = file_paths[0].parent
1273
1281
  while (
1274
- not any(
1275
- subfile.name == "pyi_hashes.json"
1276
- for subfile in pyi_hashes_parent.iterdir()
1277
- )
1278
- and pyi_hashes_parent.parent
1282
+ pyi_hashes_parent.parent
1283
+ and not (pyi_hashes_parent / "pyi_hashes.json").exists()
1279
1284
  ):
1280
1285
  pyi_hashes_parent = pyi_hashes_parent.parent
1281
1286
 
@@ -1288,6 +1293,7 @@ class PyiGenerator:
1288
1293
  pyi_hashes[str(file_path.relative_to(pyi_hashes_parent))] = (
1289
1294
  hashed_content
1290
1295
  )
1296
+
1291
1297
  pyi_hashes_file.write_text(
1292
1298
  json.dumps(pyi_hashes, indent=2, sort_keys=True) + "\n"
1293
1299
  )
reflex/utils/telemetry.py CHANGED
@@ -9,6 +9,7 @@ import platform
9
9
  import warnings
10
10
  from contextlib import suppress
11
11
  from datetime import datetime, timezone
12
+ from typing import TypedDict
12
13
 
13
14
  import httpx
14
15
  import psutil
@@ -16,6 +17,8 @@ import psutil
16
17
  from reflex import constants
17
18
  from reflex.config import environment
18
19
  from reflex.utils import console
20
+ from reflex.utils.decorator import once_unless_none
21
+ from reflex.utils.exceptions import ReflexError
19
22
  from reflex.utils.prerequisites import ensure_reflex_installation_id, get_project_hash
20
23
 
21
24
  UTC = timezone.utc
@@ -94,15 +97,39 @@ def _raise_on_missing_project_hash() -> bool:
94
97
  return not environment.REFLEX_SKIP_COMPILE.get()
95
98
 
96
99
 
97
- def _prepare_event(event: str, **kwargs) -> dict:
98
- """Prepare the event to be sent to the PostHog server.
100
+ class _Properties(TypedDict):
101
+ """Properties type for telemetry."""
99
102
 
100
- Args:
101
- event: The event name.
102
- kwargs: Additional data to send with the event.
103
+ distinct_id: int
104
+ distinct_app_id: int
105
+ user_os: str
106
+ user_os_detail: str
107
+ reflex_version: str
108
+ python_version: str
109
+ cpu_count: int
110
+ memory: int
111
+ cpu_info: dict
112
+
113
+
114
+ class _DefaultEvent(TypedDict):
115
+ """Default event type for telemetry."""
116
+
117
+ api_key: str
118
+ properties: _Properties
119
+
120
+
121
+ class _Event(_DefaultEvent):
122
+ """Event type for telemetry."""
123
+
124
+ event: str
125
+ timestamp: str
126
+
127
+
128
+ def _get_event_defaults() -> _DefaultEvent | None:
129
+ """Get the default event data.
103
130
 
104
131
  Returns:
105
- The event data.
132
+ The default event data.
106
133
  """
107
134
  from reflex.utils.prerequisites import get_cpu_info
108
135
 
@@ -113,19 +140,12 @@ def _prepare_event(event: str, **kwargs) -> dict:
113
140
  console.debug(
114
141
  f"Could not get installation_id or project_hash: {installation_id}, {project_hash}"
115
142
  )
116
- return {}
117
-
118
- stamp = datetime.now(UTC).isoformat()
143
+ return None
119
144
 
120
145
  cpuinfo = get_cpu_info()
121
146
 
122
- additional_keys = ["template", "context", "detail", "user_uuid"]
123
- additional_fields = {
124
- key: value for key in additional_keys if (value := kwargs.get(key)) is not None
125
- }
126
147
  return {
127
148
  "api_key": "phc_JoMo0fOyi0GQAooY3UyO9k0hebGkMyFJrrCw1Gt5SGb",
128
- "event": event,
129
149
  "properties": {
130
150
  "distinct_id": installation_id,
131
151
  "distinct_app_id": project_hash,
@@ -136,13 +156,55 @@ def _prepare_event(event: str, **kwargs) -> dict:
136
156
  "cpu_count": get_cpu_count(),
137
157
  "memory": get_memory(),
138
158
  "cpu_info": dataclasses.asdict(cpuinfo) if cpuinfo else {},
139
- **additional_fields,
140
159
  },
160
+ }
161
+
162
+
163
+ @once_unless_none
164
+ def get_event_defaults() -> _DefaultEvent | None:
165
+ """Get the default event data.
166
+
167
+ Returns:
168
+ The default event data.
169
+ """
170
+ return _get_event_defaults()
171
+
172
+
173
+ def _prepare_event(event: str, **kwargs) -> _Event | None:
174
+ """Prepare the event to be sent to the PostHog server.
175
+
176
+ Args:
177
+ event: The event name.
178
+ kwargs: Additional data to send with the event.
179
+
180
+ Returns:
181
+ The event data.
182
+ """
183
+ event_data = get_event_defaults()
184
+ if not event_data:
185
+ return None
186
+
187
+ additional_keys = ["template", "context", "detail", "user_uuid"]
188
+
189
+ properties = event_data["properties"]
190
+
191
+ for key in additional_keys:
192
+ if key in properties or key not in kwargs:
193
+ continue
194
+
195
+ properties[key] = kwargs[key]
196
+
197
+ stamp = datetime.now(UTC).isoformat()
198
+
199
+ return {
200
+ "api_key": event_data["api_key"],
201
+ "event": event,
202
+ "properties": properties,
141
203
  "timestamp": stamp,
142
204
  }
143
205
 
144
206
 
145
- def _send_event(event_data: dict) -> bool:
207
+ def _send_event(event_data: _Event) -> bool:
146
208
  try:
147
209
  httpx.post(POSTHOG_API_URL, json=event_data)
148
210
  except Exception:
@@ -151,7 +213,7 @@ def _send_event(event_data: dict) -> bool:
151
213
  return True
152
214
 
153
215
 
154
- def _send(event: str, telemetry_enabled: bool | None, **kwargs):
216
+ def _send(event: str, telemetry_enabled: bool | None, **kwargs) -> bool:
155
217
  from reflex.config import get_config
156
218
 
157
219
  # Get the telemetry_enabled from the config if it is not specified.
@@ -167,6 +229,7 @@ def _send(event: str, telemetry_enabled: bool | None, **kwargs):
167
229
  if not event_data:
168
230
  return False
169
231
  return _send_event(event_data)
232
+ return False
170
233
 
171
234
 
172
235
  def send(event: str, telemetry_enabled: bool | None = None, **kwargs):
@@ -196,8 +259,6 @@ def send_error(error: Exception, context: str):
196
259
  Args:
197
260
  error: The error to send.
198
261
  context: The context of the error (e.g. "frontend" or "backend")
199
-
200
- Returns:
201
- Whether the telemetry was sent successfully.
202
262
  """
203
- return send("error", detail=type(error).__name__, context=context)
263
+ if isinstance(error, ReflexError):
264
+ send("error", detail=type(error).__name__, context=context)
reflex/utils/types.py CHANGED
@@ -996,6 +996,18 @@ def typehint_issubclass(
996
996
  for arg in args
997
997
  )
998
998
 
999
+ if is_literal(possible_subclass):
1000
+ args = get_args(possible_subclass)
1001
+ return all(
1002
+ _isinstance(
1003
+ arg,
1004
+ possible_superclass,
1005
+ treat_mutable_obj_as_immutable=treat_mutable_superclasss_as_immutable,
1006
+ nested=2,
1007
+ )
1008
+ for arg in args
1009
+ )
1010
+
999
1011
  # Remove this check when Python 3.10 is the minimum supported version
1000
1012
  if hasattr(types, "UnionType"):
1001
1013
  provided_type_origin = (
reflex/vars/base.py CHANGED
@@ -44,6 +44,7 @@ from typing import (
44
44
  overload,
45
45
  )
46
46
 
47
+ from rich.markup import escape
47
48
  from sqlalchemy.orm import DeclarativeBase
48
49
  from typing_extensions import deprecated, override
49
50
 
@@ -730,6 +731,9 @@ class Var(Generic[VAR_TYPE]):
730
731
  @overload
731
732
  def to(self, output: Type[bool]) -> BooleanVar: ...
732
733
 
734
+ @overload
735
+ def to(self, output: type[int]) -> NumberVar[int]: ...
736
+
733
737
  @overload
734
738
  def to(self, output: type[int] | type[float]) -> NumberVar: ...
735
739
 
@@ -1060,6 +1064,16 @@ class Var(Generic[VAR_TYPE]):
1060
1064
 
1061
1065
  return boolify(self)
1062
1066
 
1067
+ def is_not_none(self) -> BooleanVar:
1068
+ """Check if the var is not None.
1069
+
1070
+ Returns:
1071
+ A BooleanVar object representing the result of the check.
1072
+ """
1073
+ from .number import is_not_none_operation
1074
+
1075
+ return is_not_none_operation(self)
1076
+
1063
1077
  def __and__(
1064
1078
  self, other: Var[OTHER_VAR_TYPE] | Any
1065
1079
  ) -> Var[VAR_TYPE | OTHER_VAR_TYPE]:
@@ -2371,7 +2385,7 @@ class ComputedVar(Var[RETURN_TYPE]):
2371
2385
  if not _isinstance(value, self._var_type, nested=1, treat_var_as_type=False):
2372
2386
  console.error(
2373
2387
  f"Computed var '{type(instance).__name__}.{self._js_expr}' must return"
2374
- f" a value of type '{self._var_type}', got '{value!s}' of type {type(value)}."
2388
+ f" a value of type '{escape(str(self._var_type))}', got '{value!s}' of type {type(value)}."
2375
2389
  )
2376
2390
 
2377
2391
  def _deps(
reflex/vars/number.py CHANGED
@@ -1057,6 +1057,10 @@ _IS_TRUE_IMPORT: ImportDict = {
1057
1057
  f"$/{Dirs.STATE_PATH}": [ImportVar(tag="isTrue")],
1058
1058
  }
1059
1059
 
1060
+ _IS_NOT_NULL_OR_UNDEFINED_IMPORT: ImportDict = {
1061
+ f"$/{Dirs.STATE_PATH}": [ImportVar(tag="isNotNullOrUndefined")],
1062
+ }
1063
+
1060
1064
 
1061
1065
  @var_operation
1062
1066
  def boolify(value: Var):
@@ -1075,6 +1079,23 @@ def boolify(value: Var):
1075
1079
  )
1076
1080
 
1077
1081
 
1082
+ @var_operation
1083
+ def is_not_none_operation(value: Var):
1084
+ """Check if the value is not None.
1085
+
1086
+ Args:
1087
+ value: The value.
1088
+
1089
+ Returns:
1090
+ The boolean value.
1091
+ """
1092
+ return var_operation_return(
1093
+ js_expression=f"isNotNullOrUndefined({value})",
1094
+ var_type=bool,
1095
+ var_data=VarData(imports=_IS_NOT_NULL_OR_UNDEFINED_IMPORT),
1096
+ )
1097
+
1098
+
1078
1099
  T = TypeVar("T")
1079
1100
  U = TypeVar("U")
1080
1101
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reflex
3
- Version: 0.7.6a0
3
+ Version: 0.7.7
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
@@ -18,26 +18,26 @@ Classifier: Programming Language :: Python :: 3.11
18
18
  Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Programming Language :: Python :: 3.13
20
20
  Requires-Python: <4.0,>=3.10
21
- Requires-Dist: alembic<2.0,>=1.11.1
22
- Requires-Dist: distro<2.0,>=1.8.0; platform_system == 'Linux'
23
- Requires-Dist: fastapi!=0.111.0,!=0.111.1,>=0.96.0
24
- Requires-Dist: granian[reload]>=2.2.0
21
+ Requires-Dist: alembic<2.0,>=1.15.2
22
+ Requires-Dist: distro<2.0,>=1.9.0; platform_system == 'Linux'
23
+ Requires-Dist: fastapi>=0.115.0
24
+ Requires-Dist: granian[reload]>=2.2.3
25
25
  Requires-Dist: gunicorn<24.0.0,>=23.0.0
26
- Requires-Dist: httpx<1.0,>=0.25.1
26
+ Requires-Dist: httpx<1.0,>=0.28.0
27
27
  Requires-Dist: jinja2<4.0,>=3.1.2
28
- Requires-Dist: packaging<25.0,>=23.1
29
- Requires-Dist: platformdirs<5.0,>=3.10.0
30
- Requires-Dist: psutil<8.0,>=5.9.4
28
+ Requires-Dist: packaging<25.0,>=24.2
29
+ Requires-Dist: platformdirs<5.0,>=4.3.7
30
+ Requires-Dist: psutil<8.0,>=7.0.0
31
31
  Requires-Dist: pydantic<3.0,>=1.10.21
32
32
  Requires-Dist: python-multipart<1.0,>=0.0.20
33
- Requires-Dist: python-socketio<6.0,>=5.7.0
34
- Requires-Dist: redis<6.0,>=4.3.5
35
- Requires-Dist: reflex-hosting-cli>=0.1.29
33
+ Requires-Dist: python-socketio<6.0,>=5.12.0
34
+ Requires-Dist: redis<6.0,>=5.2.1
35
+ Requires-Dist: reflex-hosting-cli>=0.1.38
36
36
  Requires-Dist: rich<14.0,>=13.0.0
37
- Requires-Dist: sqlmodel<0.1,>=0.0.14
38
- Requires-Dist: typer<1.0,>=0.15.1
39
- Requires-Dist: typing-extensions>=4.6.0
40
- Requires-Dist: uvicorn>=0.20.0
37
+ Requires-Dist: sqlmodel<0.1,>=0.0.24
38
+ Requires-Dist: typer<1.0,>=0.15.2
39
+ Requires-Dist: typing-extensions>=4.13.0
40
+ Requires-Dist: uvicorn>=0.34.0
41
41
  Requires-Dist: wrapt<2.0,>=1.17.0
42
42
  Description-Content-Type: text/markdown
43
43