industrial-model 0.1.0__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.
- industrial_model/__init__.py +27 -0
- industrial_model/cognite_adapters/__init__.py +56 -0
- industrial_model/cognite_adapters/filter_mapper.py +99 -0
- industrial_model/cognite_adapters/optimizer.py +74 -0
- industrial_model/cognite_adapters/query_mapper.py +181 -0
- industrial_model/cognite_adapters/query_result_mapper.py +216 -0
- industrial_model/cognite_adapters/schemas.py +121 -0
- industrial_model/cognite_adapters/sort_mapper.py +21 -0
- industrial_model/cognite_adapters/utils.py +33 -0
- industrial_model/cognite_adapters/view_mapper.py +16 -0
- industrial_model/config.py +10 -0
- industrial_model/constants.py +24 -0
- industrial_model/engines/__init__.py +4 -0
- industrial_model/engines/async_engine.py +37 -0
- industrial_model/engines/engine.py +62 -0
- industrial_model/models/__init__.py +19 -0
- industrial_model/models/base.py +46 -0
- industrial_model/models/entities.py +55 -0
- industrial_model/py.typed +0 -0
- industrial_model/queries/__init__.py +10 -0
- industrial_model/queries/models.py +37 -0
- industrial_model/queries/params.py +42 -0
- industrial_model/statements/__init__.py +70 -0
- industrial_model/statements/expressions.py +165 -0
- industrial_model/utils.py +38 -0
- industrial_model-0.1.0.dist-info/METADATA +23 -0
- industrial_model-0.1.0.dist-info/RECORD +28 -0
- industrial_model-0.1.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
from abc import ABC
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from industrial_model.constants import (
|
|
7
|
+
BOOL_EXPRESSION_OPERATORS,
|
|
8
|
+
LEAF_EXPRESSION_OPERATORS,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
RANGE_SUPPORTED_VALUES = str | int | float
|
|
12
|
+
LIST_SUPPORTED_VALUES = (
|
|
13
|
+
list[str] | list[int] | list[float] | list[dict[str, str]]
|
|
14
|
+
)
|
|
15
|
+
SUPPORTED_VALUES = (
|
|
16
|
+
RANGE_SUPPORTED_VALUES | bool | dict[str, str] | LIST_SUPPORTED_VALUES
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Expression(ABC):
|
|
21
|
+
operator: str
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(frozen=True)
|
|
25
|
+
class BoolExpression(Expression):
|
|
26
|
+
filters: list[Expression]
|
|
27
|
+
operator: BOOL_EXPRESSION_OPERATORS
|
|
28
|
+
|
|
29
|
+
def __and__(self, other: "BoolExpression | LeafExpression") -> bool:
|
|
30
|
+
return and_(self, other)
|
|
31
|
+
|
|
32
|
+
def __or__(self, other: "BoolExpression | LeafExpression") -> bool:
|
|
33
|
+
return or_(self, other)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(frozen=True)
|
|
37
|
+
class LeafExpression(Expression):
|
|
38
|
+
property: str
|
|
39
|
+
operator: LEAF_EXPRESSION_OPERATORS
|
|
40
|
+
value: Any
|
|
41
|
+
|
|
42
|
+
def __and__(self, other: "BoolExpression | LeafExpression") -> bool:
|
|
43
|
+
return and_(self, other)
|
|
44
|
+
|
|
45
|
+
def __or__(self, other: "BoolExpression | LeafExpression") -> bool:
|
|
46
|
+
return or_(self, other)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class Column:
|
|
50
|
+
def __init__(self, property: Any):
|
|
51
|
+
assert isinstance(property, str | Column)
|
|
52
|
+
property_ = (
|
|
53
|
+
property.property if isinstance(property, Column) else property
|
|
54
|
+
)
|
|
55
|
+
self.property: str = property_
|
|
56
|
+
|
|
57
|
+
def __hash__(self) -> int:
|
|
58
|
+
return hash(self.property)
|
|
59
|
+
|
|
60
|
+
def __eq__(self, other: Any) -> bool:
|
|
61
|
+
if other is None:
|
|
62
|
+
return self.not_exists_()
|
|
63
|
+
|
|
64
|
+
return self.equals_(other)
|
|
65
|
+
|
|
66
|
+
def __ne__(self, other: Any) -> bool:
|
|
67
|
+
if other is None:
|
|
68
|
+
return self.exists_()
|
|
69
|
+
|
|
70
|
+
return self.not_("==", other)
|
|
71
|
+
|
|
72
|
+
def __lt__(self, other: Any) -> bool:
|
|
73
|
+
return self.lt_(other)
|
|
74
|
+
|
|
75
|
+
def __le__(self, other: Any) -> bool:
|
|
76
|
+
return self.lte_(other)
|
|
77
|
+
|
|
78
|
+
def __gt__(self, other: Any) -> bool:
|
|
79
|
+
return self.gt_(other)
|
|
80
|
+
|
|
81
|
+
def __ge__(self, other: Any) -> bool:
|
|
82
|
+
return self.gte_(other)
|
|
83
|
+
|
|
84
|
+
def equals_(self, other: SUPPORTED_VALUES) -> bool:
|
|
85
|
+
return self._compare("==", other)
|
|
86
|
+
|
|
87
|
+
def prefix(self, other: str) -> bool:
|
|
88
|
+
return self._compare("prefix", other)
|
|
89
|
+
|
|
90
|
+
def lt_(self, other: RANGE_SUPPORTED_VALUES | datetime.datetime) -> bool:
|
|
91
|
+
return self._compare("<", other)
|
|
92
|
+
|
|
93
|
+
def lte_(self, other: RANGE_SUPPORTED_VALUES | datetime.datetime) -> bool:
|
|
94
|
+
return self._compare("<=", other)
|
|
95
|
+
|
|
96
|
+
def gt_(self, other: RANGE_SUPPORTED_VALUES | datetime.datetime) -> bool:
|
|
97
|
+
return self._compare(">", other)
|
|
98
|
+
|
|
99
|
+
def gte_(self, other: RANGE_SUPPORTED_VALUES | datetime.datetime) -> bool:
|
|
100
|
+
return self._compare(">=", other)
|
|
101
|
+
|
|
102
|
+
def in_(self, other: LIST_SUPPORTED_VALUES) -> bool:
|
|
103
|
+
return self._compare("in", other)
|
|
104
|
+
|
|
105
|
+
def contains_all_(self, other: LIST_SUPPORTED_VALUES) -> bool:
|
|
106
|
+
return self._compare("containsAll", other)
|
|
107
|
+
|
|
108
|
+
def contains_any_(self, other: LIST_SUPPORTED_VALUES) -> bool:
|
|
109
|
+
return self._compare("containsAny", other)
|
|
110
|
+
|
|
111
|
+
def exists_(self) -> bool:
|
|
112
|
+
return self._compare("exists", None)
|
|
113
|
+
|
|
114
|
+
def not_exists_(self) -> bool:
|
|
115
|
+
return self.not_("exists", None)
|
|
116
|
+
|
|
117
|
+
def not_(self, operator: LEAF_EXPRESSION_OPERATORS, other: Any) -> bool:
|
|
118
|
+
return BoolExpression(
|
|
119
|
+
operator="not",
|
|
120
|
+
filters=[self._compare(operator, other)], # type: ignore
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
def nested_(
|
|
124
|
+
self, expression: bool | LeafExpression | BoolExpression
|
|
125
|
+
) -> bool:
|
|
126
|
+
if not isinstance(expression, Expression):
|
|
127
|
+
raise ValueError("Invalid expression")
|
|
128
|
+
|
|
129
|
+
return self._compare("nested", expression)
|
|
130
|
+
|
|
131
|
+
def _compare(
|
|
132
|
+
self, operator: LEAF_EXPRESSION_OPERATORS, value: Any
|
|
133
|
+
) -> bool:
|
|
134
|
+
if isinstance(value, Column):
|
|
135
|
+
raise ValueError("can not compare two columns in a graphdb")
|
|
136
|
+
|
|
137
|
+
return LeafExpression(
|
|
138
|
+
property=self.property, operator=operator, value=value
|
|
139
|
+
) # type: ignore
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _unwrap_expressions(
|
|
143
|
+
*expressions: bool | LeafExpression | BoolExpression,
|
|
144
|
+
) -> list[Expression]:
|
|
145
|
+
filters: list[Expression] = []
|
|
146
|
+
for expression in expressions:
|
|
147
|
+
assert isinstance(expression, Expression)
|
|
148
|
+
filters.append(expression)
|
|
149
|
+
return filters
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def and_(*expressions: bool | LeafExpression | BoolExpression) -> bool:
|
|
153
|
+
return BoolExpression(
|
|
154
|
+
operator="and", filters=_unwrap_expressions(*expressions)
|
|
155
|
+
) # type: ignore
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def or_(*expressions: bool | LeafExpression | BoolExpression) -> bool:
|
|
159
|
+
return BoolExpression(
|
|
160
|
+
operator="or", filters=_unwrap_expressions(*expressions)
|
|
161
|
+
) # type: ignore
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def col(property: Any) -> Column:
|
|
165
|
+
return Column(property)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from collections.abc import Callable, Generator
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from typing import (
|
|
4
|
+
Any,
|
|
5
|
+
ParamSpec,
|
|
6
|
+
TypeVar,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from anyio import to_thread
|
|
10
|
+
|
|
11
|
+
TAny = TypeVar("TAny")
|
|
12
|
+
T_Retval = TypeVar("T_Retval")
|
|
13
|
+
P = ParamSpec("P")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def datetime_to_ms_iso_timestamp(dt: datetime) -> str:
|
|
17
|
+
if not isinstance(dt, datetime):
|
|
18
|
+
raise ValueError(f"Expected datetime object, got {type(dt)}")
|
|
19
|
+
if dt.tzinfo is None:
|
|
20
|
+
dt = dt.astimezone()
|
|
21
|
+
return dt.isoformat(timespec="milliseconds")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def chunk_list(
|
|
25
|
+
entries: list[TAny], chunk_size: int
|
|
26
|
+
) -> Generator[list[TAny], Any, None]:
|
|
27
|
+
for i in range(0, len(entries), chunk_size):
|
|
28
|
+
start = i
|
|
29
|
+
end = i + chunk_size
|
|
30
|
+
yield entries[start:end]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async def run_async(
|
|
34
|
+
func: Callable[..., T_Retval],
|
|
35
|
+
*args: object,
|
|
36
|
+
cancellable: bool = False,
|
|
37
|
+
) -> T_Retval:
|
|
38
|
+
return await to_thread.run_sync(func, *args, cancellable=cancellable)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: industrial-model
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Industrial Model ORM
|
|
5
|
+
Author-email: Lucas Alves <lucasrosaalves@gmail.com>
|
|
6
|
+
Classifier: Programming Language :: Python
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Topic :: Database
|
|
13
|
+
Classifier: Topic :: Database :: Database Engines/Servers
|
|
14
|
+
Classifier: Typing :: Typed
|
|
15
|
+
Requires-Python: >=3.11
|
|
16
|
+
Requires-Dist: anyio>=4.9.0
|
|
17
|
+
Requires-Dist: cognite-sdk>=7.75.0
|
|
18
|
+
Requires-Dist: pydantic>=2.11.4
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# capybara
|
|
22
|
+
|
|
23
|
+

|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
industrial_model/__init__.py,sha256=EDOULHjsfkh_XJVHVajSpQycMWLsQ3STmVj_WoKfiWc,507
|
|
2
|
+
industrial_model/config.py,sha256=wzSKVKHIdGlxCRtu0PIeL3SLYvnQBR4Py46CcETxa8U,238
|
|
3
|
+
industrial_model/constants.py,sha256=wtFdxkR9gojqekwXeyVCof6VUkJYuqjjgAgVVKrcxaw,450
|
|
4
|
+
industrial_model/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
industrial_model/utils.py,sha256=OuuAkIqu-551axsZJPuqHu5d9iReGcfY9ROBFtHIwkY,933
|
|
6
|
+
industrial_model/cognite_adapters/__init__.py,sha256=9N4oT7tWZx5wjVr7q64Ef5FLT75Omep48xGYv1PhxV8,1917
|
|
7
|
+
industrial_model/cognite_adapters/filter_mapper.py,sha256=NqH-OW7_iKFY9POCG8W3KjkwXUgrZP1d_yxDx1J0fXM,3859
|
|
8
|
+
industrial_model/cognite_adapters/optimizer.py,sha256=msOXAU2nY2-7U0-AlST3_SWuLHnyQ9wNa5_BzMRQfdw,2166
|
|
9
|
+
industrial_model/cognite_adapters/query_mapper.py,sha256=lYKRiIEmFiX7CQUnrOh5_-t1UkAMcT3dr9ORgErDXOY,6233
|
|
10
|
+
industrial_model/cognite_adapters/query_result_mapper.py,sha256=jUreXqsaLnq7hp6T_JZQNRtL8TL8hoLSFvD4SkJ4TEE,7002
|
|
11
|
+
industrial_model/cognite_adapters/schemas.py,sha256=5sR0HPBWx9o11p_EN2sZR58XHovsfeoMsKwFHJAHrFI,3352
|
|
12
|
+
industrial_model/cognite_adapters/sort_mapper.py,sha256=RJUAYlZGXoYzK0PwX63cibRF_L-MUq9g2ZsC2EeNIF4,696
|
|
13
|
+
industrial_model/cognite_adapters/utils.py,sha256=nBYHK8697L2yGEAcyKjQV9NEZQmWy_aSGq_iMl7gofM,907
|
|
14
|
+
industrial_model/cognite_adapters/view_mapper.py,sha256=lnv64KezSQTAr6XdcExa8d92GU5Ll9K9HfMcQGzhX6k,488
|
|
15
|
+
industrial_model/engines/__init__.py,sha256=7aGHrUm2MxIq39vR8h0xu3i1zNOuT9H9U-q4lV3nErQ,102
|
|
16
|
+
industrial_model/engines/async_engine.py,sha256=3Y4Ao14CDJJAZFbgTX9I6LOJUxfe8nwOOukGVeiw914,1070
|
|
17
|
+
industrial_model/engines/engine.py,sha256=8-wfktRLZpad_V7_F1Vz7vtjE_bQhga_jXXjuwSgfrE,1897
|
|
18
|
+
industrial_model/models/__init__.py,sha256=j8e54oDCY_rh6GOyacK9UtjjI4nwKLpsy3r5GSJTXpY,334
|
|
19
|
+
industrial_model/models/base.py,sha256=jbiaICJ0R1mmxXtDqxxlVdq-tTX4RLdqnLTgs9HLm_4,1279
|
|
20
|
+
industrial_model/models/entities.py,sha256=NrFV_a3ZP6Y4b1M2PFl_746qcCsexsyO2cuB0snZhkw,1319
|
|
21
|
+
industrial_model/queries/__init__.py,sha256=7aheTE5qs03rxWm9fmGWptbz_p9OIXXYD8if56cqs18,227
|
|
22
|
+
industrial_model/queries/models.py,sha256=iiHQ7-cfg0nukEv5PoCx9QPF-w1gVSnoNbXBOK9Mzeo,1185
|
|
23
|
+
industrial_model/queries/params.py,sha256=ehgCoR5n6E-tkEuoymZ2lkLcSzMaBAx_HnyJ7sWpqz0,964
|
|
24
|
+
industrial_model/statements/__init__.py,sha256=mqPIvfQ-XZ_IILwha7RbkdIKH_MRAdAvfrw80pCKU1c,1753
|
|
25
|
+
industrial_model/statements/expressions.py,sha256=bsUnkFDGVHpOQ1RUtEbSPE1nfVkF0zC3m5-9JFkSqu8,4751
|
|
26
|
+
industrial_model-0.1.0.dist-info/METADATA,sha256=jZmhsTJkulF0xz4IMktuaiizIgVOTriD2G7zimsmozw,763
|
|
27
|
+
industrial_model-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
28
|
+
industrial_model-0.1.0.dist-info/RECORD,,
|