sera-2 1.14.1__tar.gz → 1.14.3__tar.gz

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.
Files changed (41) hide show
  1. {sera_2-1.14.1 → sera_2-1.14.3}/PKG-INFO +3 -3
  2. {sera_2-1.14.1 → sera_2-1.14.3}/pyproject.toml +3 -3
  3. {sera_2-1.14.1 → sera_2-1.14.3}/sera/make/make_python_api.py +1 -1
  4. {sera_2-1.14.1 → sera_2-1.14.3}/sera/make/make_python_model.py +11 -10
  5. {sera_2-1.14.1 → sera_2-1.14.3}/sera/models/__init__.py +1 -8
  6. {sera_2-1.14.1 → sera_2-1.14.3}/sera/models/_class.py +1 -1
  7. {sera_2-1.14.1 → sera_2-1.14.3}/sera/models/_constraints.py +4 -0
  8. {sera_2-1.14.1 → sera_2-1.14.3}/sera/models/_module.py +5 -1
  9. {sera_2-1.14.1 → sera_2-1.14.3}/sera/models/_parse.py +8 -6
  10. {sera_2-1.14.1 → sera_2-1.14.3}/sera/models/_property.py +0 -13
  11. {sera_2-1.14.1 → sera_2-1.14.3}/README.md +0 -0
  12. {sera_2-1.14.1 → sera_2-1.14.3}/sera/__init__.py +0 -0
  13. {sera_2-1.14.1 → sera_2-1.14.3}/sera/constants.py +0 -0
  14. {sera_2-1.14.1 → sera_2-1.14.3}/sera/exports/__init__.py +0 -0
  15. {sera_2-1.14.1 → sera_2-1.14.3}/sera/exports/schema.py +0 -0
  16. {sera_2-1.14.1 → sera_2-1.14.3}/sera/exports/test.py +0 -0
  17. {sera_2-1.14.1 → sera_2-1.14.3}/sera/libs/__init__.py +0 -0
  18. {sera_2-1.14.1 → sera_2-1.14.3}/sera/libs/api_helper.py +0 -0
  19. {sera_2-1.14.1 → sera_2-1.14.3}/sera/libs/api_test_helper.py +0 -0
  20. {sera_2-1.14.1 → sera_2-1.14.3}/sera/libs/base_orm.py +0 -0
  21. {sera_2-1.14.1 → sera_2-1.14.3}/sera/libs/base_service.py +0 -0
  22. {sera_2-1.14.1 → sera_2-1.14.3}/sera/libs/dag/__init__.py +0 -0
  23. {sera_2-1.14.1 → sera_2-1.14.3}/sera/libs/dag/_dag.py +0 -0
  24. {sera_2-1.14.1 → sera_2-1.14.3}/sera/libs/middlewares/__init__.py +0 -0
  25. {sera_2-1.14.1 → sera_2-1.14.3}/sera/libs/middlewares/auth.py +0 -0
  26. {sera_2-1.14.1 → sera_2-1.14.3}/sera/libs/middlewares/uscp.py +0 -0
  27. {sera_2-1.14.1 → sera_2-1.14.3}/sera/make/__init__.py +0 -0
  28. {sera_2-1.14.1 → sera_2-1.14.3}/sera/make/__main__.py +0 -0
  29. {sera_2-1.14.1 → sera_2-1.14.3}/sera/make/make_app.py +0 -0
  30. {sera_2-1.14.1 → sera_2-1.14.3}/sera/make/make_python_services.py +0 -0
  31. {sera_2-1.14.1 → sera_2-1.14.3}/sera/make/make_typescript_model.py +0 -0
  32. {sera_2-1.14.1 → sera_2-1.14.3}/sera/misc/__init__.py +0 -0
  33. {sera_2-1.14.1 → sera_2-1.14.3}/sera/misc/_formatter.py +0 -0
  34. {sera_2-1.14.1 → sera_2-1.14.3}/sera/misc/_utils.py +0 -0
  35. {sera_2-1.14.1 → sera_2-1.14.3}/sera/models/_collection.py +0 -0
  36. {sera_2-1.14.1 → sera_2-1.14.3}/sera/models/_datatype.py +0 -0
  37. {sera_2-1.14.1 → sera_2-1.14.3}/sera/models/_default.py +0 -0
  38. {sera_2-1.14.1 → sera_2-1.14.3}/sera/models/_enum.py +0 -0
  39. {sera_2-1.14.1 → sera_2-1.14.3}/sera/models/_multi_lingual_string.py +0 -0
  40. {sera_2-1.14.1 → sera_2-1.14.3}/sera/models/_schema.py +0 -0
  41. {sera_2-1.14.1 → sera_2-1.14.3}/sera/typing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sera-2
3
- Version: 1.14.1
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 (>=25.1.0,<26.0.0)
11
+ Requires-Dist: black (==25.1.0)
12
12
  Requires-Dist: codegen-2 (>=2.11.1,<3.0.0)
13
- Requires-Dist: isort (>=6.0.1,<7.0.0)
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)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "sera-2"
3
- version = "1.14.1"
3
+ version = "1.14.3"
4
4
  description = ""
5
5
  authors = ["Binh Vu <bvu687@gmail.com>"]
6
6
  readme = "README.md"
@@ -14,9 +14,9 @@ msgspec = "^0.19.0"
14
14
  litestar = "^2.15.1"
15
15
  loguru = "^0.7.0"
16
16
  typer = "^0.12.3"
17
- black = "^25.1.0"
17
+ black = "==25.1.0"
18
18
  sqlalchemy = { extras = ["asyncio"], version = "^2.0.41" }
19
- isort = "^6.0.1"
19
+ isort = "==6.0.1"
20
20
  serde2 = "^1.9.0"
21
21
 
22
22
  [build-system]
@@ -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, SystemControlledMode
9
+ from sera.models import App, DataCollection, Module, Package
10
10
  from sera.typing import GLOBAL_IDENTS
11
11
 
12
12
 
@@ -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"Mapping[str, {custom_type.target.name}]"
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"Sequence[str, {custom_type.target.name}]"
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
- cls_ast = program.root.class_(
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
- proptype = f"Mapped[{prop.target.name}]"
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":
@@ -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
  ]
@@ -63,7 +63,7 @@ class Class:
63
63
  return prop
64
64
  assert (
65
65
  self.db is None
66
- ), "This class is stored in the database and thus, must have a primary key"
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:
@@ -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
  }
@@ -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(code, profile="black")
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
@@ -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
- values[k] = EnumValue(
98
- name=k,
99
- value=v["value"],
100
- description=_parse_multi_lingual_string(v.get("desc", "")),
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
 
@@ -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
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes