industrial-model 0.1.22__tar.gz → 0.1.24__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.
- {industrial_model-0.1.22 → industrial_model-0.1.24}/PKG-INFO +1 -1
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/aggregation_mapper.py +7 -1
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/filter_mapper.py +14 -4
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/queries/__init__.py +3 -1
- industrial_model-0.1.24/industrial_model/queries/models.py +98 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/statements/__init__.py +8 -3
- {industrial_model-0.1.22 → industrial_model-0.1.24}/pyproject.toml +1 -1
- {industrial_model-0.1.22 → industrial_model-0.1.24}/uv.lock +1 -1
- industrial_model-0.1.22/industrial_model/queries/models.py +0 -33
- {industrial_model-0.1.22 → industrial_model-0.1.24}/.gitignore +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/.python-version +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/README.md +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/__init__.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/__init__.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/models.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/optimizer.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/query_mapper.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/query_result_mapper.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/search_mapper.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/sort_mapper.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/upsert_mapper.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/utils.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/view_mapper.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/config.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/constants.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/engines/__init__.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/engines/async_engine.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/engines/engine.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/models/__init__.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/models/base.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/models/entities.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/models/schemas.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/py.typed +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/queries/params.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/statements/expressions.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/utils.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/scripts/build.sh +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/scripts/format.sh +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/scripts/lint.sh +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/scripts/publish.sh +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/tests/__init__.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/tests/cognite-sdk-config.yaml +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/tests/hubs.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/tests/models.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/tests/test_schema.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/tests/tests_adapter.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/tests/tests_aggregate.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/tests/tests_search.py +0 -0
- {industrial_model-0.1.22 → industrial_model-0.1.24}/tests/tests_upsert_mapper.py +0 -0
|
@@ -62,10 +62,16 @@ class AggregationMapper:
|
|
|
62
62
|
|
|
63
63
|
if metric_aggregation is None:
|
|
64
64
|
raise ValueError(f"Unsupported aggregate function: {statement.aggregate_}")
|
|
65
|
+
|
|
66
|
+
group_by_columns = (
|
|
67
|
+
[prop.property for prop in statement.group_by_properties]
|
|
68
|
+
if statement.group_by_properties is not None
|
|
69
|
+
else statement.entity.get_group_by_fields()
|
|
70
|
+
)
|
|
65
71
|
return AggregationQuery(
|
|
66
72
|
view=root_view,
|
|
67
73
|
metric_aggregation=metric_aggregation,
|
|
68
74
|
filters=filters_,
|
|
69
|
-
group_by_columns=
|
|
75
|
+
group_by_columns=group_by_columns,
|
|
70
76
|
limit=statement.limit_,
|
|
71
77
|
)
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
from datetime import date, datetime
|
|
2
|
+
from typing import Any
|
|
2
3
|
|
|
3
4
|
import cognite.client.data_classes.filters as cdf_filters
|
|
4
5
|
from cognite.client.data_classes.data_modeling import MappedProperty, View
|
|
5
6
|
|
|
6
7
|
from industrial_model.cognite_adapters.utils import get_property_ref
|
|
8
|
+
from industrial_model.models.entities import InstanceId
|
|
7
9
|
from industrial_model.statements import (
|
|
8
10
|
BoolExpression,
|
|
9
11
|
Expression,
|
|
@@ -54,11 +56,8 @@ class FilterMapper:
|
|
|
54
56
|
property_ref = get_property_ref(expression.property, root_view)
|
|
55
57
|
|
|
56
58
|
value_ = expression.value
|
|
57
|
-
if isinstance(value_, datetime):
|
|
58
|
-
value_ = datetime_to_ms_iso_timestamp(value_)
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
value_ = value_.strftime("%Y-%m-%d")
|
|
60
|
+
value_ = self._handle_type_value_convertion(value_)
|
|
62
61
|
|
|
63
62
|
if expression.operator == "==":
|
|
64
63
|
return cdf_filters.Equals(property_ref, value_)
|
|
@@ -96,3 +95,14 @@ class FilterMapper:
|
|
|
96
95
|
assert isinstance(view_definiton, MappedProperty)
|
|
97
96
|
assert view_definiton.source
|
|
98
97
|
return self._view_mapper.get_view(view_definiton.source.external_id)
|
|
98
|
+
|
|
99
|
+
def _handle_type_value_convertion(self, value_: Any) -> Any:
|
|
100
|
+
if isinstance(value_, datetime):
|
|
101
|
+
return datetime_to_ms_iso_timestamp(value_)
|
|
102
|
+
elif isinstance(value_, date):
|
|
103
|
+
return value_.strftime("%Y-%m-%d")
|
|
104
|
+
elif isinstance(value_, InstanceId):
|
|
105
|
+
return value_.model_dump(mode="json", by_alias=True)
|
|
106
|
+
elif isinstance(value_, list):
|
|
107
|
+
return [self._handle_type_value_convertion(v) for v in value_]
|
|
108
|
+
return value_
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
from .models import BasePaginatedQuery, BaseQuery
|
|
1
|
+
from .models import BaseAggregationQuery, BasePaginatedQuery, BaseQuery, BaseSearchQuery
|
|
2
2
|
from .params import NestedQueryParam, QueryParam, SortParam
|
|
3
3
|
|
|
4
4
|
__all__ = [
|
|
5
5
|
"BaseQuery",
|
|
6
6
|
"BasePaginatedQuery",
|
|
7
|
+
"BaseSearchQuery",
|
|
8
|
+
"BaseAggregationQuery",
|
|
7
9
|
"SortParam",
|
|
8
10
|
"QueryParam",
|
|
9
11
|
"NestedQueryParam",
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from industrial_model.models import RootModel, TAggregatedViewInstance, TViewInstance
|
|
4
|
+
from industrial_model.statements import (
|
|
5
|
+
AggregateTypes,
|
|
6
|
+
AggregationStatement,
|
|
7
|
+
SearchStatement,
|
|
8
|
+
Statement,
|
|
9
|
+
aggregate,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from .params import NestedQueryParam, QueryParam, SortParam
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BaseQuery(RootModel):
|
|
16
|
+
def to_statement(self, entity: type[TViewInstance]) -> Statement[TViewInstance]:
|
|
17
|
+
statement = Statement(entity)
|
|
18
|
+
|
|
19
|
+
for key, item in self.__class__.model_fields.items():
|
|
20
|
+
values = getattr(self, key)
|
|
21
|
+
if not values:
|
|
22
|
+
continue
|
|
23
|
+
for metadata_item in item.metadata:
|
|
24
|
+
if isinstance(metadata_item, SortParam):
|
|
25
|
+
statement.sort(values, metadata_item.direction)
|
|
26
|
+
elif isinstance(metadata_item, QueryParam | NestedQueryParam):
|
|
27
|
+
statement.where(metadata_item.to_expression(values))
|
|
28
|
+
|
|
29
|
+
return statement
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class BasePaginatedQuery(BaseQuery):
|
|
33
|
+
limit: int = 1000
|
|
34
|
+
cursor: str | None = None
|
|
35
|
+
|
|
36
|
+
def to_statement(self, entity: type[TViewInstance]) -> Statement[TViewInstance]:
|
|
37
|
+
statement = super().to_statement(entity)
|
|
38
|
+
statement.limit(self.limit)
|
|
39
|
+
statement.cursor(self.cursor)
|
|
40
|
+
|
|
41
|
+
return statement
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class BaseSearchQuery(RootModel):
|
|
45
|
+
query: str | None = None
|
|
46
|
+
query_properties: list[str] | list[Any] | None = None
|
|
47
|
+
limit: int = 1000
|
|
48
|
+
|
|
49
|
+
def to_statement(
|
|
50
|
+
self, entity: type[TViewInstance]
|
|
51
|
+
) -> SearchStatement[TViewInstance]:
|
|
52
|
+
statement = SearchStatement(entity)
|
|
53
|
+
|
|
54
|
+
for key, item in self.__class__.model_fields.items():
|
|
55
|
+
values = getattr(self, key)
|
|
56
|
+
if not values:
|
|
57
|
+
continue
|
|
58
|
+
for metadata_item in item.metadata:
|
|
59
|
+
if isinstance(metadata_item, SortParam):
|
|
60
|
+
statement.sort(values, metadata_item.direction)
|
|
61
|
+
elif isinstance(metadata_item, QueryParam | NestedQueryParam):
|
|
62
|
+
statement.where(metadata_item.to_expression(values))
|
|
63
|
+
if self.query:
|
|
64
|
+
statement.query_by(self.query, self.query_properties)
|
|
65
|
+
statement.limit(self.limit)
|
|
66
|
+
|
|
67
|
+
return statement
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class BaseAggregationQuery(RootModel):
|
|
71
|
+
aggregate: AggregateTypes | None = None
|
|
72
|
+
group_by_properties: list[str] | list[Any] | None = None
|
|
73
|
+
aggregation_property: str | None = None
|
|
74
|
+
limit: int | None = None
|
|
75
|
+
|
|
76
|
+
def to_statement(
|
|
77
|
+
self, entity: type[TAggregatedViewInstance]
|
|
78
|
+
) -> AggregationStatement[TAggregatedViewInstance]:
|
|
79
|
+
statement = aggregate(entity, self.aggregate)
|
|
80
|
+
|
|
81
|
+
for key, item in self.__class__.model_fields.items():
|
|
82
|
+
values = getattr(self, key)
|
|
83
|
+
if not values:
|
|
84
|
+
continue
|
|
85
|
+
for metadata_item in item.metadata:
|
|
86
|
+
if isinstance(metadata_item, QueryParam | NestedQueryParam):
|
|
87
|
+
statement.where(metadata_item.to_expression(values))
|
|
88
|
+
|
|
89
|
+
if self.group_by_properties:
|
|
90
|
+
statement.group_by(*self.group_by_properties)
|
|
91
|
+
|
|
92
|
+
if self.aggregation_property:
|
|
93
|
+
statement.aggregate_by(self.aggregation_property)
|
|
94
|
+
|
|
95
|
+
if self.limit:
|
|
96
|
+
statement.limit(self.limit)
|
|
97
|
+
|
|
98
|
+
return statement
|
|
@@ -74,7 +74,7 @@ class SearchStatement(BaseStatement[T]):
|
|
|
74
74
|
def query_by(
|
|
75
75
|
self,
|
|
76
76
|
query: str,
|
|
77
|
-
query_properties: list[Column | str | Any] | None = None,
|
|
77
|
+
query_properties: list[Column] | list[str] | list[Any] | None = None,
|
|
78
78
|
) -> Self:
|
|
79
79
|
self.query = query
|
|
80
80
|
self.query_properties = (
|
|
@@ -97,10 +97,15 @@ class AggregationStatement(Generic[T]):
|
|
|
97
97
|
entity: type[T] = field(init=True)
|
|
98
98
|
aggregate: AggregateTypes = field(init=True)
|
|
99
99
|
|
|
100
|
+
group_by_properties: list[Column] | None = field(init=False, default=None)
|
|
100
101
|
aggregation_property: Column = field(init=False, default=Column("externalId"))
|
|
101
102
|
where_clauses: list[Expression] = field(init=False, default_factory=list)
|
|
102
103
|
limit_: int = field(init=False, default=-1)
|
|
103
104
|
|
|
105
|
+
def group_by(self, *property: str | Column | Any) -> Self:
|
|
106
|
+
self.group_by_properties = [_create_column(prop) for prop in property]
|
|
107
|
+
return self
|
|
108
|
+
|
|
104
109
|
def aggregate_by(self, property: str | Column | Any) -> Self:
|
|
105
110
|
self.aggregation_property = _create_column(property)
|
|
106
111
|
return self
|
|
@@ -122,9 +127,9 @@ def select(entity: type[T]) -> Statement[T]:
|
|
|
122
127
|
|
|
123
128
|
def aggregate(
|
|
124
129
|
entity: type[T],
|
|
125
|
-
aggregate: AggregateTypes = "count",
|
|
130
|
+
aggregate: AggregateTypes | None = "count",
|
|
126
131
|
) -> AggregationStatement[T]:
|
|
127
|
-
return AggregationStatement(entity=entity, aggregate=aggregate)
|
|
132
|
+
return AggregationStatement(entity=entity, aggregate=aggregate or "count")
|
|
128
133
|
|
|
129
134
|
|
|
130
135
|
def search(entity: type[T]) -> SearchStatement[T]:
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
from industrial_model.models import RootModel, TViewInstance
|
|
2
|
-
from industrial_model.statements import Statement
|
|
3
|
-
|
|
4
|
-
from .params import NestedQueryParam, QueryParam, SortParam
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class BaseQuery(RootModel):
|
|
8
|
-
def to_statement(self, entity: type[TViewInstance]) -> Statement[TViewInstance]:
|
|
9
|
-
statement = Statement(entity)
|
|
10
|
-
|
|
11
|
-
for key, item in self.__class__.model_fields.items():
|
|
12
|
-
values = getattr(self, key)
|
|
13
|
-
if not values:
|
|
14
|
-
continue
|
|
15
|
-
for metadata_item in item.metadata:
|
|
16
|
-
if isinstance(metadata_item, SortParam):
|
|
17
|
-
statement.sort(values, metadata_item.direction)
|
|
18
|
-
elif isinstance(metadata_item, QueryParam | NestedQueryParam):
|
|
19
|
-
statement.where(metadata_item.to_expression(values))
|
|
20
|
-
|
|
21
|
-
return statement
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class BasePaginatedQuery(BaseQuery):
|
|
25
|
-
limit: int = 1000
|
|
26
|
-
cursor: str | None = None
|
|
27
|
-
|
|
28
|
-
def to_statement(self, entity: type[TViewInstance]) -> Statement[TViewInstance]:
|
|
29
|
-
statement = super().to_statement(entity)
|
|
30
|
-
statement.limit(self.limit)
|
|
31
|
-
statement.cursor(self.cursor)
|
|
32
|
-
|
|
33
|
-
return statement
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/__init__.py
RENAMED
|
File without changes
|
{industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/models.py
RENAMED
|
File without changes
|
{industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/optimizer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/sort_mapper.py
RENAMED
|
File without changes
|
|
File without changes
|
{industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/utils.py
RENAMED
|
File without changes
|
{industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/cognite_adapters/view_mapper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/engines/async_engine.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{industrial_model-0.1.22 → industrial_model-0.1.24}/industrial_model/statements/expressions.py
RENAMED
|
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
|