reflex 0.8.14.post1__py3-none-any.whl → 0.8.15a0__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/__init__.py +1 -1
- reflex/__init__.pyi +2 -1
- reflex/app.py +5 -2
- reflex/base.py +61 -33
- reflex/components/datadisplay/dataeditor.py +17 -2
- reflex/components/datadisplay/dataeditor.pyi +6 -2
- reflex/components/lucide/icon.py +2 -1
- reflex/components/lucide/icon.pyi +2 -1
- reflex/components/sonner/toast.py +3 -2
- reflex/components/sonner/toast.pyi +3 -2
- reflex/constants/installer.py +3 -3
- reflex/environment.py +9 -1
- reflex/istate/proxy.py +35 -24
- reflex/model.py +530 -511
- reflex/plugins/tailwind_v4.py +2 -2
- reflex/reflex.py +16 -10
- reflex/state.py +21 -25
- reflex/testing.py +8 -6
- reflex/utils/build.py +11 -1
- reflex/utils/compat.py +11 -56
- reflex/utils/prerequisites.py +2 -1
- reflex/utils/serializers.py +21 -20
- reflex/utils/telemetry.py +0 -2
- reflex/utils/types.py +81 -90
- reflex/vars/base.py +2 -16
- reflex/vars/object.py +28 -1
- {reflex-0.8.14.post1.dist-info → reflex-0.8.15a0.dist-info}/METADATA +5 -1
- {reflex-0.8.14.post1.dist-info → reflex-0.8.15a0.dist-info}/RECORD +31 -31
- {reflex-0.8.14.post1.dist-info → reflex-0.8.15a0.dist-info}/WHEEL +0 -0
- {reflex-0.8.14.post1.dist-info → reflex-0.8.15a0.dist-info}/entry_points.txt +0 -0
- {reflex-0.8.14.post1.dist-info → reflex-0.8.15a0.dist-info}/licenses/LICENSE +0 -0
reflex/plugins/tailwind_v4.py
CHANGED
|
@@ -17,7 +17,7 @@ class Constants(SimpleNamespace):
|
|
|
17
17
|
"""Tailwind constants."""
|
|
18
18
|
|
|
19
19
|
# The Tailwindcss version
|
|
20
|
-
VERSION = "tailwindcss@4.1.
|
|
20
|
+
VERSION = "tailwindcss@4.1.14"
|
|
21
21
|
# The Tailwind config.
|
|
22
22
|
CONFIG = "tailwind.config.js"
|
|
23
23
|
# Default Tailwind content paths
|
|
@@ -156,7 +156,7 @@ class TailwindV4Plugin(TailwindPlugin):
|
|
|
156
156
|
return [
|
|
157
157
|
*super().get_frontend_development_dependencies(**context),
|
|
158
158
|
Constants.VERSION,
|
|
159
|
-
"@tailwindcss/postcss@4.1.
|
|
159
|
+
"@tailwindcss/postcss@4.1.14",
|
|
160
160
|
]
|
|
161
161
|
|
|
162
162
|
def pre_compile(self, **context):
|
reflex/reflex.py
CHANGED
|
@@ -11,12 +11,14 @@ from reflex_cli.v2.deployments import hosting_cli
|
|
|
11
11
|
|
|
12
12
|
from reflex import constants
|
|
13
13
|
from reflex.config import get_config
|
|
14
|
-
from reflex.constants.base import LITERAL_ENV
|
|
15
14
|
from reflex.custom_components.custom_components import custom_components_cli
|
|
16
15
|
from reflex.environment import environment
|
|
17
|
-
from reflex.
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
from reflex.utils import console
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from reflex_cli.constants.base import LogLevel as HostingLogLevel
|
|
20
|
+
|
|
21
|
+
from reflex.constants.base import LITERAL_ENV
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
def set_loglevel(ctx: click.Context, self: click.Parameter, value: str | None):
|
|
@@ -40,6 +42,8 @@ def cli():
|
|
|
40
42
|
|
|
41
43
|
loglevel_option = click.option(
|
|
42
44
|
"--loglevel",
|
|
45
|
+
"--log-level",
|
|
46
|
+
"loglevel",
|
|
43
47
|
type=click.Choice(
|
|
44
48
|
[loglevel.value for loglevel in constants.LogLevel],
|
|
45
49
|
case_sensitive=False,
|
|
@@ -63,7 +67,9 @@ def _init(
|
|
|
63
67
|
exec.output_system_info()
|
|
64
68
|
|
|
65
69
|
if ai:
|
|
66
|
-
redir
|
|
70
|
+
from reflex.utils.redir import reflex_build_redirect
|
|
71
|
+
|
|
72
|
+
reflex_build_redirect()
|
|
67
73
|
return
|
|
68
74
|
|
|
69
75
|
# Validate the app name.
|
|
@@ -136,7 +142,9 @@ def _run(
|
|
|
136
142
|
"""Run the app in the given directory."""
|
|
137
143
|
import atexit
|
|
138
144
|
|
|
139
|
-
from reflex.
|
|
145
|
+
from reflex.state import reset_disk_state_manager
|
|
146
|
+
from reflex.utils import build, exec, prerequisites, processes, telemetry
|
|
147
|
+
from reflex.utils.exec import should_use_granian
|
|
140
148
|
|
|
141
149
|
config = get_config()
|
|
142
150
|
|
|
@@ -535,6 +543,8 @@ def login():
|
|
|
535
543
|
validated_info = hosting_cli.login()
|
|
536
544
|
if validated_info is not None:
|
|
537
545
|
_skip_compile() # Allow running outside of an app dir
|
|
546
|
+
from reflex.utils import telemetry
|
|
547
|
+
|
|
538
548
|
telemetry.send("login", user_uuid=validated_info.get("user_id"))
|
|
539
549
|
|
|
540
550
|
|
|
@@ -838,10 +848,6 @@ def rename(new_name: str):
|
|
|
838
848
|
rename_app(new_name, get_config().loglevel)
|
|
839
849
|
|
|
840
850
|
|
|
841
|
-
if TYPE_CHECKING:
|
|
842
|
-
from reflex_cli.constants.base import LogLevel as HostingLogLevel
|
|
843
|
-
|
|
844
|
-
|
|
845
851
|
def _convert_reflex_loglevel_to_reflex_cli_loglevel(
|
|
846
852
|
loglevel: constants.LogLevel,
|
|
847
853
|
) -> HostingLogLevel:
|
reflex/state.py
CHANGED
|
@@ -17,19 +17,15 @@ import typing
|
|
|
17
17
|
import warnings
|
|
18
18
|
from collections.abc import AsyncIterator, Callable, Sequence
|
|
19
19
|
from hashlib import md5
|
|
20
|
+
from importlib.util import find_spec
|
|
20
21
|
from types import FunctionType
|
|
21
22
|
from typing import TYPE_CHECKING, Any, BinaryIO, ClassVar, TypeVar, cast, get_type_hints
|
|
22
23
|
|
|
23
|
-
import pydantic.v1 as pydantic
|
|
24
|
-
from pydantic import BaseModel as BaseModelV2
|
|
25
|
-
from pydantic.v1 import BaseModel as BaseModelV1
|
|
26
|
-
from pydantic.v1.fields import ModelField
|
|
27
24
|
from rich.markup import escape
|
|
28
25
|
from typing_extensions import Self
|
|
29
26
|
|
|
30
27
|
import reflex.istate.dynamic
|
|
31
28
|
from reflex import constants, event
|
|
32
|
-
from reflex.base import Base
|
|
33
29
|
from reflex.constants.state import FIELD_MARKER
|
|
34
30
|
from reflex.environment import PerformanceMode, environment
|
|
35
31
|
from reflex.event import (
|
|
@@ -94,13 +90,11 @@ if environment.REFLEX_PERF_MODE.get() != PerformanceMode.OFF:
|
|
|
94
90
|
VAR_TYPE = TypeVar("VAR_TYPE")
|
|
95
91
|
|
|
96
92
|
|
|
97
|
-
def _no_chain_background_task(
|
|
98
|
-
state_cls: type[BaseState], name: str, fn: Callable
|
|
99
|
-
) -> Callable:
|
|
93
|
+
def _no_chain_background_task(state: BaseState, name: str, fn: Callable) -> Callable:
|
|
100
94
|
"""Protect against directly chaining a background task from another event handler.
|
|
101
95
|
|
|
102
96
|
Args:
|
|
103
|
-
|
|
97
|
+
state: The state instance the background task is bound to.
|
|
104
98
|
name: The name of the background task.
|
|
105
99
|
fn: The background task coroutine function / generator.
|
|
106
100
|
|
|
@@ -110,7 +104,7 @@ def _no_chain_background_task(
|
|
|
110
104
|
Raises:
|
|
111
105
|
TypeError: If the background task is not async.
|
|
112
106
|
"""
|
|
113
|
-
call = f"{
|
|
107
|
+
call = f"{type(state).__name__}.{name}"
|
|
114
108
|
message = (
|
|
115
109
|
f"Cannot directly call background task {name!r}, use "
|
|
116
110
|
f"`yield {call}` or `return {call}` instead."
|
|
@@ -259,10 +253,6 @@ class EventHandlerSetVar(EventHandler):
|
|
|
259
253
|
return super().__call__(*args)
|
|
260
254
|
|
|
261
255
|
|
|
262
|
-
if TYPE_CHECKING:
|
|
263
|
-
from pydantic.v1.fields import ModelField
|
|
264
|
-
|
|
265
|
-
|
|
266
256
|
def get_var_for_field(cls: type[BaseState], name: str, f: Field) -> Var:
|
|
267
257
|
"""Get a Var instance for a state field.
|
|
268
258
|
|
|
@@ -479,7 +469,7 @@ class BaseState(EvenMoreBasicBaseState):
|
|
|
479
469
|
|
|
480
470
|
Args:
|
|
481
471
|
mixin: Whether the subclass is a mixin and should not be initialized.
|
|
482
|
-
**kwargs: The kwargs to pass to the
|
|
472
|
+
**kwargs: The kwargs to pass to the init_subclass method.
|
|
483
473
|
|
|
484
474
|
Raises:
|
|
485
475
|
StateValueError: If a substate class shadows another.
|
|
@@ -739,7 +729,7 @@ class BaseState(EvenMoreBasicBaseState):
|
|
|
739
729
|
mixin
|
|
740
730
|
for mixin in cls.__mro__
|
|
741
731
|
if (
|
|
742
|
-
mixin not
|
|
732
|
+
mixin is not cls
|
|
743
733
|
and issubclass(mixin, BaseState)
|
|
744
734
|
and mixin._mixin is True
|
|
745
735
|
)
|
|
@@ -1090,7 +1080,7 @@ class BaseState(EvenMoreBasicBaseState):
|
|
|
1090
1080
|
_var_data=VarData.from_state(cls, name),
|
|
1091
1081
|
).guess_type()
|
|
1092
1082
|
|
|
1093
|
-
# add the
|
|
1083
|
+
# add the field dynamically (must be done before _init_var)
|
|
1094
1084
|
cls.add_field(name, var, default_value)
|
|
1095
1085
|
|
|
1096
1086
|
cls._init_var(name, var)
|
|
@@ -1188,7 +1178,7 @@ class BaseState(EvenMoreBasicBaseState):
|
|
|
1188
1178
|
name: The name of the var.
|
|
1189
1179
|
prop: The var to set the default value for.
|
|
1190
1180
|
"""
|
|
1191
|
-
# Get the
|
|
1181
|
+
# Get the field for the var.
|
|
1192
1182
|
field = cls.get_fields()[name]
|
|
1193
1183
|
|
|
1194
1184
|
if field.default is None and not types.is_optional(prop._var_type):
|
|
@@ -1349,7 +1339,7 @@ class BaseState(EvenMoreBasicBaseState):
|
|
|
1349
1339
|
if name in event_handlers:
|
|
1350
1340
|
handler = event_handlers[name]
|
|
1351
1341
|
if handler.is_background:
|
|
1352
|
-
fn = _no_chain_background_task(
|
|
1342
|
+
fn = _no_chain_background_task(self, name, handler.fn)
|
|
1353
1343
|
else:
|
|
1354
1344
|
fn = functools.partial(handler.fn, self)
|
|
1355
1345
|
fn.__module__ = handler.fn.__module__
|
|
@@ -1465,7 +1455,7 @@ class BaseState(EvenMoreBasicBaseState):
|
|
|
1465
1455
|
|
|
1466
1456
|
@classmethod
|
|
1467
1457
|
@functools.lru_cache
|
|
1468
|
-
def _is_client_storage(cls, prop_name_or_field: str |
|
|
1458
|
+
def _is_client_storage(cls, prop_name_or_field: str | Field) -> bool:
|
|
1469
1459
|
"""Check if the var is a client storage var.
|
|
1470
1460
|
|
|
1471
1461
|
Args:
|
|
@@ -1872,10 +1862,16 @@ class BaseState(EvenMoreBasicBaseState):
|
|
|
1872
1862
|
if key in hinted_args.__fields__
|
|
1873
1863
|
}
|
|
1874
1864
|
)
|
|
1875
|
-
elif dataclasses.is_dataclass(hinted_args)
|
|
1876
|
-
hinted_args, (Base, BaseModelV1, BaseModelV2)
|
|
1877
|
-
):
|
|
1865
|
+
elif dataclasses.is_dataclass(hinted_args):
|
|
1878
1866
|
payload[arg] = hinted_args(**value)
|
|
1867
|
+
elif find_spec("pydantic"):
|
|
1868
|
+
from pydantic import BaseModel as BaseModelV2
|
|
1869
|
+
from pydantic.v1 import BaseModel as BaseModelV1
|
|
1870
|
+
|
|
1871
|
+
if issubclass(hinted_args, BaseModelV1):
|
|
1872
|
+
payload[arg] = hinted_args.parse_obj(value)
|
|
1873
|
+
elif issubclass(hinted_args, BaseModelV2):
|
|
1874
|
+
payload[arg] = hinted_args.model_validate(value)
|
|
1879
1875
|
elif isinstance(value, list) and (hinted_args is set or hinted_args is set):
|
|
1880
1876
|
payload[arg] = set(value)
|
|
1881
1877
|
elif isinstance(value, list) and (
|
|
@@ -2142,7 +2138,7 @@ class BaseState(EvenMoreBasicBaseState):
|
|
|
2142
2138
|
Args:
|
|
2143
2139
|
include_computed: Whether to include computed vars.
|
|
2144
2140
|
initial: Whether to get the initial value of computed vars.
|
|
2145
|
-
**kwargs: Kwargs to pass to the
|
|
2141
|
+
**kwargs: Kwargs to pass to the dict method.
|
|
2146
2142
|
|
|
2147
2143
|
Returns:
|
|
2148
2144
|
The object as a dictionary.
|
|
@@ -2626,7 +2622,7 @@ class ComponentState(State, mixin=True):
|
|
|
2626
2622
|
|
|
2627
2623
|
Args:
|
|
2628
2624
|
mixin: Whether the subclass is a mixin and should not be initialized.
|
|
2629
|
-
**kwargs: The kwargs to pass to the
|
|
2625
|
+
**kwargs: The kwargs to pass to the init_subclass method.
|
|
2630
2626
|
"""
|
|
2631
2627
|
super().__init_subclass__(mixin=mixin, **kwargs)
|
|
2632
2628
|
|
reflex/testing.py
CHANGED
|
@@ -21,6 +21,7 @@ import time
|
|
|
21
21
|
import types
|
|
22
22
|
from collections.abc import AsyncIterator, Callable, Coroutine, Sequence
|
|
23
23
|
from http.server import SimpleHTTPRequestHandler
|
|
24
|
+
from importlib.util import find_spec
|
|
24
25
|
from pathlib import Path
|
|
25
26
|
from typing import TYPE_CHECKING, Any, Literal, TypeVar
|
|
26
27
|
|
|
@@ -320,12 +321,13 @@ class AppHarness:
|
|
|
320
321
|
await self.app_instance.sio.shutdown()
|
|
321
322
|
|
|
322
323
|
# sqlalchemy async engine shutdown handler
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
324
|
+
if find_spec("sqlmodel"):
|
|
325
|
+
try:
|
|
326
|
+
async_engine = reflex.model.get_async_engine(None)
|
|
327
|
+
except ValueError:
|
|
328
|
+
pass
|
|
329
|
+
else:
|
|
330
|
+
await async_engine.dispose()
|
|
329
331
|
|
|
330
332
|
await original_shutdown(*args, **kwargs)
|
|
331
333
|
|
reflex/utils/build.py
CHANGED
|
@@ -187,7 +187,11 @@ def _duplicate_index_html_to_parent_directory(directory: Path):
|
|
|
187
187
|
|
|
188
188
|
|
|
189
189
|
def build():
|
|
190
|
-
"""Build the app for deployment.
|
|
190
|
+
"""Build the app for deployment.
|
|
191
|
+
|
|
192
|
+
Raises:
|
|
193
|
+
SystemExit: If the build process fails.
|
|
194
|
+
"""
|
|
191
195
|
wdir = prerequisites.get_web_dir()
|
|
192
196
|
|
|
193
197
|
# Clean the static directory if it exists.
|
|
@@ -214,6 +218,12 @@ def build():
|
|
|
214
218
|
},
|
|
215
219
|
)
|
|
216
220
|
processes.show_progress("Creating Production Build", process, checkpoints)
|
|
221
|
+
process.wait()
|
|
222
|
+
if process.returncode != 0:
|
|
223
|
+
console.error(
|
|
224
|
+
"Failed to build the frontend. Please run with --loglevel debug for more information.",
|
|
225
|
+
)
|
|
226
|
+
raise SystemExit(1)
|
|
217
227
|
_duplicate_index_html_to_parent_directory(wdir / constants.Dirs.STATIC)
|
|
218
228
|
|
|
219
229
|
spa_fallback = wdir / constants.Dirs.STATIC / constants.ReactRouter.SPA_FALLBACK
|
reflex/utils/compat.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"""Compatibility hacks and helpers."""
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from pydantic.fields import FieldInfo
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
async def windows_hot_reload_lifespan_hack():
|
|
@@ -29,63 +30,17 @@ async def windows_hot_reload_lifespan_hack():
|
|
|
29
30
|
pass
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"""A context manager that patches the Pydantic module to mimic v1 behaviour.
|
|
35
|
-
|
|
36
|
-
Yields:
|
|
37
|
-
None when the Pydantic module is patched.
|
|
38
|
-
"""
|
|
39
|
-
import pydantic
|
|
40
|
-
|
|
41
|
-
if pydantic.__version__.startswith("1."):
|
|
42
|
-
# pydantic v1 is already installed
|
|
43
|
-
yield
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
patched_modules = [
|
|
47
|
-
"pydantic",
|
|
48
|
-
"pydantic.fields",
|
|
49
|
-
"pydantic.errors",
|
|
50
|
-
"pydantic.main",
|
|
51
|
-
]
|
|
52
|
-
originals = {module: sys.modules.get(module) for module in patched_modules}
|
|
53
|
-
try:
|
|
54
|
-
import pydantic.v1
|
|
55
|
-
|
|
56
|
-
sys.modules["pydantic.fields"] = pydantic.v1.fields # pyright: ignore [reportAttributeAccessIssue]
|
|
57
|
-
sys.modules["pydantic.main"] = pydantic.v1.main # pyright: ignore [reportAttributeAccessIssue]
|
|
58
|
-
sys.modules["pydantic.errors"] = pydantic.v1.errors # pyright: ignore [reportAttributeAccessIssue]
|
|
59
|
-
sys.modules["pydantic"] = pydantic.v1
|
|
60
|
-
yield
|
|
61
|
-
except (ImportError, AttributeError):
|
|
62
|
-
# pydantic v1 is already installed
|
|
63
|
-
yield
|
|
64
|
-
finally:
|
|
65
|
-
# Restore the original Pydantic module
|
|
66
|
-
for k, original in originals.items():
|
|
67
|
-
if k in sys.modules:
|
|
68
|
-
if original:
|
|
69
|
-
sys.modules[k] = original
|
|
70
|
-
else:
|
|
71
|
-
del sys.modules[k]
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
with pydantic_v1_patch():
|
|
75
|
-
import sqlmodel as sqlmodel
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def sqlmodel_field_has_primary_key(field: Any) -> bool:
|
|
79
|
-
"""Determines if a field is a priamary.
|
|
33
|
+
def sqlmodel_field_has_primary_key(field_info: "FieldInfo") -> bool:
|
|
34
|
+
"""Determines if a field is a primary.
|
|
80
35
|
|
|
81
36
|
Args:
|
|
82
|
-
|
|
37
|
+
field_info: a rx.model field
|
|
83
38
|
|
|
84
39
|
Returns:
|
|
85
|
-
If
|
|
40
|
+
If field_info is a primary key (Bool)
|
|
86
41
|
"""
|
|
87
|
-
if getattr(
|
|
42
|
+
if getattr(field_info, "primary_key", None) is True:
|
|
88
43
|
return True
|
|
89
|
-
if getattr(
|
|
44
|
+
if getattr(field_info, "sa_column", None) is None:
|
|
90
45
|
return False
|
|
91
|
-
return bool(getattr(
|
|
46
|
+
return bool(getattr(field_info.sa_column, "primary_key", None)) # pyright: ignore[reportAttributeAccessIssue]
|
reflex/utils/prerequisites.py
CHANGED
|
@@ -15,7 +15,6 @@ from pathlib import Path
|
|
|
15
15
|
from types import ModuleType
|
|
16
16
|
from typing import NamedTuple
|
|
17
17
|
|
|
18
|
-
from alembic.util.exc import CommandError
|
|
19
18
|
from packaging import version
|
|
20
19
|
from redis import Redis as RedisSync
|
|
21
20
|
from redis.asyncio import Redis
|
|
@@ -639,6 +638,8 @@ def check_schema_up_to_date():
|
|
|
639
638
|
if get_config().db_url is None or not environment.ALEMBIC_CONFIG.get().exists():
|
|
640
639
|
return
|
|
641
640
|
with model.Model.get_db_engine().connect() as connection:
|
|
641
|
+
from alembic.util.exc import CommandError
|
|
642
|
+
|
|
642
643
|
try:
|
|
643
644
|
if model.Model.alembic_autogenerate(
|
|
644
645
|
connection=connection,
|
reflex/utils/serializers.py
CHANGED
|
@@ -12,13 +12,11 @@ import warnings
|
|
|
12
12
|
from collections.abc import Callable, Mapping, Sequence
|
|
13
13
|
from datetime import date, datetime, time, timedelta
|
|
14
14
|
from enum import Enum
|
|
15
|
+
from importlib.util import find_spec
|
|
15
16
|
from pathlib import Path
|
|
16
17
|
from typing import Any, Literal, TypeVar, get_type_hints, overload
|
|
17
18
|
from uuid import UUID
|
|
18
19
|
|
|
19
|
-
from pydantic import BaseModel as BaseModelV2
|
|
20
|
-
from pydantic.v1 import BaseModel as BaseModelV1
|
|
21
|
-
|
|
22
20
|
from reflex.base import Base
|
|
23
21
|
from reflex.constants.colors import Color
|
|
24
22
|
from reflex.utils import console, types
|
|
@@ -281,24 +279,13 @@ def serialize_base(value: Base) -> dict:
|
|
|
281
279
|
}
|
|
282
280
|
|
|
283
281
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
Args:
|
|
289
|
-
model: The BaseModel to serialize.
|
|
290
|
-
|
|
291
|
-
Returns:
|
|
292
|
-
The serialized BaseModel.
|
|
293
|
-
"""
|
|
294
|
-
return model.dict()
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
if BaseModelV1 is not BaseModelV2:
|
|
282
|
+
if find_spec("pydantic"):
|
|
283
|
+
from pydantic import BaseModel as BaseModelV2
|
|
284
|
+
from pydantic.v1 import BaseModel as BaseModelV1
|
|
298
285
|
|
|
299
286
|
@serializer(to=dict)
|
|
300
|
-
def
|
|
301
|
-
"""Serialize a pydantic
|
|
287
|
+
def serialize_base_model_v1(model: BaseModelV1) -> dict:
|
|
288
|
+
"""Serialize a pydantic v1 BaseModel instance.
|
|
302
289
|
|
|
303
290
|
Args:
|
|
304
291
|
model: The BaseModel to serialize.
|
|
@@ -306,7 +293,21 @@ if BaseModelV1 is not BaseModelV2:
|
|
|
306
293
|
Returns:
|
|
307
294
|
The serialized BaseModel.
|
|
308
295
|
"""
|
|
309
|
-
return model.
|
|
296
|
+
return model.dict()
|
|
297
|
+
|
|
298
|
+
if BaseModelV1 is not BaseModelV2:
|
|
299
|
+
|
|
300
|
+
@serializer(to=dict)
|
|
301
|
+
def serialize_base_model_v2(model: BaseModelV2) -> dict:
|
|
302
|
+
"""Serialize a pydantic v2 BaseModel instance.
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
model: The BaseModel to serialize.
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
The serialized BaseModel.
|
|
309
|
+
"""
|
|
310
|
+
return model.model_dump()
|
|
310
311
|
|
|
311
312
|
|
|
312
313
|
@serializer
|