industrial-model 0.1.16__tar.gz → 0.1.18__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 (44) hide show
  1. {industrial_model-0.1.16 → industrial_model-0.1.18}/PKG-INFO +1 -1
  2. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/cognite_adapters/query_result_mapper.py +35 -6
  3. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/models/entities.py +3 -0
  4. {industrial_model-0.1.16 → industrial_model-0.1.18}/pyproject.toml +1 -1
  5. {industrial_model-0.1.16 → industrial_model-0.1.18}/uv.lock +1 -1
  6. {industrial_model-0.1.16 → industrial_model-0.1.18}/.gitignore +0 -0
  7. {industrial_model-0.1.16 → industrial_model-0.1.18}/.python-version +0 -0
  8. {industrial_model-0.1.16 → industrial_model-0.1.18}/README.md +0 -0
  9. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/__init__.py +0 -0
  10. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/cognite_adapters/__init__.py +0 -0
  11. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/cognite_adapters/aggregation_mapper.py +0 -0
  12. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/cognite_adapters/filter_mapper.py +0 -0
  13. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/cognite_adapters/models.py +0 -0
  14. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/cognite_adapters/optimizer.py +0 -0
  15. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/cognite_adapters/query_mapper.py +0 -0
  16. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/cognite_adapters/sort_mapper.py +0 -0
  17. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/cognite_adapters/upsert_mapper.py +0 -0
  18. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/cognite_adapters/utils.py +0 -0
  19. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/cognite_adapters/view_mapper.py +0 -0
  20. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/config.py +0 -0
  21. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/constants.py +0 -0
  22. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/engines/__init__.py +0 -0
  23. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/engines/async_engine.py +0 -0
  24. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/engines/engine.py +0 -0
  25. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/models/__init__.py +0 -0
  26. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/models/base.py +0 -0
  27. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/models/schemas.py +0 -0
  28. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/py.typed +0 -0
  29. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/queries/__init__.py +0 -0
  30. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/queries/models.py +0 -0
  31. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/queries/params.py +0 -0
  32. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/statements/__init__.py +0 -0
  33. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/statements/expressions.py +0 -0
  34. {industrial_model-0.1.16 → industrial_model-0.1.18}/industrial_model/utils.py +0 -0
  35. {industrial_model-0.1.16 → industrial_model-0.1.18}/scripts/build.sh +0 -0
  36. {industrial_model-0.1.16 → industrial_model-0.1.18}/scripts/format.sh +0 -0
  37. {industrial_model-0.1.16 → industrial_model-0.1.18}/scripts/lint.sh +0 -0
  38. {industrial_model-0.1.16 → industrial_model-0.1.18}/tests/__init__.py +0 -0
  39. {industrial_model-0.1.16 → industrial_model-0.1.18}/tests/cognite-sdk-config.yaml +0 -0
  40. {industrial_model-0.1.16 → industrial_model-0.1.18}/tests/hubs.py +0 -0
  41. {industrial_model-0.1.16 → industrial_model-0.1.18}/tests/models.py +0 -0
  42. {industrial_model-0.1.16 → industrial_model-0.1.18}/tests/test_upsert_mapper.py +0 -0
  43. {industrial_model-0.1.16 → industrial_model-0.1.18}/tests/tests_adapter.py +0 -0
  44. {industrial_model-0.1.16 → industrial_model-0.1.18}/tests/tests_aggregate.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: industrial-model
3
- Version: 0.1.16
3
+ Version: 0.1.18
4
4
  Summary: Industrial Model ORM
5
5
  Author-email: Lucas Alves <lucasrosaalves@gmail.com>
6
6
  Classifier: Programming Language :: Python
@@ -1,5 +1,6 @@
1
1
  from collections import defaultdict
2
- from typing import Any, TypedDict
2
+ from enum import StrEnum
3
+ from typing import Any, Literal, TypedDict
3
4
 
