cognite-toolkit 0.6.97__py3-none-any.whl → 0.7.39__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.
Files changed (198) hide show
  1. cognite_toolkit/_cdf.py +21 -23
  2. cognite_toolkit/_cdf_tk/apps/__init__.py +4 -0
  3. cognite_toolkit/_cdf_tk/apps/_core_app.py +19 -5
  4. cognite_toolkit/_cdf_tk/apps/_data_app.py +1 -1
  5. cognite_toolkit/_cdf_tk/apps/_dev_app.py +86 -0
  6. cognite_toolkit/_cdf_tk/apps/_download_app.py +693 -25
  7. cognite_toolkit/_cdf_tk/apps/_dump_app.py +44 -102
  8. cognite_toolkit/_cdf_tk/apps/_import_app.py +41 -0
  9. cognite_toolkit/_cdf_tk/apps/_landing_app.py +18 -4
  10. cognite_toolkit/_cdf_tk/apps/_migrate_app.py +424 -9
  11. cognite_toolkit/_cdf_tk/apps/_modules_app.py +0 -3
  12. cognite_toolkit/_cdf_tk/apps/_purge.py +15 -43
  13. cognite_toolkit/_cdf_tk/apps/_run.py +11 -0
  14. cognite_toolkit/_cdf_tk/apps/_upload_app.py +45 -6
  15. cognite_toolkit/_cdf_tk/builders/__init__.py +2 -2
  16. cognite_toolkit/_cdf_tk/builders/_base.py +28 -42
  17. cognite_toolkit/_cdf_tk/builders/_raw.py +1 -1
  18. cognite_toolkit/_cdf_tk/cdf_toml.py +20 -1
  19. cognite_toolkit/_cdf_tk/client/_toolkit_client.py +32 -12
  20. cognite_toolkit/_cdf_tk/client/api/infield.py +114 -17
  21. cognite_toolkit/_cdf_tk/client/api/{canvas.py → legacy/canvas.py} +15 -7
  22. cognite_toolkit/_cdf_tk/client/api/{charts.py → legacy/charts.py} +1 -1
  23. cognite_toolkit/_cdf_tk/client/api/{extended_data_modeling.py → legacy/extended_data_modeling.py} +1 -1
  24. cognite_toolkit/_cdf_tk/client/api/{extended_files.py → legacy/extended_files.py} +2 -2
  25. cognite_toolkit/_cdf_tk/client/api/{extended_functions.py → legacy/extended_functions.py} +15 -18
  26. cognite_toolkit/_cdf_tk/client/api/{extended_raw.py → legacy/extended_raw.py} +1 -1
  27. cognite_toolkit/_cdf_tk/client/api/{extended_timeseries.py → legacy/extended_timeseries.py} +5 -2
  28. cognite_toolkit/_cdf_tk/client/api/{location_filters.py → legacy/location_filters.py} +1 -1
  29. cognite_toolkit/_cdf_tk/client/api/legacy/robotics/__init__.py +8 -0
  30. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/capabilities.py +1 -1
  31. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/data_postprocessing.py +1 -1
  32. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/frames.py +1 -1
  33. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/locations.py +1 -1
  34. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/maps.py +1 -1
  35. cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/robots.py +2 -2
  36. cognite_toolkit/_cdf_tk/client/api/{search_config.py → legacy/search_config.py} +5 -1
  37. cognite_toolkit/_cdf_tk/client/api/migration.py +177 -4
  38. cognite_toolkit/_cdf_tk/client/api/project.py +9 -8
  39. cognite_toolkit/_cdf_tk/client/api/search.py +2 -2
  40. cognite_toolkit/_cdf_tk/client/api/streams.py +88 -0
  41. cognite_toolkit/_cdf_tk/client/api/three_d.py +384 -0
  42. cognite_toolkit/_cdf_tk/client/data_classes/api_classes.py +13 -0
  43. cognite_toolkit/_cdf_tk/client/data_classes/base.py +37 -33
  44. cognite_toolkit/_cdf_tk/client/data_classes/charts_data.py +95 -213
  45. cognite_toolkit/_cdf_tk/client/data_classes/infield.py +32 -18
  46. cognite_toolkit/_cdf_tk/client/data_classes/instance_api.py +18 -13
  47. cognite_toolkit/_cdf_tk/client/data_classes/legacy/__init__.py +0 -0
  48. cognite_toolkit/_cdf_tk/client/data_classes/{canvas.py → legacy/canvas.py} +47 -4
  49. cognite_toolkit/_cdf_tk/client/data_classes/{charts.py → legacy/charts.py} +3 -3
  50. cognite_toolkit/_cdf_tk/client/data_classes/{migration.py → legacy/migration.py} +10 -2
  51. cognite_toolkit/_cdf_tk/client/data_classes/streams.py +90 -0
  52. cognite_toolkit/_cdf_tk/client/data_classes/three_d.py +112 -0
  53. cognite_toolkit/_cdf_tk/client/testing.py +42 -18
  54. cognite_toolkit/_cdf_tk/commands/__init__.py +7 -6
  55. cognite_toolkit/_cdf_tk/commands/_changes.py +3 -42
  56. cognite_toolkit/_cdf_tk/commands/_download.py +21 -11
  57. cognite_toolkit/_cdf_tk/commands/_migrate/__init__.py +0 -2
  58. cognite_toolkit/_cdf_tk/commands/_migrate/command.py +22 -20
  59. cognite_toolkit/_cdf_tk/commands/_migrate/conversion.py +140 -92
  60. cognite_toolkit/_cdf_tk/commands/_migrate/creators.py +1 -1
  61. cognite_toolkit/_cdf_tk/commands/_migrate/data_classes.py +108 -26
  62. cognite_toolkit/_cdf_tk/commands/_migrate/data_mapper.py +448 -45
  63. cognite_toolkit/_cdf_tk/commands/_migrate/data_model.py +1 -0
  64. cognite_toolkit/_cdf_tk/commands/_migrate/default_mappings.py +6 -6
  65. cognite_toolkit/_cdf_tk/commands/_migrate/issues.py +52 -1
  66. cognite_toolkit/_cdf_tk/commands/_migrate/migration_io.py +377 -11
  67. cognite_toolkit/_cdf_tk/commands/_migrate/selectors.py +9 -4
  68. cognite_toolkit/_cdf_tk/commands/_profile.py +1 -1
  69. cognite_toolkit/_cdf_tk/commands/_purge.py +36 -39
  70. cognite_toolkit/_cdf_tk/commands/_questionary_style.py +16 -0
  71. cognite_toolkit/_cdf_tk/commands/_upload.py +109 -86
  72. cognite_toolkit/_cdf_tk/commands/about.py +221 -0
  73. cognite_toolkit/_cdf_tk/commands/auth.py +19 -12
  74. cognite_toolkit/_cdf_tk/commands/build_cmd.py +16 -62
  75. cognite_toolkit/_cdf_tk/commands/build_v2/__init__.py +0 -0
  76. cognite_toolkit/_cdf_tk/commands/build_v2/build_cmd.py +241 -0
  77. cognite_toolkit/_cdf_tk/commands/build_v2/build_input.py +85 -0
  78. cognite_toolkit/_cdf_tk/commands/build_v2/build_issues.py +27 -0
  79. cognite_toolkit/_cdf_tk/commands/clean.py +63 -16
  80. cognite_toolkit/_cdf_tk/commands/deploy.py +20 -17
  81. cognite_toolkit/_cdf_tk/commands/dump_resource.py +10 -8
  82. cognite_toolkit/_cdf_tk/commands/init.py +225 -3
  83. cognite_toolkit/_cdf_tk/commands/modules.py +20 -44
  84. cognite_toolkit/_cdf_tk/commands/pull.py +6 -19
  85. cognite_toolkit/_cdf_tk/commands/resources.py +179 -0
  86. cognite_toolkit/_cdf_tk/commands/run.py +1 -1
  87. cognite_toolkit/_cdf_tk/constants.py +20 -1
  88. cognite_toolkit/_cdf_tk/cruds/__init__.py +19 -5
  89. cognite_toolkit/_cdf_tk/cruds/_base_cruds.py +14 -70
  90. cognite_toolkit/_cdf_tk/cruds/_data_cruds.py +10 -19
  91. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/__init__.py +4 -1
  92. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/agent.py +11 -9
  93. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/auth.py +5 -15
  94. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/classic.py +45 -44
  95. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/configuration.py +5 -12
  96. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/data_organization.py +4 -13
  97. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/datamodel.py +206 -67
  98. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/extraction_pipeline.py +6 -18
  99. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py +126 -35
  100. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py +7 -28
  101. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/function.py +23 -30
  102. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/hosted_extractors.py +12 -30
  103. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/industrial_tool.py +4 -8
  104. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/location.py +4 -16
  105. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/migration.py +5 -13
  106. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/raw.py +5 -11
  107. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/relationship.py +3 -8
  108. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/robotics.py +16 -45
  109. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/streams.py +94 -0
  110. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/three_d_model.py +3 -7
  111. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/timeseries.py +5 -15
  112. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/transformation.py +75 -32
  113. cognite_toolkit/_cdf_tk/cruds/_resource_cruds/workflow.py +20 -40
  114. cognite_toolkit/_cdf_tk/cruds/_worker.py +24 -36
  115. cognite_toolkit/_cdf_tk/data_classes/_module_toml.py +1 -0
  116. cognite_toolkit/_cdf_tk/feature_flags.py +16 -36
  117. cognite_toolkit/_cdf_tk/plugins.py +2 -1
  118. cognite_toolkit/_cdf_tk/resource_classes/__init__.py +4 -0
  119. cognite_toolkit/_cdf_tk/resource_classes/capabilities.py +12 -0
  120. cognite_toolkit/_cdf_tk/resource_classes/functions.py +3 -1
  121. cognite_toolkit/_cdf_tk/resource_classes/infield_cdm_location_config.py +109 -0
  122. cognite_toolkit/_cdf_tk/resource_classes/migration.py +8 -17
  123. cognite_toolkit/_cdf_tk/resource_classes/search_config.py +1 -1
  124. cognite_toolkit/_cdf_tk/resource_classes/streams.py +29 -0
  125. cognite_toolkit/_cdf_tk/resource_classes/workflow_version.py +164 -5
  126. cognite_toolkit/_cdf_tk/storageio/__init__.py +9 -21
  127. cognite_toolkit/_cdf_tk/storageio/_annotations.py +19 -16
  128. cognite_toolkit/_cdf_tk/storageio/_applications.py +340 -28
  129. cognite_toolkit/_cdf_tk/storageio/_asset_centric.py +67 -104
  130. cognite_toolkit/_cdf_tk/storageio/_base.py +61 -29
  131. cognite_toolkit/_cdf_tk/storageio/_datapoints.py +276 -20
  132. cognite_toolkit/_cdf_tk/storageio/_file_content.py +435 -0
  133. cognite_toolkit/_cdf_tk/storageio/_instances.py +35 -3
  134. cognite_toolkit/_cdf_tk/storageio/_raw.py +26 -0
  135. cognite_toolkit/_cdf_tk/storageio/selectors/__init__.py +71 -4
  136. cognite_toolkit/_cdf_tk/storageio/selectors/_base.py +14 -2
  137. cognite_toolkit/_cdf_tk/storageio/selectors/_canvas.py +14 -0
  138. cognite_toolkit/_cdf_tk/storageio/selectors/_charts.py +14 -0
  139. cognite_toolkit/_cdf_tk/storageio/selectors/_datapoints.py +23 -3
  140. cognite_toolkit/_cdf_tk/storageio/selectors/_file_content.py +164 -0
  141. cognite_toolkit/_cdf_tk/storageio/selectors/_three_d.py +34 -0
  142. cognite_toolkit/_cdf_tk/tk_warnings/other.py +4 -0
  143. cognite_toolkit/_cdf_tk/tracker.py +2 -2
  144. cognite_toolkit/_cdf_tk/utils/cdf.py +1 -1
  145. cognite_toolkit/_cdf_tk/utils/dtype_conversion.py +9 -3
  146. cognite_toolkit/_cdf_tk/utils/fileio/__init__.py +2 -0
  147. cognite_toolkit/_cdf_tk/utils/fileio/_base.py +5 -1
  148. cognite_toolkit/_cdf_tk/utils/fileio/_readers.py +112 -20
  149. cognite_toolkit/_cdf_tk/utils/fileio/_writers.py +15 -15
  150. cognite_toolkit/_cdf_tk/utils/http_client/__init__.py +28 -0
  151. cognite_toolkit/_cdf_tk/utils/http_client/_client.py +285 -18
  152. cognite_toolkit/_cdf_tk/utils/http_client/_data_classes.py +56 -4
  153. cognite_toolkit/_cdf_tk/utils/http_client/_data_classes2.py +247 -0
  154. cognite_toolkit/_cdf_tk/utils/http_client/_tracker.py +5 -2
  155. cognite_toolkit/_cdf_tk/utils/interactive_select.py +60 -18
  156. cognite_toolkit/_cdf_tk/utils/sql_parser.py +2 -3
  157. cognite_toolkit/_cdf_tk/utils/useful_types.py +6 -2
  158. cognite_toolkit/_cdf_tk/validation.py +83 -1
  159. cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml +1 -1
  160. cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml +1 -1
  161. cognite_toolkit/_resources/cdf.toml +5 -4
  162. cognite_toolkit/_version.py +1 -1
  163. cognite_toolkit/config.dev.yaml +13 -0
  164. {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.39.dist-info}/METADATA +24 -24
  165. cognite_toolkit-0.7.39.dist-info/RECORD +322 -0
  166. cognite_toolkit-0.7.39.dist-info/WHEEL +4 -0
  167. {cognite_toolkit-0.6.97.dist-info → cognite_toolkit-0.7.39.dist-info}/entry_points.txt +1 -0
  168. cognite_toolkit/_cdf_tk/client/api/robotics/__init__.py +0 -3
  169. cognite_toolkit/_cdf_tk/commands/_migrate/canvas.py +0 -201
  170. cognite_toolkit/_cdf_tk/commands/dump_data.py +0 -489
  171. cognite_toolkit/_cdf_tk/commands/featureflag.py +0 -27
  172. cognite_toolkit/_cdf_tk/prototypes/import_app.py +0 -41
  173. cognite_toolkit/_cdf_tk/utils/table_writers.py +0 -434
  174. cognite_toolkit-0.6.97.dist-info/RECORD +0 -306
  175. cognite_toolkit-0.6.97.dist-info/WHEEL +0 -4
  176. cognite_toolkit-0.6.97.dist-info/licenses/LICENSE +0 -18
  177. /cognite_toolkit/_cdf_tk/{prototypes/commands → client/api/legacy}/__init__.py +0 -0
  178. /cognite_toolkit/_cdf_tk/client/api/{dml.py → legacy/dml.py} +0 -0
  179. /cognite_toolkit/_cdf_tk/client/api/{fixed_transformations.py → legacy/fixed_transformations.py} +0 -0
  180. /cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/api.py +0 -0
  181. /cognite_toolkit/_cdf_tk/client/api/{robotics → legacy/robotics}/utlis.py +0 -0
  182. /cognite_toolkit/_cdf_tk/client/data_classes/{apm_config_v1.py → legacy/apm_config_v1.py} +0 -0
  183. /cognite_toolkit/_cdf_tk/client/data_classes/{extendable_cognite_file.py → legacy/extendable_cognite_file.py} +0 -0
  184. /cognite_toolkit/_cdf_tk/client/data_classes/{extended_filemetadata.py → legacy/extended_filemetadata.py} +0 -0
  185. /cognite_toolkit/_cdf_tk/client/data_classes/{extended_filemetdata.py → legacy/extended_filemetdata.py} +0 -0
  186. /cognite_toolkit/_cdf_tk/client/data_classes/{extended_timeseries.py → legacy/extended_timeseries.py} +0 -0
  187. /cognite_toolkit/_cdf_tk/client/data_classes/{functions.py → legacy/functions.py} +0 -0
  188. /cognite_toolkit/_cdf_tk/client/data_classes/{graphql_data_models.py → legacy/graphql_data_models.py} +0 -0
  189. /cognite_toolkit/_cdf_tk/client/data_classes/{instances.py → legacy/instances.py} +0 -0
  190. /cognite_toolkit/_cdf_tk/client/data_classes/{location_filters.py → legacy/location_filters.py} +0 -0
  191. /cognite_toolkit/_cdf_tk/client/data_classes/{pending_instances_ids.py → legacy/pending_instances_ids.py} +0 -0
  192. /cognite_toolkit/_cdf_tk/client/data_classes/{project.py → legacy/project.py} +0 -0
  193. /cognite_toolkit/_cdf_tk/client/data_classes/{raw.py → legacy/raw.py} +0 -0
  194. /cognite_toolkit/_cdf_tk/client/data_classes/{robotics.py → legacy/robotics.py} +0 -0
  195. /cognite_toolkit/_cdf_tk/client/data_classes/{search_config.py → legacy/search_config.py} +0 -0
  196. /cognite_toolkit/_cdf_tk/client/data_classes/{sequences.py → legacy/sequences.py} +0 -0
  197. /cognite_toolkit/_cdf_tk/client/data_classes/{streamlit_.py → legacy/streamlit_.py} +0 -0
  198. /cognite_toolkit/_cdf_tk/{prototypes/commands/import_.py → commands/_import_cmd.py} +0 -0
