reflex 0.7.6a0__py3-none-any.whl → 0.7.6a1__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.
- reflex/components/el/elements/forms.py +6 -0
- reflex/components/el/elements/forms.pyi +4 -0
- reflex/utils/decorator.py +21 -0
- reflex/utils/pyi_generator.py +13 -7
- reflex/utils/telemetry.py +82 -21
- reflex/utils/types.py +12 -0
- {reflex-0.7.6a0.dist-info → reflex-0.7.6a1.dist-info}/METADATA +1 -1
- {reflex-0.7.6a0.dist-info → reflex-0.7.6a1.dist-info}/RECORD +11 -11
- {reflex-0.7.6a0.dist-info → reflex-0.7.6a1.dist-info}/WHEEL +0 -0
- {reflex-0.7.6a0.dist-info → reflex-0.7.6a1.dist-info}/entry_points.txt +0 -0
- {reflex-0.7.6a0.dist-info → reflex-0.7.6a1.dist-info}/licenses/LICENSE +0 -0
|
@@ -572,6 +572,12 @@ class Select(BaseHTML):
|
|
|
572
572
|
# Fired when the select value changes
|
|
573
573
|
on_change: EventHandler[input_event]
|
|
574
574
|
|
|
575
|
+
# The controlled value of the select, read only unless used with on_change
|
|
576
|
+
value: Var[str]
|
|
577
|
+
|
|
578
|
+
# The default value of the select when initially rendered
|
|
579
|
+
default_value: Var[str]
|
|
580
|
+
|
|
575
581
|
|
|
576
582
|
AUTO_HEIGHT_JS = """
|
|
577
583
|
const autoHeightOnInput = (e, is_enabled) => {
|
|
@@ -3027,6 +3027,8 @@ class Select(BaseHTML):
|
|
|
3027
3027
|
name: Var[str] | str | None = None,
|
|
3028
3028
|
required: Var[bool] | bool | None = None,
|
|
3029
3029
|
size: Var[int] | int | None = None,
|
|
3030
|
+
value: Var[str] | str | None = None,
|
|
3031
|
+
default_value: Var[str] | str | None = None,
|
|
3030
3032
|
access_key: Var[str] | str | None = None,
|
|
3031
3033
|
auto_capitalize: Literal[
|
|
3032
3034
|
"characters", "none", "off", "on", "sentences", "words"
|
|
@@ -3246,6 +3248,8 @@ class Select(BaseHTML):
|
|
|
3246
3248
|
required: Indicates that the select control must have a selected option
|
|
3247
3249
|
size: Number of visible options in a drop-down list
|
|
3248
3250
|
on_change: Fired when the select value changes
|
|
3251
|
+
value: The controlled value of the select, read only unless used with on_change
|
|
3252
|
+
default_value: The default value of the select when initially rendered
|
|
3249
3253
|
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
|
3250
3254
|
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
|
3251
3255
|
content_editable: Indicates whether the element's content is editable.
|
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/pyi_generator.py
CHANGED
|
@@ -1250,12 +1250,20 @@ class PyiGenerator:
|
|
|
1250
1250
|
file_parent = file_parent.parent
|
|
1251
1251
|
top_dir = top_dir.parent
|
|
1252
1252
|
|
|
1253
|
-
|
|
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(
|
|
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
|
-
|
|
1275
|
-
|
|
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
|
-
|
|
98
|
-
"""
|
|
100
|
+
class _Properties(TypedDict):
|
|
101
|
+
"""Properties type for telemetry."""
|
|
99
102
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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:
|
|
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
|
-
|
|
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 = (
|
|
@@ -136,8 +136,8 @@ reflex/components/el/elements/__init__.py,sha256=Ocexkpl7YRpdpL6YPsG_QgxYWO0dx1g
|
|
|
136
136
|
reflex/components/el/elements/__init__.pyi,sha256=uuwnUtPo4hPTByt8qzbdZT-_cOSPiTTaw5BXN2H2kpM,11129
|
|
137
137
|
reflex/components/el/elements/base.py,sha256=4jnwyCQUHvWcIfwiIWVCiIC_jbwZlkAiOgx73t7tdw8,3075
|
|
138
138
|
reflex/components/el/elements/base.pyi,sha256=QQ9ZvgJEH-0QnjEY7I9Rj4O4qVPAxt3mhx0UXHqZII8,10032
|
|
139
|
-
reflex/components/el/elements/forms.py,sha256=
|
|
140
|
-
reflex/components/el/elements/forms.pyi,sha256=
|
|
139
|
+
reflex/components/el/elements/forms.py,sha256=Yr4JZ3qy-NGehP3kGnFayUNaEIg3Ly8B1AAdrrN16oo,20293
|
|
140
|
+
reflex/components/el/elements/forms.pyi,sha256=zzxMYkjhY4Eo8zWF99YM9yW_QDpyP4zLwG8l9Wwwd9k,126565
|
|
141
141
|
reflex/components/el/elements/inline.py,sha256=GxOYtkNm1OfdMeqNvrFY_AUm-SVdc4Zg4JdSf3V3S6g,4064
|
|
142
142
|
reflex/components/el/elements/inline.pyi,sha256=O9CSe9Cm-NzxLn64UtdnkosZyIgXfJcYGxLYlc-hEQA,231259
|
|
143
143
|
reflex/components/el/elements/media.py,sha256=n84bNz3KO4TkaCi7eFierpVkcDEB9uYTk5oBKl-s1GI,13064
|
|
@@ -371,7 +371,7 @@ reflex/utils/build.py,sha256=yt6obelsj1MUhTVHoaxdOH--gYtIEpekYjTN97iFrNg,9118
|
|
|
371
371
|
reflex/utils/codespaces.py,sha256=6oNokBRpH5Qj39LTS9R2hW59ZVLRwDEooeHD_85hmfw,2945
|
|
372
372
|
reflex/utils/compat.py,sha256=aSJH_M6iomgHPQ4onQ153xh1MWqPi3HSYDzE68N6gZM,2635
|
|
373
373
|
reflex/utils/console.py,sha256=97QCo1vXFM-B32zrvYH51yzDRyNPkXD5nNriaiCrlpc,9439
|
|
374
|
-
reflex/utils/decorator.py,sha256=
|
|
374
|
+
reflex/utils/decorator.py,sha256=RaqnUjPaEZSrTy9jy4AQZVG2rpOjJK8Eec0PE-9BNcA,1711
|
|
375
375
|
reflex/utils/exceptions.py,sha256=Wwu7Ji2xgq521bJKtU2NgjwhmFfnG8erirEVN2h8S-g,8884
|
|
376
376
|
reflex/utils/exec.py,sha256=cZhowK1CD8qUZEyRxhfTljOkKsZCoMXODLv621sQ3b0,19394
|
|
377
377
|
reflex/utils/export.py,sha256=bcJA0L8lBbjij-5PU93ka2c1d_yJqrIurp5u4mN5f68,2537
|
|
@@ -383,12 +383,12 @@ reflex/utils/net.py,sha256=8ceAC_diguAxVOOJpzax2vb1RA2h4BxS8SJvpgWqGYI,3175
|
|
|
383
383
|
reflex/utils/path_ops.py,sha256=idGxUSJRKwYLLi7ppXkq3eV6rvAytJoO-n-FuLkwl3o,7604
|
|
384
384
|
reflex/utils/prerequisites.py,sha256=OdZlAL7EMybK1jD_q7MuBbH_o9nP9z9d12dT7skb3jk,65869
|
|
385
385
|
reflex/utils/processes.py,sha256=OpZafayCw5VhPyD1LIyin_5fu7Oy2mDCqSxAxX4sh08,16617
|
|
386
|
-
reflex/utils/pyi_generator.py,sha256=
|
|
386
|
+
reflex/utils/pyi_generator.py,sha256=SaBMcZrQ68hl77DcskNBo9FODyFQdWuixmlpS695EjE,45030
|
|
387
387
|
reflex/utils/redir.py,sha256=23OcUTsbThak5VYMQPOkSzyNsMB3VkgtF1bodSnHwbE,1533
|
|
388
388
|
reflex/utils/registry.py,sha256=ymBScatt5YiQz9tPYHCzSPs-X7z29hGuu2tlZG28YDQ,1877
|
|
389
389
|
reflex/utils/serializers.py,sha256=mk5U7U-ae4yTvifq17ejaX1qtKhg1UIJiWiXUNWjJfY,13399
|
|
390
|
-
reflex/utils/telemetry.py,sha256=
|
|
391
|
-
reflex/utils/types.py,sha256=
|
|
390
|
+
reflex/utils/telemetry.py,sha256=kZeI_RjY32MTpx12Y5hMXyd6bkli9xAQsmbbIKuf0fg,6779
|
|
391
|
+
reflex/utils/types.py,sha256=puaBT2vazRGRQluyTcZh8iZ6qLMRCuccMsKTNY0RCFg,33970
|
|
392
392
|
reflex/vars/__init__.py,sha256=2Kv6Oh9g3ISZFESjL1al8KiO7QBZUXmLKGMCBsP-DoY,1243
|
|
393
393
|
reflex/vars/base.py,sha256=bYCCkLp7aa75Wuv4M763K7Xqu2DFd_FbW11M-fw7ykE,101326
|
|
394
394
|
reflex/vars/datetime.py,sha256=fEc68T0A6XYlAJ3AGteCIb_vDqgoO1O8tpjMzqlp9sc,5104
|
|
@@ -397,8 +397,8 @@ reflex/vars/function.py,sha256=2sVnhgetPSwtor8VFtAiYJdzZ9IRNzAKdsUJG6dXQcE,14461
|
|
|
397
397
|
reflex/vars/number.py,sha256=__X8C4lwDQNy8RL9-AxVgC6MM1KF-2PClXE0aR9Ldno,27453
|
|
398
398
|
reflex/vars/object.py,sha256=-fGqHThozjxAAuQL-wTwEItPiFI-ps53P2bKoSlW_As,17081
|
|
399
399
|
reflex/vars/sequence.py,sha256=zR3Gwi0xkypThKO45KGqu_AYruY1mTK8kmHjzXcm8y8,55289
|
|
400
|
-
reflex-0.7.
|
|
401
|
-
reflex-0.7.
|
|
402
|
-
reflex-0.7.
|
|
403
|
-
reflex-0.7.
|
|
404
|
-
reflex-0.7.
|
|
400
|
+
reflex-0.7.6a1.dist-info/METADATA,sha256=ZKSIdEnakJpgtGN_G7VxdvQyezSgK9E1wTp7Nc97Bg4,11897
|
|
401
|
+
reflex-0.7.6a1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
402
|
+
reflex-0.7.6a1.dist-info/entry_points.txt,sha256=Rxt4dXc7MLBNt5CSHTehVPuSe9Xqow4HLX55nD9tQQ0,45
|
|
403
|
+
reflex-0.7.6a1.dist-info/licenses/LICENSE,sha256=dw3zLrp9f5ObD7kqS32vWfhcImfO52PMmRqvtxq_YEE,11358
|
|
404
|
+
reflex-0.7.6a1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|