4
5
  from cognite.client.data_classes.data_modeling import (
5
6
  Edge,
@@ -19,8 +20,15 @@ from industrial_model.models import EdgeContainer
19
20
  from .view_mapper import ViewMapper
20
21
 
21
22
 
23
+ class ConnectionTypeEnum(StrEnum):
24
+ DIRECT_RELATION = "DirectRelation"
25
+ REVERSE_DIRECT_RELATION = "ReverseDirectRelation"
26
+ EDGE = "Edge"
27
+
28
+
22
29
  class _PropertyMapping(TypedDict):
23
30
  is_list: bool
31
+ connection_type: ConnectionTypeEnum
24
32
  nodes: dict[tuple[str, str], list[Node]]
25
33
  edges: dict[tuple[str, str], list[Edge]]
26
34
 
@@ -92,16 +100,26 @@ class QueryResultMapper:
92
100
  for mapping_key, mapping_value in mappings.items():
93
101
  element = properties.get(mapping_key)
94
102
 
103
+ mapping_nodes = mapping_value.get("nodes", {})
104
+ mapping_edges = mapping_value.get("edges", {})
105
+ is_list = mapping_value.get("is_list", False)
106
+ connection_type = mapping_value.get(
107
+ "connection_type",
108
+ ConnectionTypeEnum.DIRECT_RELATION,
109
+ )
110
+
111
+ if (
112
+ element is None
113
+ and connection_type == ConnectionTypeEnum.DIRECT_RELATION
114
+ ):
115
+ continue
116
+
95
117
  element_key: tuple[str, str] = (
96
118
  (element.get("space", ""), element.get("externalId", ""))
97
119
  if isinstance(element, dict)
98
120
  else (node.space, node.external_id)
99
121
  )
100
122
 
101
- mapping_nodes = mapping_value.get("nodes", {})
102
- mapping_edges = mapping_value.get("edges", {})
103
- is_list = mapping_value.get("is_list", False)
104
-
105
123
  node_entries = mapping_nodes.get(element_key)
106
124
  if not node_entries:
107
125
  continue
@@ -116,6 +134,7 @@ class QueryResultMapper:
116
134
  edge_entries
117
135
  )
118
136
  properties["_edges"] = edges_mapping
137
+
119
138
  node.properties[view_id] = properties
120
139
 
121
140
  result[node_id].append(node)
@@ -136,6 +155,9 @@ class QueryResultMapper:
136
155
  nodes: dict[tuple[str, str], list[Node]] | None = None
137
156
  edges: dict[tuple[str, str], list[Edge]] | None = None
138
157
  is_list = False
158
+ connection_type: ConnectionTypeEnum = (
159
+ ConnectionTypeEnum.DIRECT_RELATION
160
+ )
139
161
 
140
162
  if isinstance(property, MappedProperty) and property.source:
141
163
  nodes = self._map_node_property(
@@ -144,6 +166,7 @@ class QueryResultMapper:
144
166
  query_result,
145
167
  )
146
168
  is_list = False
169
+ connection_type = ConnectionTypeEnum.DIRECT_RELATION
147
170
  elif (
148
171
  isinstance(property, SingleReverseDirectRelation)
149
172
  and property.source
@@ -155,6 +178,7 @@ class QueryResultMapper:
155
178
  property.through.property,
156
179
  )
157
180
  is_list = False
181
+ connection_type = ConnectionTypeEnum.REVERSE_DIRECT_RELATION
158
182
  elif (
159
183
  isinstance(property, MultiReverseDirectRelation)
160
184
  and property.source
@@ -166,6 +190,7 @@ class QueryResultMapper:
166
190
  property.through.property,
167
191
  )
168
192
  is_list = True
193
+ connection_type = ConnectionTypeEnum.REVERSE_DIRECT_RELATION
169
194
 
170
195
  elif isinstance(property, EdgeConnection) and property.source:
171
196
  nodes, edges = self._map_edge_property(
@@ -175,10 +200,14 @@ class QueryResultMapper:
175
200
  property.direction,
176
201
  )
177
202
  is_list = True
203
+ connection_type = ConnectionTypeEnum.EDGE
178
204
 
179
205
  if nodes:
180
206
  mappings[property_name] = _PropertyMapping(
181
- is_list=is_list, nodes=nodes, edges=edges or {}
207
+ is_list=is_list,
208
+ connection_type=connection_type,
209
+ nodes=nodes,
210
+ edges=edges or {},
182
211
  )
183
212
 
184
213
  return mappings
@@ -101,5 +101,8 @@ class PaginatedResult(RootModel, Generic[TViewInstance]):
101
101
  has_next_page: bool
102
102
  next_cursor: str | None
103
103
 
104
+ def first_or_default(self) -> TViewInstance | None:
105
+ return self.data[0] if self.data else None
106
+
104
107
 
105
108
  ValidationMode = Literal["raiseOnError", "ignoreOnError"]
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "industrial-model"
3
- version = "0.1.16"
3
+ version = "0.1.18"
4
4
  description = "Industrial Model ORM"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -215,7 +215,7 @@ wheels = [
215
215
 
216
216
  [[package]]
217
217
  name = "industrial-model"
218
- version = "0.1.16"
218
+ version = "0.1.18"
219
219
  source = { editable = "." }
220
220
  dependencies = [
221
221
  { name = "anyio" },