sera-2 1.14.1__py3-none-any.whl → 1.14.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.
- sera/make/make_python_api.py +1 -1
- sera/make/make_python_model.py +11 -10
- sera/models/__init__.py +1 -8
- sera/models/_class.py +1 -1
- sera/models/_constraints.py +4 -0
- sera/models/_module.py +5 -1
- sera/models/_parse.py +8 -6
- sera/models/_property.py +0 -13
- {sera_2-1.14.1.dist-info → sera_2-1.14.3.dist-info}/METADATA +3 -3
- {sera_2-1.14.1.dist-info → sera_2-1.14.3.dist-info}/RECORD +11 -11
- {sera_2-1.14.1.dist-info → sera_2-1.14.3.dist-info}/WHEEL +0 -0
sera/make/make_python_api.py
CHANGED
@@ -6,7 +6,7 @@ from codegen.models import DeferredVar, ImportHelper, PredefinedFn, Program, exp
|
|
6
6
|
from loguru import logger
|
7
7
|
|
8
8
|
from sera.misc import assert_not_null, to_snake_case
|
9
|
-
from sera.models import App, DataCollection, Module, Package
|
9
|
+
from sera.models import App, DataCollection, Module, Package
|
10
10
|
from sera.typing import GLOBAL_IDENTS
|
11
11
|
|
12
12
|
|
sera/make/make_python_model.py
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
import sys
|
4
|
-
from ast import Not
|
5
3
|
from typing import Callable, Literal, Optional, Sequence
|
6
4
|
|
7
5
|
from codegen.models import (
|
@@ -29,7 +27,6 @@ from sera.models import (
|
|
29
27
|
PyTypeWithDep,
|
30
28
|
Schema,
|
31
29
|
)
|
32
|
-
from sera.models._property import SystemControlledMode
|
33
30
|
from sera.typing import GLOBAL_IDENTS, ObjectPath
|
34
31
|
|
35
32
|
|
@@ -937,14 +934,12 @@ def make_python_relational_model(
|
|
937
934
|
|
938
935
|
if custom_type.cardinality.is_star_to_many():
|
939
936
|
if custom_type.is_map:
|
940
|
-
program.import_("typing.Mapping", True)
|
941
937
|
program.import_("sera.libs.base_orm.DictDataclassType", True)
|
942
|
-
type = f"
|
938
|
+
type = f"dict[str, {custom_type.target.name}]"
|
943
939
|
maptype = f"DictDataclassType({custom_type.target.name})"
|
944
940
|
else:
|
945
|
-
program.import_("typing.Sequence", True)
|
946
941
|
program.import_("sera.libs.base_orm.ListDataclassType", True)
|
947
|
-
type = f"
|
942
|
+
type = f"list[{custom_type.target.name}]"
|
948
943
|
maptype = f"ListDataclassType({custom_type.target.name})"
|
949
944
|
else:
|
950
945
|
program.import_("sera.libs.base_orm.DataclassType", True)
|
@@ -957,7 +952,7 @@ def make_python_relational_model(
|
|
957
952
|
|
958
953
|
type_map.append((expr.ExprIdent(type), expr.ExprIdent(maptype)))
|
959
954
|
|
960
|
-
|
955
|
+
program.root.class_(
|
961
956
|
"Base", [expr.ExprIdent("DeclarativeBase"), expr.ExprIdent("BaseORM")]
|
962
957
|
)(
|
963
958
|
stmt.DefClassVarStatement(
|
@@ -1246,7 +1241,7 @@ def make_python_relational_object_property(
|
|
1246
1241
|
return
|
1247
1242
|
|
1248
1243
|
if prop.cardinality.is_star_to_many():
|
1249
|
-
raise NotImplementedError()
|
1244
|
+
raise NotImplementedError((cls.name, prop.name))
|
1250
1245
|
|
1251
1246
|
# we store this class in the database
|
1252
1247
|
propname = f"{prop.name}_id"
|
@@ -1291,7 +1286,13 @@ def make_python_relational_object_property(
|
|
1291
1286
|
is_import_attr=True,
|
1292
1287
|
)
|
1293
1288
|
propname = prop.name
|
1294
|
-
|
1289
|
+
if prop.cardinality.is_star_to_many():
|
1290
|
+
if prop.is_map:
|
1291
|
+
proptype = f"Mapped[dict[str, {prop.target.name}]]"
|
1292
|
+
else:
|
1293
|
+
proptype = f"Mapped[list[{prop.target.name}]]"
|
1294
|
+
else:
|
1295
|
+
proptype = f"Mapped[{prop.target.name}]"
|
1295
1296
|
|
1296
1297
|
# we have two choices, one is to create a composite class, one is to create a custom field
|
1297
1298
|
if prop.db.is_embedded == "composite":
|
sera/models/__init__.py
CHANGED
@@ -5,13 +5,7 @@ from sera.models._enum import Enum
|
|
5
5
|
from sera.models._module import App, Module, Package
|
6
6
|
from sera.models._multi_lingual_string import MultiLingualString
|
7
7
|
from sera.models._parse import parse_schema
|
8
|
-
from sera.models._property import
|
9
|
-
Cardinality,
|
10
|
-
DataProperty,
|
11
|
-
ObjectProperty,
|
12
|
-
Property,
|
13
|
-
SystemControlledMode,
|
14
|
-
)
|
8
|
+
from sera.models._property import Cardinality, DataProperty, ObjectProperty, Property
|
15
9
|
from sera.models._schema import Schema
|
16
10
|
|
17
11
|
__all__ = [
|
@@ -31,5 +25,4 @@ __all__ = [
|
|
31
25
|
"PyTypeWithDep",
|
32
26
|
"TsTypeWithDep",
|
33
27
|
"Enum",
|
34
|
-
"SystemControlledMode",
|
35
28
|
]
|
sera/models/_class.py
CHANGED
@@ -63,7 +63,7 @@ class Class:
|
|
63
63
|
return prop
|
64
64
|
assert (
|
65
65
|
self.db is None
|
66
|
-
), "
|
66
|
+
), f"The class {self.name} is stored in the database and thus, must have a primary key"
|
67
67
|
return None
|
68
68
|
|
69
69
|
def get_pymodule_name(self) -> str:
|
sera/models/_constraints.py
CHANGED
@@ -4,6 +4,7 @@ from dataclasses import dataclass
|
|
4
4
|
from typing import Literal
|
5
5
|
|
6
6
|
ConstraintName = Literal[
|
7
|
+
"url",
|
7
8
|
"phone_number",
|
8
9
|
"email",
|
9
10
|
"not_empty",
|
@@ -37,6 +38,8 @@ class Constraint:
|
|
37
38
|
return "msgspec.Meta(ge=0)"
|
38
39
|
elif self.name == "positive_number":
|
39
40
|
return "msgspec.Meta(gt=0)"
|
41
|
+
elif self.name == "url":
|
42
|
+
return r"msgspec.Meta(pattern=r'^(https?|ftp)://[^\s/$.?#].[^\s]*$')"
|
40
43
|
|
41
44
|
raise NotImplementedError()
|
42
45
|
|
@@ -57,4 +60,5 @@ predefined_constraints: dict[ConstraintName, Constraint] = {
|
|
57
60
|
"password": Constraint("password", ()),
|
58
61
|
"whole_number": Constraint("whole_number", ()),
|
59
62
|
"positive_number": Constraint("positive_number", ()),
|
63
|
+
"url": Constraint("url", ()),
|
60
64
|
}
|
sera/models/_module.py
CHANGED
@@ -10,6 +10,7 @@ import black.mode
|
|
10
10
|
import isort
|
11
11
|
from codegen.models import Program
|
12
12
|
from loguru import logger
|
13
|
+
|
13
14
|
from sera.misc import File, Formatter
|
14
15
|
from sera.typing import Language
|
15
16
|
|
@@ -62,7 +63,9 @@ class Module:
|
|
62
63
|
target_versions={black.mode.TargetVersion.PY312},
|
63
64
|
),
|
64
65
|
)
|
65
|
-
code = isort.code(
|
66
|
+
code = isort.code(
|
67
|
+
code, profile="black", known_first_party=[self.package.app.name]
|
68
|
+
)
|
66
69
|
except:
|
67
70
|
logger.error("Error writing module {}", self.path)
|
68
71
|
print(">>> Program")
|
@@ -173,3 +176,4 @@ class App:
|
|
173
176
|
def name(self) -> str:
|
174
177
|
"""Get the name of the application"""
|
175
178
|
return self.root.dir.name
|
179
|
+
return self.root.dir.name
|
sera/models/_parse.py
CHANGED
@@ -34,7 +34,6 @@ from sera.models._property import (
|
|
34
34
|
ObjectProperty,
|
35
35
|
PropDataAttrs,
|
36
36
|
SystemControlledAttrs,
|
37
|
-
SystemControlledMode,
|
38
37
|
)
|
39
38
|
from sera.models._schema import Schema
|
40
39
|
|
@@ -94,11 +93,14 @@ def _parse_enum(schema: Schema, enum_name: str, enum: dict) -> Enum:
|
|
94
93
|
name=k, value=v, description=MultiLingualString.en("")
|
95
94
|
)
|
96
95
|
else:
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
96
|
+
try:
|
97
|
+
values[k] = EnumValue(
|
98
|
+
name=k,
|
99
|
+
value=v["value"],
|
100
|
+
description=_parse_multi_lingual_string(v.get("desc", "")),
|
101
|
+
)
|
102
|
+
except KeyError as e:
|
103
|
+
raise ValueError(f"Invalid enum value definition for {k}: {v}") from e
|
102
104
|
return Enum(name=enum_name, values=values)
|
103
105
|
|
104
106
|
|
sera/models/_property.py
CHANGED
@@ -56,19 +56,6 @@ class Cardinality(str, Enum):
|
|
56
56
|
]
|
57
57
|
|
58
58
|
|
59
|
-
class SystemControlledMode(str, Enum):
|
60
|
-
"""Indicates if this property is controlled by the system.
|
61
|
-
|
62
|
-
There are two modes:
|
63
|
-
1. The system automatically sets the value, and users cannot modify it.
|
64
|
-
2. Users with special roles are allowed to set the value and other users cannot modify it
|
65
|
-
"""
|
66
|
-
|
67
|
-
AUTO = "auto"
|
68
|
-
RESTRICTED = "restricted"
|
69
|
-
NO = "no"
|
70
|
-
|
71
|
-
|
72
59
|
@dataclass(kw_only=True)
|
73
60
|
class GetSCPropValueFunc:
|
74
61
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: sera-2
|
3
|
-
Version: 1.14.
|
3
|
+
Version: 1.14.3
|
4
4
|
Summary:
|
5
5
|
Author: Binh Vu
|
6
6
|
Author-email: bvu687@gmail.com
|
@@ -8,9 +8,9 @@ Requires-Python: >=3.12,<4.0
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
9
9
|
Classifier: Programming Language :: Python :: 3.12
|
10
10
|
Classifier: Programming Language :: Python :: 3.13
|
11
|
-
Requires-Dist: black (
|
11
|
+
Requires-Dist: black (==25.1.0)
|
12
12
|
Requires-Dist: codegen-2 (>=2.11.1,<3.0.0)
|
13
|
-
Requires-Dist: isort (
|
13
|
+
Requires-Dist: isort (==6.0.1)
|
14
14
|
Requires-Dist: litestar (>=2.15.1,<3.0.0)
|
15
15
|
Requires-Dist: loguru (>=0.7.0,<0.8.0)
|
16
16
|
Requires-Dist: msgspec (>=0.19.0,<0.20.0)
|
@@ -16,26 +16,26 @@ sera/libs/middlewares/uscp.py,sha256=H5umW8iEQSCdb_MJ5Im49kxg1E7TpxSg1p2_2A5zI1U
|
|
16
16
|
sera/make/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
17
|
sera/make/__main__.py,sha256=bt-gDF8E026OWc2zqr9_a3paMOiDkFd3ybWn8ltL2g0,1448
|
18
18
|
sera/make/make_app.py,sha256=n9NtW73O3s_5Q31VHIRmnd-jEIcpDO7ksAsOdovde2s,5999
|
19
|
-
sera/make/make_python_api.py,sha256=
|
20
|
-
sera/make/make_python_model.py,sha256=
|
19
|
+
sera/make/make_python_api.py,sha256=iXGbKQ3IJvsY1ur_fhurr_THFNnH66E3Wl85o0emUbw,26853
|
20
|
+
sera/make/make_python_model.py,sha256=pv8gkWE4kIexjTfmtc5GG4Pg2kR9yA3Urnqal1RJ6WI,61430
|
21
21
|
sera/make/make_python_services.py,sha256=0ZpWLwQ7Nwfn8BXAikAB4JRpNknpSJyJgY5b1cjtxV4,2073
|
22
22
|
sera/make/make_typescript_model.py,sha256=ugDdSTw_1ayHLuL--92RQ8hf_D-dpJtnvmUZNxcwcDs,63687
|
23
23
|
sera/misc/__init__.py,sha256=Dh4uDq0D4N53h3zhvmwfa5a0TPVRSUvLzb0hkFuPirk,411
|
24
24
|
sera/misc/_formatter.py,sha256=aCGYL08l8f3aLODHxSocxBBwkRYEo3K1QzCDEn3suj0,1685
|
25
25
|
sera/misc/_utils.py,sha256=V5g4oLGHOhUCR75Kkcn1w01pAvGvaepK-T8Z3pIgHjI,1450
|
26
|
-
sera/models/__init__.py,sha256=
|
27
|
-
sera/models/_class.py,sha256=
|
26
|
+
sera/models/__init__.py,sha256=vJC5Kzo_N7wd16ocNPy1VvAZDGNiWeiAhWJ4ihATKvA,780
|
27
|
+
sera/models/_class.py,sha256=9XSnJli2SGF-jm-v0swsfY6-omiQ5Xeh33R2pM9Kg_g,2526
|
28
28
|
sera/models/_collection.py,sha256=ZnQEriKC4X88Zz48Kn1AVZKH-1_l8OgWa-zf2kcQOOE,1414
|
29
|
-
sera/models/_constraints.py,sha256=
|
29
|
+
sera/models/_constraints.py,sha256=RpWDU-TfCslXaMUaTG9utWbl5z8Z6nzvF_fhqlek6ew,1987
|
30
30
|
sera/models/_datatype.py,sha256=y5kfim0G3gLhnGjiokFBr8leU1Y6as_Vw7oK-caOo68,7140
|
31
31
|
sera/models/_default.py,sha256=ABggW6qdPR4ZDqIPJdJ0GCGQ-7kfsfZmQ_DchgZEa-I,137
|
32
32
|
sera/models/_enum.py,sha256=sy0q7E646F-APsqrVQ52r1fAQ_DCAeaNq5YM5QN3zIk,2070
|
33
|
-
sera/models/_module.py,sha256=
|
33
|
+
sera/models/_module.py,sha256=I-GfnTgAa-5R87qTAvEzOt-VVEGeFBBwubGCgUkXVSw,5159
|
34
34
|
sera/models/_multi_lingual_string.py,sha256=JETN6k00VH4wrA4w5vAHMEJV8fp3SY9bJebskFTjQLA,1186
|
35
|
-
sera/models/_parse.py,sha256=
|
36
|
-
sera/models/_property.py,sha256=
|
35
|
+
sera/models/_parse.py,sha256=ohexBbjFv6A1wZsEtokfw0zMVoR-RGXYrXa_tAub_Vs,12147
|
36
|
+
sera/models/_property.py,sha256=Y98bYIjuCQDcSWpDxERNIFgmxXIaJiwBNFtYeGbDYRE,6812
|
37
37
|
sera/models/_schema.py,sha256=VxJEiqgVvbXgcSUK4UW6JnRcggk4nsooVSE6MyXmfNY,1636
|
38
38
|
sera/typing.py,sha256=Fl4-UzLJu1GdLLk_g87fA7nT9wQGelNnGzag6dg_0gs,980
|
39
|
-
sera_2-1.14.
|
40
|
-
sera_2-1.14.
|
41
|
-
sera_2-1.14.
|
39
|
+
sera_2-1.14.3.dist-info/METADATA,sha256=-PIatY73pPVkjplx7zJAXHmtRcyQFIMEMIu9Manov6M,852
|
40
|
+
sera_2-1.14.3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
41
|
+
sera_2-1.14.3.dist-info/RECORD,,
|
File without changes
|