exdrf 0.0.1.dev0__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.
- exdrf/__init__.py +0 -0
- exdrf/__version__.py +24 -0
- exdrf/api.py +51 -0
- exdrf/constants.py +30 -0
- exdrf/dataset.py +197 -0
- exdrf/field.py +554 -0
- exdrf/field_types/__init__.py +0 -0
- exdrf/field_types/api.py +78 -0
- exdrf/field_types/blob_field.py +44 -0
- exdrf/field_types/bool_field.py +47 -0
- exdrf/field_types/date_field.py +49 -0
- exdrf/field_types/date_time.py +52 -0
- exdrf/field_types/dur_field.py +44 -0
- exdrf/field_types/enum_field.py +41 -0
- exdrf/field_types/filter_field.py +11 -0
- exdrf/field_types/float_field.py +85 -0
- exdrf/field_types/float_list.py +18 -0
- exdrf/field_types/formatted.py +39 -0
- exdrf/field_types/int_field.py +70 -0
- exdrf/field_types/int_list.py +18 -0
- exdrf/field_types/ref_base.py +105 -0
- exdrf/field_types/ref_m2m.py +39 -0
- exdrf/field_types/ref_m2o.py +23 -0
- exdrf/field_types/ref_o2m.py +36 -0
- exdrf/field_types/ref_o2o.py +32 -0
- exdrf/field_types/sort_field.py +18 -0
- exdrf/field_types/str_field.py +77 -0
- exdrf/field_types/str_list.py +18 -0
- exdrf/field_types/time_field.py +49 -0
- exdrf/filter.py +653 -0
- exdrf/filter_dsl.py +950 -0
- exdrf/filter_op_catalog.py +222 -0
- exdrf/label_dsl.py +691 -0
- exdrf/moment.py +496 -0
- exdrf/py.typed +0 -0
- exdrf/py_support.py +21 -0
- exdrf/resource.py +901 -0
- exdrf/sa_fi_item.py +69 -0
- exdrf/sa_filter_op.py +324 -0
- exdrf/utils.py +17 -0
- exdrf/validator.py +45 -0
- exdrf/var_bag.py +328 -0
- exdrf/visitor.py +58 -0
- exdrf-0.0.1.dev0.dist-info/METADATA +42 -0
- exdrf-0.0.1.dev0.dist-info/RECORD +57 -0
- exdrf-0.0.1.dev0.dist-info/WHEEL +5 -0
- exdrf-0.0.1.dev0.dist-info/top_level.txt +3 -0
- exdrf_tests/__init__.py +0 -0
- exdrf_tests/test_dataset.py +422 -0
- exdrf_tests/test_field.py +109 -0
- exdrf_tests/test_filter.py +425 -0
- exdrf_tests/test_filter_dsl.py +556 -0
- exdrf_tests/test_label_dsl.py +234 -0
- exdrf_tests/test_resource.py +107 -0
- exdrf_tests/test_utils.py +43 -0
- exdrf_tests/test_visitor.py +31 -0
- exdrf_tests/var_bag_test.py +502 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
2
|
+
|
|
3
|
+
from attrs import define, field
|
|
4
|
+
|
|
5
|
+
from exdrf.constants import FIELD_TYPE_REF_ONE_TO_MANY
|
|
6
|
+
from exdrf.field_types.ref_base import RefBaseField
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from exdrf.resource import ExResource
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@define
|
|
13
|
+
class RefOneToManyField(RefBaseField):
|
|
14
|
+
"""This type of field is created by OneToMany relations.
|
|
15
|
+
|
|
16
|
+
In this type of relation there is one item of the present resource
|
|
17
|
+
that is related to many items of the related resource. Expect the foreign
|
|
18
|
+
key to be in the *related* resource.
|
|
19
|
+
|
|
20
|
+
It is asserted that in this case the `is_list` attribute is set to
|
|
21
|
+
`True`.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
type_name: str = field(default=FIELD_TYPE_REF_ONE_TO_MANY)
|
|
25
|
+
is_list: bool = field(default=True)
|
|
26
|
+
subordinate: bool = field(default=False)
|
|
27
|
+
bridge: Optional["ExResource"] = field(default=None)
|
|
28
|
+
|
|
29
|
+
def field_properties(self, explicit: bool = False) -> dict[str, Any]:
|
|
30
|
+
result = super().field_properties(explicit)
|
|
31
|
+
if self.subordinate or explicit:
|
|
32
|
+
result["subordinate"] = self.subordinate
|
|
33
|
+
return result
|
|
34
|
+
|
|
35
|
+
def __repr__(self) -> str:
|
|
36
|
+
return f"O2M({self.ref.name})"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from attrs import define, field
|
|
4
|
+
|
|
5
|
+
from exdrf.constants import FIELD_TYPE_REF_ONE_TO_ONE
|
|
6
|
+
from exdrf.field_types.ref_base import RefBaseField
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@define
|
|
10
|
+
class RefOneToOneField(RefBaseField):
|
|
11
|
+
"""This type of field is created by OneToOne relations.
|
|
12
|
+
|
|
13
|
+
In this type of relation there is one item of the present resource
|
|
14
|
+
that is related to one item of the related resource. The foreign key mey
|
|
15
|
+
be in either the present, in the related resource but *not in both*.
|
|
16
|
+
|
|
17
|
+
It is asserted that in this case the `is_list` attribute is set to
|
|
18
|
+
`False`.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
type_name: str = field(default=FIELD_TYPE_REF_ONE_TO_ONE)
|
|
22
|
+
is_list: bool = field(default=False)
|
|
23
|
+
subordinate: bool = field(default=False)
|
|
24
|
+
|
|
25
|
+
def field_properties(self, explicit: bool = False) -> dict[str, Any]:
|
|
26
|
+
result = super().field_properties(explicit)
|
|
27
|
+
if self.subordinate or explicit:
|
|
28
|
+
result["subordinate"] = self.subordinate
|
|
29
|
+
return result
|
|
30
|
+
|
|
31
|
+
def __repr__(self) -> str:
|
|
32
|
+
return f"O2O({self.ref.name})"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, List
|
|
2
|
+
|
|
3
|
+
from attrs import define, field
|
|
4
|
+
|
|
5
|
+
from exdrf.constants import FIELD_TYPE_SORT
|
|
6
|
+
from exdrf.field import ExField
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from exdrf.dataset import ExDataset
|
|
10
|
+
from exdrf.resource import ExResource
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@define
|
|
14
|
+
class SortField(ExField):
|
|
15
|
+
type_name: str = field(default=FIELD_TYPE_SORT)
|
|
16
|
+
|
|
17
|
+
def extra_ref(self, d_set: "ExDataset") -> List["ExResource"]:
|
|
18
|
+
return [d_set["SortItem"]]
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from typing import Any, List, Optional, Tuple
|
|
2
|
+
|
|
3
|
+
from attrs import define, field
|
|
4
|
+
from pydantic import Field, field_validator
|
|
5
|
+
|
|
6
|
+
from exdrf.constants import FIELD_TYPE_STRING
|
|
7
|
+
from exdrf.field import ExField, FieldInfo
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@define
|
|
11
|
+
class StrField(ExField):
|
|
12
|
+
"""A field that stores strings.
|
|
13
|
+
|
|
14
|
+
Attributes:
|
|
15
|
+
multiline: Whether the string can span multiple lines.
|
|
16
|
+
min_length: The minimum length of the string.
|
|
17
|
+
max_length: The maximum length of the string.
|
|
18
|
+
enum_values: The list of predefined (named) values for the field. The
|
|
19
|
+
first element of the tuple is the value, the second element is the
|
|
20
|
+
display name.
|
|
21
|
+
no_dia_field: The name of the field that is used to store the value
|
|
22
|
+
of this field without diacritics.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
type_name: str = field(default=FIELD_TYPE_STRING)
|
|
26
|
+
|
|
27
|
+
multiline: bool = field(default=False)
|
|
28
|
+
min_length: int = field(default=None)
|
|
29
|
+
max_length: int = field(default=None)
|
|
30
|
+
enum_values: List[Tuple[str, str]] = field(factory=list)
|
|
31
|
+
|
|
32
|
+
no_dia_field: Optional["ExField"] = field(default=None)
|
|
33
|
+
|
|
34
|
+
def __repr__(self) -> str:
|
|
35
|
+
return f"StrF({self.resource.name}.{self.name})"
|
|
36
|
+
|
|
37
|
+
def field_properties(self, explicit: bool = False) -> dict[str, Any]:
|
|
38
|
+
result = super().field_properties(explicit)
|
|
39
|
+
if self.multiline or explicit:
|
|
40
|
+
result["multiline"] = self.multiline
|
|
41
|
+
if self.min_length is not None or explicit:
|
|
42
|
+
result["min_length"] = self.min_length
|
|
43
|
+
if self.max_length is not None or explicit:
|
|
44
|
+
result["max_length"] = self.max_length
|
|
45
|
+
if self.enum_values or explicit:
|
|
46
|
+
result["enum_values"] = self.enum_values
|
|
47
|
+
return result
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class StrInfo(FieldInfo):
|
|
51
|
+
"""Parser for information about a string field.
|
|
52
|
+
|
|
53
|
+
Attributes:
|
|
54
|
+
multiline: Whether the string can span multiple lines.
|
|
55
|
+
min_length: The minimum length of the string.
|
|
56
|
+
max_length: The maximum length of the string. Note that providing a
|
|
57
|
+
value for this attribute will override the derived value from the
|
|
58
|
+
database column (like `VARCHAR(255)`; see `field_from_sql_col()`
|
|
59
|
+
implementation).
|
|
60
|
+
enum_values: The list of predefined (named) values for the field. The
|
|
61
|
+
first element of the tuple is the value, the second element is the
|
|
62
|
+
display name.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
multiline: Optional[bool] = None
|
|
66
|
+
min_length: Optional[int] = None
|
|
67
|
+
max_length: Optional[int] = None
|
|
68
|
+
enum_values: List[Tuple[str, str]] = Field(default_factory=list)
|
|
69
|
+
|
|
70
|
+
@field_validator("enum_values", mode="before")
|
|
71
|
+
@classmethod
|
|
72
|
+
def validate_enum_values(cls, v):
|
|
73
|
+
"""Validate the enum values.
|
|
74
|
+
|
|
75
|
+
Accepts either a list of (int, str) tuples or an Enum class.
|
|
76
|
+
"""
|
|
77
|
+
return cls.validate_enum_with_type(v, str)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from attrs import define, field
|
|
2
|
+
|
|
3
|
+
from exdrf.constants import FIELD_TYPE_STRING_LIST
|
|
4
|
+
from exdrf.field_types.str_field import StrField, StrInfo
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@define
|
|
8
|
+
class StrListField(StrField):
|
|
9
|
+
"""A field that stores list of strings."""
|
|
10
|
+
|
|
11
|
+
type_name: str = field(default=FIELD_TYPE_STRING_LIST)
|
|
12
|
+
|
|
13
|
+
def __repr__(self) -> str:
|
|
14
|
+
return f"SListF({self.resource.name}.{self.name})"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class StrListInfo(StrInfo):
|
|
18
|
+
"""Parser for information about a string-list field."""
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from datetime import time
|
|
2
|
+
from typing import Any, Optional
|
|
3
|
+
|
|
4
|
+
from attrs import define, field
|
|
5
|
+
|
|
6
|
+
from exdrf.constants import FIELD_TYPE_TIME
|
|
7
|
+
from exdrf.field import ExField, FieldInfo
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@define
|
|
11
|
+
class TimeField(ExField):
|
|
12
|
+
"""A field that stores a time of day (without a date)
|
|
13
|
+
|
|
14
|
+
Attributes:
|
|
15
|
+
min: The minimum time that can be stored in the field.
|
|
16
|
+
max: The maximum time that can be stored in the field.
|
|
17
|
+
format: The format of the time string.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
type_name: str = field(default=FIELD_TYPE_TIME)
|
|
21
|
+
|
|
22
|
+
min: time = field(default=None)
|
|
23
|
+
max: time = field(default=None)
|
|
24
|
+
format: str = field(default="HH:mm:ss")
|
|
25
|
+
|
|
26
|
+
def __repr__(self) -> str:
|
|
27
|
+
return f"TimeF({self.resource.name}.{self.name})"
|
|
28
|
+
|
|
29
|
+
def field_properties(self, explicit: bool = False) -> dict[str, Any]:
|
|
30
|
+
result = super().field_properties(explicit)
|
|
31
|
+
if self.min is not None or explicit:
|
|
32
|
+
result["min"] = self.min
|
|
33
|
+
if self.max is not None or explicit:
|
|
34
|
+
result["max"] = self.max
|
|
35
|
+
if self.format or explicit:
|
|
36
|
+
result["format"] = self.format
|
|
37
|
+
return result
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class TimeInfo(FieldInfo):
|
|
41
|
+
"""Parser for information about a date-time field.
|
|
42
|
+
|
|
43
|
+
Attributes:
|
|
44
|
+
min: The minimum time that can be stored in the field.
|
|
45
|
+
max: The maximum time that can be stored in the field.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
min: Optional[time] = None
|
|
49
|
+
max: Optional[time] = None
|