@@ -1,489 +0,0 @@
1
- import time
2
- from abc import ABC, abstractmethod
3
- from collections.abc import Callable, Iterable, Iterator
4
- from functools import lru_cache
5
- from itertools import groupby
6
- from pathlib import Path
7
- from typing import Any, ClassVar, Generic, Literal
8
-
9
- from cognite.client.data_classes import (
10
- Asset,
11
- AssetFilter,
12
- DataSetList,
13
- Event,
14
- EventFilter,
15
- FileMetadata,
16
- FileMetadataFilter,
17
- LabelDefinitionList,
18
- TimeSeries,
19
- TimeSeriesFilter,
20
- )
21
- from cognite.client.data_classes._base import T_CogniteResource
22
- from rich.console import Console
23
- from rich.progress import track
24
-
25
- from cognite_toolkit._cdf_tk.client import ToolkitClient
26
- from cognite_toolkit._cdf_tk.commands._base import ToolkitCommand
27
- from cognite_toolkit._cdf_tk.cruds import (
28
- AssetCRUD,
29
- DataSetsCRUD,
30
- EventCRUD,
31
- FileMetadataCRUD,
32
- LabelCRUD,
33
- ResourceCRUD,
34
- TimeSeriesCRUD,
35
- )
36
- from cognite_toolkit._cdf_tk.exceptions import (
37
- ToolkitFileExistsError,
38
- ToolkitIsADirectoryError,
39
- ToolkitValueError,
40
- )
41
- from cognite_toolkit._cdf_tk.utils import humanize_collection
42
- from cognite_toolkit._cdf_tk.utils.cdf import metadata_key_counts
43
- from cognite_toolkit._cdf_tk.utils.file import safe_rmtree
44
- from cognite_toolkit._cdf_tk.utils.producer_worker import ProducerWorkerExecutor
45
- from cognite_toolkit._cdf_tk.utils.table_writers import (
46
- FileFormat,
47
- Schema,
48
- SchemaColumn,
49
- SchemaColumnList,
50
- TableFileWriter,
51
- )
52
-
53
-
54
- class DataFinder:
55
- supported_formats: ClassVar[frozenset[FileFormat]] = frozenset()
56
- # This is the standard maximum items that can be returns by most CDF endpoints.
57
- chunk_size: ClassVar[int] = 1000
58
-
59
- def validate_format(self, format_: str) -> Literal[FileFormat]:
60
- if format_ in self.supported_formats:
61
- return format_ # type: ignore[return-value]
62
- raise ToolkitValueError(
63
- f"Unsupported format {format_}. Supported formats are {humanize_collection(self.supported_formats)}."
64
- )
65
-
66
- @abstractmethod
67
- def create_iterators(
68
- self, format_: FileFormat, limit: int | None
69
- ) -> Iterator[tuple[Schema, int, Iterable, Callable]]:
70
- """Create an iterator for the specified format."""
71
- raise NotImplementedError("This method should be implemented in subclasses.")
72
-
73
-
74
- class AssetCentricFinder(DataFinder, ABC, Generic[T_CogniteResource]):
75
- def __init__(self, client: ToolkitClient, hierarchies: list[str], data_sets: list[str]):
76
- self.client = client
77
- self.hierarchies = hierarchies
78
- self.data_sets = data_sets
79
- self.loader = self._create_loader(client)
80
- self._hierarchy_set = set(self.hierarchies)
81
- self._data_set_set = set(self.data_sets)
82
- self._used_labels: set[str] = set()
83
- self._used_data_sets: set[str] = set()
84
-
85
- @abstractmethod
86
- def _create_loader(self, client: ToolkitClient) -> ResourceCRUD:
87
- """Create the appropriate loader for the finder."""
88
- raise NotImplementedError()
89
-
90
- @lru_cache
91
- def aggregate_count(self, hierarchies: tuple[str, ...], data_sets: tuple[str, ...]) -> int:
92
- return self._aggregate_count(list(hierarchies), list(data_sets))
93
-
94
- @abstractmethod
95
- def _aggregate_count(self, hierarchies: list[str], data_sets: list[str]) -> int:
96
- raise NotImplementedError()
97
-
98
- @abstractmethod
99
- def _get_resource_columns(self) -> SchemaColumnList:
100
- """Get the columns for the schema."""
101
- raise NotImplementedError()
102
-
103
- @abstractmethod
104
- def create_resource_iterator(self, limit: int | None) -> Iterable:
105
- raise NotImplementedError()
106
-
107
- @abstractmethod
108
- def _resource_processor(self, items: Iterable[T_CogniteResource]) -> list[tuple[str, list[dict[str, Any]]]]:
109
- """Process the resources and return them in a format suitable for writing."""
110
- raise NotImplementedError()
111
-
112
- def _to_write(self, items: Iterable[T_CogniteResource]) -> list[dict[str, Any]]:
113
- write_items: list[dict[str, Any]] = []
114
- for item in items:
115
- dumped = self.loader.dump_resource(item)
116
- if "metadata" in dumped:
117
- metadata = dumped.pop("metadata")
118
- for key, value in metadata.items():
119
- dumped[f"metadata.{key}"] = value
120
- if isinstance(dumped.get("labels"), list):
121
- dumped["labels"] = [label["externalId"] for label in dumped["labels"]]
122
- self._used_labels.update(dumped["labels"])
123
- if "dataSetExternalId" in dumped:
124
- self._used_data_sets.add(dumped["dataSetExternalId"])
125
- write_items.append(dumped)
126
- return write_items
127
-
128
- def create_iterators(
129
- self, format_: FileFormat, limit: int | None
130
- ) -> Iterator[tuple[Schema, int, Iterable, Callable]]:
131
- total = self.aggregate_count(tuple(self.hierarchies), tuple(self.data_sets))
132
- columns = self._get_resource_columns()
133
-
134
- iteration_count = total // self.chunk_size + (1 if total % self.chunk_size > 0 else 0)
135
- if iteration_count == 0:
136
- return
137
-
138
- yield (
139
- Schema(
140
- display_name=self.loader.display_name,
141
- format_=format_,
142
- columns=columns,
143
- folder_name=self.loader.folder_name,
144
- kind=self.loader.kind,
145
- ),
146
- iteration_count,
147
- self.create_resource_iterator(limit),
148
- self._resource_processor,
149
- )
150
- if self._used_data_sets:
151
- yield self._data_sets()
152
- if self._used_labels:
153
- yield self._labels()
154
-
155
- def _data_sets(self) -> tuple[Schema, int, Iterable, Callable]:
156
- data_sets = self.client.data_sets.retrieve_multiple(
157
- external_ids=list(self._used_data_sets), ignore_unknown_ids=True
158
- )
159
- loader = DataSetsCRUD.create_loader(self.client)
160
-
161
- def process_data_sets(items: DataSetList) -> list[tuple[str, list[dict[str, Any]]]]:
162
- # All data sets are written to a single group, thus the empty string as the group key.
163
- # (Group keys are for example used in CSV files to create separate files for each
164
- # data set an asset belongs to.)
165
- return [("", [loader.dump_resource(item) for item in items])]
166
-
167
- return (
168
- # YAML format does not need columns.
169
- Schema(
170
- display_name=loader.display_name,
171
- format_="yaml",
172
- columns=SchemaColumnList(),
173
- folder_name=loader.folder_name,
174
- kind=loader.kind,
175
- ),
176
- 1,
177
- [data_sets],
178
- process_data_sets,
179
- )
180
-
181
- def _labels(self) -> tuple[Schema, int, Iterable, Callable]:
182
- labels = self.client.labels.retrieve(external_id=list(self._used_labels))
183
- loader = LabelCRUD.create_loader(self.client)
184
-
185
- def process_labels(items: LabelDefinitionList) -> list[tuple[str, list[dict[str, Any]]]]:
186
- # All labels are written to a single group, thus the empty string as the group key.
187
- # (Group keys are for example used in CSV files to create separate files for each
188
- # label an asset belongs to.)
189
- return [("", [loader.dump_resource(item) for item in items])]
190
-
191
- return (
192
- # YAML format does not need columns.
193
- Schema(
194
- display_name=loader.display_name,
195
- format_="yaml",
196
- columns=SchemaColumnList(),
197
- folder_name=loader.folder_name,
198
- kind=loader.kind,
199
- ),
200
- 1,
201
- [labels],
202
- process_labels,
203
- )
204
-
205
-
206
- class AssetFinder(AssetCentricFinder[Asset]):
207
- supported_formats = frozenset({"csv", "parquet", "yaml"})
208
-
209
- def _create_loader(self, client: ToolkitClient) -> ResourceCRUD:
210
- return AssetCRUD.create_loader(client)
211
-
212
- def _aggregate_count(self, hierarchies: list[str], data_sets: list[str]) -> int:
213
- return self.client.assets.aggregate_count(
214
- filter=AssetFilter(
215
- data_set_ids=[{"externalId": item} for item in data_sets] or None,
216
- asset_subtree_ids=[{"externalId": item} for item in hierarchies] or None,
217
- )
218
- )
219
-
220
- def create_resource_iterator(self, limit: int | None) -> Iterator:
221
- return self.client.assets(
222
- chunk_size=self.chunk_size,
223
- asset_subtree_external_ids=self.hierarchies or None,
224
- data_set_external_ids=self.data_sets or None,
225
- limit=limit,
226
- )
227
-
228
- def _resource_processor(self, assets: Iterable[Asset]) -> list[tuple[str, list[dict[str, Any]]]]:
229
- grouped_assets: list[tuple[str, list[dict[str, object]]]] = []
230
- for group, asset_group in groupby(
231
- sorted([(self._group(asset), asset) for asset in assets], key=lambda x: x[0]), key=lambda x: x[0]
232
- ):
233
- grouped_assets.append((group, self._to_write([asset for _, asset in asset_group])))
234
- return grouped_assets
235
-
236
- def _group(self, item: Asset) -> str:
237
- if self.hierarchies and self.data_sets:
238
- asset_external_id = self.client.lookup.assets.external_id(item.root_id or 0)
239
- data_set_external_id = self.client.lookup.data_sets.external_id(item.data_set_id or 0)
240
- if asset_external_id and data_set_external_id:
241
- return f"{asset_external_id}.{data_set_external_id}"
242
- elif asset_external_id:
243
- return asset_external_id
244
- elif data_set_external_id:
245
- return data_set_external_id
246
- return ""
247
- elif self.hierarchies:
248
- return self.client.lookup.assets.external_id(item.root_id or 0) or ""
249
- elif self.data_sets:
250
- return self.client.lookup.data_sets.external_id(item.data_set_id or 0) or ""
251
- return ""
252
-
253
- def _get_resource_columns(self) -> SchemaColumnList:
254
- columns = SchemaColumnList(
255
- [
256
- SchemaColumn(name="externalId", type="string"),
257
- SchemaColumn(name="name", type="string"),
258
- SchemaColumn(name="parentExternalId", type="string"),
259
- SchemaColumn(name="description", type="string"),
260
- SchemaColumn(name="dataSetExternalId", type="string"),
261
- SchemaColumn(name="source", type="string"),
262
- SchemaColumn(name="labels", type="string", is_array=True),
263
- SchemaColumn(name="geoLocation", type="json"),
264
- ]
265
- )
266
- data_set_ids = self.client.lookup.data_sets.id(self.data_sets) if self.data_sets else []
267
- root_ids = self.client.lookup.assets.id(self.hierarchies) if self.hierarchies else []
268
- metadata_keys = metadata_key_counts(self.client, "assets", data_set_ids or None, root_ids or None)
269
- sorted_keys = sorted([key for key, count in metadata_keys if count > 0])
270
- columns.extend([SchemaColumn(name=f"metadata.{key}", type="string") for key in sorted_keys])
271
- return columns
272
-
273
-
274
- class FileMetadataFinder(AssetCentricFinder[FileMetadata]):
275
- supported_formats = frozenset({"csv", "parquet"})
276
-
277
- def _create_loader(self, client: ToolkitClient) -> ResourceCRUD:
278
- return FileMetadataCRUD.create_loader(client)
279
-
280
- def _aggregate_count(self, hierarchies: list[str], data_sets: list[str]) -> int:
281
- result = self.client.files.aggregate(
282
- filter=FileMetadataFilter(
283
- data_set_ids=[{"externalId": item} for item in data_sets] or None,
284
- asset_subtree_ids=[{"externalId": item} for item in hierarchies] or None,
285
- )
286
- )
287
- return result[0].count if result else 0
288
-
289
- def _get_resource_columns(self) -> SchemaColumnList:
290
- columns = SchemaColumnList(
291
- [
292
- SchemaColumn(name="externalId", type="string"),
293
- SchemaColumn(name="name", type="string"),
294
- SchemaColumn(name="directory", type="string"),
295
- SchemaColumn(name="source", type="string"),
296
- SchemaColumn(name="mimeType", type="string"),
297
- SchemaColumn(name="assetExternalIds", type="string", is_array=True),
298
- SchemaColumn(name="dataSetExternalId", type="string"),
299
- SchemaColumn(name="sourceCreatedTime", type="integer"),
300
- SchemaColumn(name="sourceModifiedTime", type="integer"),
301
- SchemaColumn(name="securityCategories", type="string", is_array=True),
302
- SchemaColumn(name="labels", type="string", is_array=True),
303
- SchemaColumn(name="geoLocation", type="json"),
304
- ]
305
- )
306
- data_set_ids = self.client.lookup.data_sets.id(self.data_sets) if self.data_sets else []
307
- root_ids = self.client.lookup.assets.id(self.hierarchies) if self.hierarchies else []
308
- metadata_keys = metadata_key_counts(self.client, "files", data_set_ids or None, root_ids or None)
309
- sorted_keys = sorted([key for key, count in metadata_keys if count > 0])
310
- columns.extend([SchemaColumn(name=f"metadata.{key}", type="string") for key in sorted_keys])
311
- return columns
312
-
313
- def create_resource_iterator(self, limit: int | None) -> Iterable:
314
- return self.client.files(
315
- chunk_size=self.chunk_size,
316
- asset_subtree_external_ids=self.hierarchies or None,
317
- data_set_external_ids=self.data_sets or None,
318
- limit=limit,
319
- )
320
-
321
- def _resource_processor(self, items: Iterable[FileMetadata]) -> list[tuple[str, list[dict[str, Any]]]]:
322
- return [("", self._to_write(items))]
323
-
324
-
325
- class TimeSeriesFinder(AssetCentricFinder[TimeSeries]):
326
- supported_formats = frozenset({"csv", "parquet", "yaml"})
327
-
328
- def _create_loader(self, client: ToolkitClient) -> TimeSeriesCRUD:
329
- return TimeSeriesCRUD.create_loader(client)
330
-
331
- def _aggregate_count(self, hierarchies: list[str], data_sets: list[str]) -> int:
332
- return self.client.time_series.aggregate_count(
333
- filter=TimeSeriesFilter(
334
- data_set_ids=[{"externalId": item} for item in data_sets] or None,
335
- asset_subtree_ids=[{"externalId": item} for item in hierarchies] or None,
336
- )
337
- )
338
-
339
- def create_resource_iterator(self, limit: int | None) -> Iterator:
340
- return self.client.time_series(
341
- chunk_size=self.chunk_size,
342
- asset_subtree_external_ids=self.hierarchies or None,
343
- data_set_external_ids=self.data_sets or None,
344
- limit=limit,
345
- )
346
-
347
- def _resource_processor(self, time_series: Iterable[TimeSeries]) -> list[tuple[str, list[dict[str, Any]]]]:
348
- return [("", self._to_write(time_series))]
349
-
350
- def _get_resource_columns(self) -> SchemaColumnList:
351
- columns = SchemaColumnList(
352
- [
353
- SchemaColumn(name="externalId", type="string"),
354
- SchemaColumn(name="name", type="string"),
355
- SchemaColumn(name="isString", type="boolean"),
356
- SchemaColumn(name="unit", type="string"),
357
- SchemaColumn(name="unitExternalId", type="string"),
358
- SchemaColumn(name="assetExternalId", type="string"),
359
- SchemaColumn(name="isStep", type="boolean"),
360
- SchemaColumn(name="description", type="string"),
361
- SchemaColumn(name="dataSetExternalId", type="string"),
362
- SchemaColumn(name="securityCategories", type="string", is_array=True),
363
- ]
364
- )
365
- data_set_ids = self.client.lookup.data_sets.id(self.data_sets) if self.data_sets else []
366
- root_ids = self.client.lookup.assets.id(self.hierarchies) if self.hierarchies else []
367
- metadata_keys = metadata_key_counts(self.client, "timeseries", data_set_ids or None, root_ids or None)
368
- sorted_keys = sorted([key for key, count in metadata_keys if count > 0])
369
- columns.extend([SchemaColumn(name=f"metadata.{key}", type="string") for key in sorted_keys])
370
- return columns
371
-
372
-
373
- class EventFinder(AssetCentricFinder[Event]):
374
- supported_formats = frozenset({"csv", "parquet"})
375
-
376
- def _create_loader(self, client: ToolkitClient) -> ResourceCRUD:
377
- return EventCRUD.create_loader(client)
378
-
379
- def _aggregate_count(self, hierarchies: list[str], data_sets: list[str]) -> int:
380
- return self.client.events.aggregate_count(
381
- filter=EventFilter(
382
- data_set_ids=[{"externalId": item} for item in data_sets] or None,
383
- asset_subtree_ids=[{"externalId": item} for item in hierarchies] or None,
384
- )
385
- )
386
-
387
- def _get_resource_columns(self) -> SchemaColumnList:
388
- columns = SchemaColumnList(
389
- [
390
- SchemaColumn(name="externalId", type="string"),
391
- SchemaColumn(name="dataSetExternalId", type="string"),
392
- SchemaColumn(name="startTime", type="integer"),
393
- SchemaColumn(name="endTime", type="integer"),
394
- SchemaColumn(name="type", type="string"),
395
- SchemaColumn(name="subtype", type="string"),
396
- SchemaColumn(name="description", type="string"),
397
- SchemaColumn(name="assetExternalIds", type="string", is_array=True),
398
- SchemaColumn(name="source", type="string"),
399
- ]
400
- )
401
- data_set_ids = self.client.lookup.data_sets.id(self.data_sets) if self.data_sets else []
402
- root_ids = self.client.lookup.assets.id(self.hierarchies) if self.hierarchies else []
403
- metadata_keys = metadata_key_counts(self.client, "events", data_set_ids or None, root_ids or None)
404
- sorted_keys = sorted([key for key, count in metadata_keys if count > 0])
405
- columns.extend([SchemaColumn(name=f"metadata.{key}", type="string") for key in sorted_keys])
406
- return columns
407
-
408
- def create_resource_iterator(self, limit: int | None) -> Iterable:
409
- return self.client.events(
410
- chunk_size=self.chunk_size,
411
- asset_subtree_external_ids=self.hierarchies or None,
412
- data_set_external_ids=self.data_sets or None,
413
- limit=limit,
414
- )
415
-
416
- def _resource_processor(self, items: Iterable[Event]) -> list[tuple[str, list[dict[str, Any]]]]:
417
- return [("", self._to_write(items))]
418
-
419
-
420
- class DumpDataCommand(ToolkitCommand):
421
- def dump_table(
422
- self,
423
- finder: DataFinder,
424
- output_dir: Path,
425
- clean: bool,
426
- limit: int | None = None,
427
- format_: str = "csv",
428
- verbose: bool = False,
429
- parallel_threshold: int = 10,
430
- max_queue_size: int = 10,
431
- ) -> None:
432
- """Dumps data from CDF to a file
433
-
434
- Args:
435
- finder (DataFinder): The finder object to use for fetching data.
436
- output_dir (Path): The directory to write the output files to.
437
- clean (bool): Whether to clean the output directory before writing files.
438
- limit (int | None, optional): The maximum number of rows to write. Defaults to None.
439
- format_ (Literal["yaml", "csv", "parquet"], optional): The format of the output file. Defaults to "csv".
440
- verbose (bool, optional): Whether to print detailed progress information. Defaults to False.
441
- parallel_threshold (int, optional): The iteration threshold for parallel processing. Defaults to 10.
442
- max_queue_size (int, optional): If using parallel processing, the maximum size of the queue. Defaults to 10.
443
-
444
- """
445
- valid_format = finder.validate_format(format_)
446
- self.validate_directory(output_dir, clean)
447
-
448
- console = Console()
449
- # The ignore is used as MyPy does not understand that is_supported_format
450
- # above guarantees that the format is valid.
451
- for schema, iteration_count, resource_iterator, resource_processor in finder.create_iterators(
452
- valid_format, limit
453
- ):
454
- writer_cls = TableFileWriter.get_write_cls(schema.format_)
455
- row_counts = 0
456
- t0 = time.perf_counter()
457
- with writer_cls(schema, output_dir) as writer:
458
- if iteration_count > parallel_threshold:
459
- executor = ProducerWorkerExecutor(
460
- download_iterable=resource_iterator,
461
- process=resource_processor,
462
- write=writer.write_rows,
463
- iteration_count=iteration_count,
464
- max_queue_size=max_queue_size,
465
- download_description=f"Downloading {schema.display_name}",
466
- process_description=f"Processing {schema.display_name}",
467
- write_description=f"Writing {schema.display_name} to file",
468
- )
469
- executor.run()
470
- executor.raise_on_error()
471
- row_counts = executor.total_items
472
- else:
473
- for resources in track(
474
- resource_iterator, total=iteration_count, description=f"Dumping {schema.display_name}"
475
- ):
476
- row_counts += len(resources)
477
- processed = resource_processor(resources)
478
- writer.write_rows(processed)
479
- elapsed = time.perf_counter() - t0
480
- console.print(f"Dumped {row_counts:,} rows to {output_dir} in {elapsed:,.2f} seconds.")
481
-
482
- @staticmethod
483
- def validate_directory(output_dir: Path, clean: bool) -> None:
484
- if output_dir.exists() and clean:
485
- safe_rmtree(output_dir)
486
- elif output_dir.exists():
487
- raise ToolkitFileExistsError(f"Output directory {output_dir!s} already exists. Use --clean to remove it.")
488
- elif output_dir.suffix:
489
- raise ToolkitIsADirectoryError(f"Output directory {output_dir!s} is not a directory.")
@@ -1,27 +0,0 @@
1
- from rich import print
2
- from rich.table import Table
3
-
4
- from cognite_toolkit._cdf_tk.cdf_toml import CDFToml
5
- from cognite_toolkit._cdf_tk.commands._base import ToolkitCommand
6
- from cognite_toolkit._cdf_tk.feature_flags import Flags
7
-
8
-
9
- class FeatureFlagCommand(ToolkitCommand):
10
- @staticmethod
11
- def list() -> None:
12
- user_settings = CDFToml.load().alpha_flags
13
- table = Table(title="feature flags")
14
- table.add_column("Name", justify="left")
15
- table.add_column("Description", justify="left")
16
- table.add_column("Status", justify="left")
17
-
18
- for flag in Flags:
19
- is_enabled = user_settings.get(flag.name, False)
20
- if is_enabled or flag.value.visible:
21
- table.add_row(
22
- flag.name,
23
- flag.value.description,
24
- "enabled" if is_enabled else "disabled",
25
- style="yellow" if is_enabled else "",
26
- )
27
- print(table)
@@ -1,41 +0,0 @@
1
- from pathlib import Path
2
-
3
- import typer
4
-
5
- from cognite_toolkit._cdf_tk.client import ToolkitClient
6
- from cognite_toolkit._cdf_tk.utils.auth import EnvironmentVariables
7
-
8
- from .commands.import_ import ImportTransformationCLI
9
-
10
- import_app = typer.Typer(
11
- pretty_exceptions_short=False, pretty_exceptions_show_locals=False, pretty_exceptions_enable=False
12
- )
13
-
14
-
15
- @import_app.callback(invoke_without_command=True)
16
- def import_main(ctx: typer.Context) -> None:
17
- """PREVIEW FEATURE Import resources into Cognite-Toolkit."""
18
- if ctx.invoked_subcommand is None:
19
- print("Use [bold yellow]cdf-tk import --help[/] for more information.")
20
- return None
21
-
22
-
23
- @import_app.command("transformation-cli")
24
- def transformation_cli(
25
- source: Path = typer.Argument(..., help="Path to the transformation CLI manifest directory or files."),
26
- destination: Path = typer.Argument(..., help="Path to the destination directory."),
27
- overwrite: bool = typer.Option(False, help="Overwrite destination if it already exists."),
28
- flatten: bool = typer.Option(False, help="Flatten the directory structure."),
29
- clean: bool = typer.Option(False, help="Remove the source directory after import."),
30
- verbose: bool = typer.Option(False, help="Turn on to get more verbose output when running the command"),
31
- ) -> None:
32
- """Import transformation CLI manifests into Cognite-Toolkit modules."""
33
-
34
- # We are lazy loading the client as we only need it if we need to look up dataset ids.
35
- # This is to ensure the command can be executed without a client if the user does not need to look up dataset ids.
36
- # (which is likely 99% of the time)
37
- def get_client() -> ToolkitClient:
38
- return EnvironmentVariables.create_from_environment().get_client()
39
-
40
- cmd = ImportTransformationCLI(print_warning=True, get_client=get_client)
41
- cmd.execute(source, destination, overwrite, flatten, clean, verbose=verbose)