cognite-extractor-utils 7.5.14__py3-none-any.whl → 7.6.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.
Potentially problematic release.
This version of cognite-extractor-utils might be problematic. Click here for more details.
- cognite/extractorutils/__init__.py +1 -1
- cognite/extractorutils/_inner_util.py +1 -1
- cognite/extractorutils/base.py +120 -40
- cognite/extractorutils/configtools/__init__.py +4 -5
- cognite/extractorutils/configtools/_util.py +3 -2
- cognite/extractorutils/configtools/elements.py +206 -33
- cognite/extractorutils/configtools/loaders.py +68 -16
- cognite/extractorutils/configtools/validators.py +5 -1
- cognite/extractorutils/exceptions.py +11 -2
- cognite/extractorutils/metrics.py +17 -12
- cognite/extractorutils/statestore/__init__.py +77 -3
- cognite/extractorutils/statestore/_base.py +7 -3
- cognite/extractorutils/statestore/hashing.py +129 -15
- cognite/extractorutils/statestore/watermark.py +77 -87
- cognite/extractorutils/threading.py +30 -4
- cognite/extractorutils/unstable/__init__.py +5 -5
- cognite/extractorutils/unstable/configuration/__init__.py +3 -0
- cognite/extractorutils/unstable/configuration/exceptions.py +13 -2
- cognite/extractorutils/unstable/configuration/loaders.py +78 -13
- cognite/extractorutils/unstable/configuration/models.py +121 -7
- cognite/extractorutils/unstable/core/__init__.py +5 -0
- cognite/extractorutils/unstable/core/_dto.py +5 -3
- cognite/extractorutils/unstable/core/base.py +113 -4
- cognite/extractorutils/unstable/core/errors.py +41 -0
- cognite/extractorutils/unstable/core/logger.py +149 -0
- cognite/extractorutils/unstable/core/restart_policy.py +16 -2
- cognite/extractorutils/unstable/core/runtime.py +44 -6
- cognite/extractorutils/unstable/core/tasks.py +53 -1
- cognite/extractorutils/unstable/scheduling/__init__.py +13 -0
- cognite/extractorutils/unstable/scheduling/_scheduler.py +1 -1
- cognite/extractorutils/uploader/__init__.py +7 -5
- cognite/extractorutils/uploader/_base.py +4 -5
- cognite/extractorutils/uploader/assets.py +13 -8
- cognite/extractorutils/uploader/data_modeling.py +37 -2
- cognite/extractorutils/uploader/events.py +14 -9
- cognite/extractorutils/uploader/files.py +80 -21
- cognite/extractorutils/uploader/raw.py +12 -7
- cognite/extractorutils/uploader/time_series.py +58 -49
- cognite/extractorutils/uploader/upload_failure_handler.py +35 -2
- cognite/extractorutils/uploader_extractor.py +29 -6
- cognite/extractorutils/uploader_types.py +15 -1
- cognite/extractorutils/util.py +76 -23
- {cognite_extractor_utils-7.5.14.dist-info → cognite_extractor_utils-7.6.0.dist-info}/METADATA +1 -1
- cognite_extractor_utils-7.6.0.dist-info/RECORD +50 -0
- cognite_extractor_utils-7.5.14.dist-info/RECORD +0 -50
- {cognite_extractor_utils-7.5.14.dist-info → cognite_extractor_utils-7.6.0.dist-info}/WHEEL +0 -0
- {cognite_extractor_utils-7.5.14.dist-info → cognite_extractor_utils-7.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module containing pre-built elements for common extractor configuration.
|
|
3
|
+
"""
|
|
4
|
+
|
|
1
5
|
# Copyright 2023 Cognite AS
|
|
2
6
|
#
|
|
3
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -56,7 +60,7 @@ _logger = logging.getLogger(__name__)
|
|
|
56
60
|
@dataclass
|
|
57
61
|
class CertificateConfig:
|
|
58
62
|
"""
|
|
59
|
-
Configuration parameters for certificates
|
|
63
|
+
Configuration parameters for certificates.
|
|
60
64
|
"""
|
|
61
65
|
|
|
62
66
|
path: str
|
|
@@ -67,7 +71,7 @@ class CertificateConfig:
|
|
|
67
71
|
@dataclass
|
|
68
72
|
class AuthenticatorConfig:
|
|
69
73
|
"""
|
|
70
|
-
Configuration parameters for an OIDC flow
|
|
74
|
+
Configuration parameters for an OIDC flow.
|
|
71
75
|
"""
|
|
72
76
|
|
|
73
77
|
client_id: str
|
|
@@ -85,7 +89,7 @@ class AuthenticatorConfig:
|
|
|
85
89
|
@dataclass
|
|
86
90
|
class ConnectionConfig:
|
|
87
91
|
"""
|
|
88
|
-
Configuration parameters for the global_config python SDK settings
|
|
92
|
+
Configuration parameters for the global_config python SDK settings.
|
|
89
93
|
"""
|
|
90
94
|
|
|
91
95
|
disable_gzip: bool = False
|
|
@@ -102,6 +106,7 @@ class ConnectionConfig:
|
|
|
102
106
|
class EitherIdConfig:
|
|
103
107
|
"""
|
|
104
108
|
Configuration parameter representing an ID in CDF, which can either be an external or internal ID.
|
|
109
|
+
|
|
105
110
|
An EitherId can only hold one ID type, not both.
|
|
106
111
|
"""
|
|
107
112
|
|
|
@@ -110,23 +115,35 @@ class EitherIdConfig:
|
|
|
110
115
|
|
|
111
116
|
@property
|
|
112
117
|
def either_id(self) -> EitherId:
|
|
118
|
+
"""
|
|
119
|
+
Returns an EitherId object based on the current configuration.
|
|
120
|
+
|
|
121
|
+
Raises:
|
|
122
|
+
TypeError: If both id and external_id are None, or if both are set.
|
|
123
|
+
"""
|
|
113
124
|
return EitherId(id=self.id, external_id=self.external_id)
|
|
114
125
|
|
|
115
126
|
|
|
116
127
|
class TimeIntervalConfig(yaml.YAMLObject):
|
|
117
128
|
"""
|
|
118
|
-
Configuration parameter for setting a time interval
|
|
129
|
+
Configuration parameter for setting a time interval.
|
|
119
130
|
"""
|
|
120
131
|
|
|
121
132
|
def __init__(self, expression: str) -> None:
|
|
122
133
|
self._interval, self._expression = TimeIntervalConfig._parse_expression(expression)
|
|
123
134
|
|
|
124
135
|
def __eq__(self, other: object) -> bool:
|
|
136
|
+
"""
|
|
137
|
+
Two TimeIntervalConfig objects are equal if they have the same number of seconds in their interval.
|
|
138
|
+
"""
|
|
125
139
|
if not isinstance(other, TimeIntervalConfig):
|
|
126
140
|
return NotImplemented
|
|
127
141
|
return self._interval == other._interval
|
|
128
142
|
|
|
129
143
|
def __hash__(self) -> int:
|
|
144
|
+
"""
|
|
145
|
+
Hash function for TimeIntervalConfig based on the number of seconds in the interval.
|
|
146
|
+
"""
|
|
130
147
|
return hash(self._interval)
|
|
131
148
|
|
|
132
149
|
@classmethod
|
|
@@ -148,42 +165,75 @@ class TimeIntervalConfig(yaml.YAMLObject):
|
|
|
148
165
|
|
|
149
166
|
@property
|
|
150
167
|
def seconds(self) -> int:
|
|
168
|
+
"""
|
|
169
|
+
Time interval as number of seconds.
|
|
170
|
+
"""
|
|
151
171
|
return self._interval
|
|
152
172
|
|
|
153
173
|
@property
|
|
154
174
|
def minutes(self) -> float:
|
|
175
|
+
"""
|
|
176
|
+
Time interval as number of minutes.
|
|
177
|
+
|
|
178
|
+
This is a float since the underlying interval is in seconds.
|
|
179
|
+
"""
|
|
155
180
|
return self._interval / 60
|
|
156
181
|
|
|
157
182
|
@property
|
|
158
183
|
def hours(self) -> float:
|
|
184
|
+
"""
|
|
185
|
+
Time interval as number of hours.
|
|
186
|
+
|
|
187
|
+
This is a float since the underlying interval is in seconds.
|
|
188
|
+
"""
|
|
159
189
|
return self._interval / (60 * 60)
|
|
160
190
|
|
|
161
191
|
@property
|
|
162
192
|
def days(self) -> float:
|
|
193
|
+
"""
|
|
194
|
+
Time interval as number of days.
|
|
195
|
+
|
|
196
|
+
This is a float since the underlying interval is in seconds.
|
|
197
|
+
"""
|
|
163
198
|
return self._interval / (60 * 60 * 24)
|
|
164
199
|
|
|
165
200
|
@property
|
|
166
201
|
def timedelta(self) -> timedelta:
|
|
202
|
+
"""
|
|
203
|
+
Time interval as a timedelta object.
|
|
204
|
+
"""
|
|
167
205
|
days = self._interval // (60 * 60 * 24)
|
|
168
206
|
seconds = self._interval % (60 * 60 * 24)
|
|
169
207
|
return timedelta(days=days, seconds=seconds)
|
|
170
208
|
|
|
171
209
|
def __int__(self) -> int:
|
|
210
|
+
"""
|
|
211
|
+
Returns the time interval as a number of seconds.
|
|
212
|
+
"""
|
|
172
213
|
return int(self._interval)
|
|
173
214
|
|
|
174
215
|
def __float__(self) -> float:
|
|
216
|
+
"""
|
|
217
|
+
Returns the time interval as a number of seconds.
|
|
218
|
+
"""
|
|
175
219
|
return float(self._interval)
|
|
176
220
|
|
|
177
221
|
def __str__(self) -> str:
|
|
222
|
+
"""
|
|
223
|
+
Returns the time interval as a human readable string.
|
|
224
|
+
"""
|
|
178
225
|
return self._expression
|
|
179
226
|
|
|
180
227
|
def __repr__(self) -> str:
|
|
228
|
+
"""
|
|
229
|
+
Returns the time interval as a human readable string.
|
|
230
|
+
"""
|
|
181
231
|
return self._expression
|
|
182
232
|
|
|
183
233
|
|
|
184
234
|
class FileSizeConfig(yaml.YAMLObject):
|
|
185
235
|
"""
|
|
186
|
-
Configuration parameter for setting a file size
|
|
236
|
+
Configuration parameter for setting a file size.
|
|
187
237
|
"""
|
|
188
238
|
|
|
189
239
|
def __init__(self, expression: str) -> None:
|
|
@@ -219,50 +269,89 @@ class FileSizeConfig(yaml.YAMLObject):
|
|
|
219
269
|
|
|
220
270
|
@property
|
|
221
271
|
def bytes(self) -> int:
|
|
272
|
+
"""
|
|
273
|
+
File size in bytes.
|
|
274
|
+
"""
|
|
222
275
|
return self._bytes
|
|
223
276
|
|
|
224
277
|
@property
|
|
225
278
|
def kilobytes(self) -> float:
|
|
279
|
+
"""
|
|
280
|
+
File size in kilobytes.
|
|
281
|
+
"""
|
|
226
282
|
return self._bytes / 1000
|
|
227
283
|
|
|
228
284
|
@property
|
|
229
285
|
def megabytes(self) -> float:
|
|
286
|
+
"""
|
|
287
|
+
File size in megabytes.
|
|
288
|
+
"""
|
|
230
289
|
return self._bytes / 1_000_000
|
|
231
290
|
|
|
232
291
|
@property
|
|
233
292
|
def gigabytes(self) -> float:
|
|
293
|
+
"""
|
|
294
|
+
File size in gigabytes.
|
|
295
|
+
"""
|
|
234
296
|
return self._bytes / 1_000_000_000
|
|
235
297
|
|
|
236
298
|
@property
|
|
237
299
|
def terabytes(self) -> float:
|
|
300
|
+
"""
|
|
301
|
+
File size in terabytes.
|
|
302
|
+
"""
|
|
238
303
|
return self._bytes / 1_000_000_000_000
|
|
239
304
|
|
|
240
305
|
@property
|
|
241
306
|
def kibibytes(self) -> float:
|
|
307
|
+
"""
|
|
308
|
+
File size in kibibytes (1024 bytes).
|
|
309
|
+
"""
|
|
242
310
|
return self._bytes / 1024
|
|
243
311
|
|
|
244
312
|
@property
|
|
245
313
|
def mebibytes(self) -> float:
|
|
314
|
+
"""
|
|
315
|
+
File size in mebibytes (1024 kibibytes).
|
|
316
|
+
"""
|
|
246
317
|
return self._bytes / 1_048_576
|
|
247
318
|
|
|
248
319
|
@property
|
|
249
320
|
def gibibytes(self) -> float:
|
|
321
|
+
"""
|
|
322
|
+
File size in gibibytes (1024 mebibytes).
|
|
323
|
+
"""
|
|
250
324
|
return self._bytes / 1_073_741_824
|
|
251
325
|
|
|
252
326
|
@property
|
|
253
327
|
def tebibytes(self) -> float:
|
|
328
|
+
"""
|
|
329
|
+
File size in tebibytes (1024 gibibytes).
|
|
330
|
+
"""
|
|
254
331
|
return self._bytes / 1_099_511_627_776
|
|
255
332
|
|
|
256
333
|
def __int__(self) -> int:
|
|
334
|
+
"""
|
|
335
|
+
Returns the file size as bytes.
|
|
336
|
+
"""
|
|
257
337
|
return int(self._bytes)
|
|
258
338
|
|
|
259
339
|
def __float__(self) -> float:
|
|
340
|
+
"""
|
|
341
|
+
Returns the file size as bytes.
|
|
342
|
+
"""
|
|
260
343
|
return float(self._bytes)
|
|
261
344
|
|
|
262
345
|
def __str__(self) -> str:
|
|
346
|
+
"""
|
|
347
|
+
Returns the file size as a human readable string.
|
|
348
|
+
"""
|
|
263
349
|
return self._expression
|
|
264
350
|
|
|
265
351
|
def __repr__(self) -> str:
|
|
352
|
+
"""
|
|
353
|
+
Returns the file size as a human readable string.
|
|
354
|
+
"""
|
|
266
355
|
return self._expression
|
|
267
356
|
|
|
268
357
|
|
|
@@ -281,7 +370,7 @@ def _validate_https_url(value: str, name: str) -> None:
|
|
|
281
370
|
@dataclass
|
|
282
371
|
class CogniteConfig:
|
|
283
372
|
"""
|
|
284
|
-
Configuration parameters for CDF connection, such as project name, host address and authentication
|
|
373
|
+
Configuration parameters for CDF connection, such as project name, host address and authentication.
|
|
285
374
|
"""
|
|
286
375
|
|
|
287
376
|
project: str
|
|
@@ -290,7 +379,7 @@ class CogniteConfig:
|
|
|
290
379
|
data_set_id: int | None = None
|
|
291
380
|
data_set_external_id: str | None = None
|
|
292
381
|
extraction_pipeline: EitherIdConfig | None = None
|
|
293
|
-
timeout: TimeIntervalConfig = TimeIntervalConfig("30s")
|
|
382
|
+
timeout: TimeIntervalConfig = field(default_factory=lambda: TimeIntervalConfig("30s"))
|
|
294
383
|
connection: ConnectionConfig = field(default_factory=ConnectionConfig)
|
|
295
384
|
security_categories: list[int] | None = None
|
|
296
385
|
external_id_prefix: str = ""
|
|
@@ -302,6 +391,20 @@ class CogniteConfig:
|
|
|
302
391
|
token_custom_args: dict[str, str] | None = None,
|
|
303
392
|
use_experimental_sdk: bool = False,
|
|
304
393
|
) -> CogniteClient:
|
|
394
|
+
"""
|
|
395
|
+
Creates a CogniteClient based on the configuration.
|
|
396
|
+
|
|
397
|
+
Args:
|
|
398
|
+
client_name: Name of the client, set as the x-cdp-app header in the requests.
|
|
399
|
+
token_custom_args: Additional arguments to pass to the token request, such as resource or audience.
|
|
400
|
+
use_experimental_sdk: If True, use the experimental SDK instead of the stable one.
|
|
401
|
+
|
|
402
|
+
Returns:
|
|
403
|
+
A CogniteClient instance configured with the provided parameters.
|
|
404
|
+
|
|
405
|
+
Raises:
|
|
406
|
+
InvalidConfigError: If the configuration is invalid, such as missing project name or invalid authority URL.
|
|
407
|
+
"""
|
|
305
408
|
from cognite.client.config import global_config
|
|
306
409
|
|
|
307
410
|
global_config.disable_pypi_version_check = True
|
|
@@ -390,6 +493,15 @@ class CogniteConfig:
|
|
|
390
493
|
return CogniteClient(client_config)
|
|
391
494
|
|
|
392
495
|
def get_data_set(self, cdf_client: CogniteClient) -> DataSet | None:
|
|
496
|
+
"""
|
|
497
|
+
Retrieves the DataSet object based on the configuration.
|
|
498
|
+
|
|
499
|
+
Args:
|
|
500
|
+
cdf_client: An instance of CogniteClient to use for retrieving the DataSet.
|
|
501
|
+
|
|
502
|
+
Returns:
|
|
503
|
+
DataSet object if data_set, data_set_id, or data_set_external_id is provided; otherwise None.
|
|
504
|
+
"""
|
|
393
505
|
if self.data_set_external_id:
|
|
394
506
|
logging.getLogger(__name__).warning(
|
|
395
507
|
"Using data-set-external-id is deprecated, please use data-set/external-id instead"
|
|
@@ -409,6 +521,18 @@ class CogniteConfig:
|
|
|
409
521
|
)
|
|
410
522
|
|
|
411
523
|
def get_extraction_pipeline(self, cdf_client: CogniteClient) -> ExtractionPipeline | None:
|
|
524
|
+
"""
|
|
525
|
+
Retrieves the ExtractionPipeline object based on the configuration.
|
|
526
|
+
|
|
527
|
+
Args:
|
|
528
|
+
cdf_client: An instance of CogniteClient to use for retrieving the ExtractionPipeline.
|
|
529
|
+
|
|
530
|
+
Returns:
|
|
531
|
+
ExtractionPipeline object if extraction_pipeline is provided, otherwise None.
|
|
532
|
+
|
|
533
|
+
Raises:
|
|
534
|
+
ValueError: If the extraction pipeline with the specified ID is not found.
|
|
535
|
+
"""
|
|
412
536
|
if not self.extraction_pipeline:
|
|
413
537
|
return None
|
|
414
538
|
|
|
@@ -437,7 +561,7 @@ class _FileLoggingConfig:
|
|
|
437
561
|
@dataclass
|
|
438
562
|
class LoggingConfig:
|
|
439
563
|
"""
|
|
440
|
-
Logging settings, such as log levels and path to log file
|
|
564
|
+
Logging settings, such as log levels and path to log file.
|
|
441
565
|
"""
|
|
442
566
|
|
|
443
567
|
console: _ConsoleLoggingConfig | None
|
|
@@ -449,7 +573,7 @@ class LoggingConfig:
|
|
|
449
573
|
|
|
450
574
|
def setup_logging(self, suppress_console: bool = False) -> None:
|
|
451
575
|
"""
|
|
452
|
-
Sets up the default logger in the logging package to be configured as defined in this config object
|
|
576
|
+
Sets up the default logger in the logging package to be configured as defined in this config object.
|
|
453
577
|
|
|
454
578
|
Args:
|
|
455
579
|
suppress_console: Don't log to console regardless of config. Useful when running an extractor as a Windows
|
|
@@ -510,7 +634,7 @@ class _PushGatewayConfig:
|
|
|
510
634
|
password: str | None
|
|
511
635
|
|
|
512
636
|
clear_after: TimeIntervalConfig | None
|
|
513
|
-
push_interval: TimeIntervalConfig = TimeIntervalConfig("30s")
|
|
637
|
+
push_interval: TimeIntervalConfig = field(default_factory=lambda: TimeIntervalConfig("30s"))
|
|
514
638
|
|
|
515
639
|
|
|
516
640
|
@dataclass
|
|
@@ -526,14 +650,15 @@ class _CogniteMetricsConfig:
|
|
|
526
650
|
asset_external_id: str | None
|
|
527
651
|
data_set: EitherIdConfig | None = None
|
|
528
652
|
|
|
529
|
-
push_interval: TimeIntervalConfig = TimeIntervalConfig("30s")
|
|
653
|
+
push_interval: TimeIntervalConfig = field(default_factory=lambda: TimeIntervalConfig("30s"))
|
|
530
654
|
|
|
531
655
|
|
|
532
656
|
@dataclass
|
|
533
657
|
class MetricsConfig:
|
|
534
658
|
"""
|
|
535
|
-
Destination(s) for metrics
|
|
536
|
-
|
|
659
|
+
Destination(s) for metrics.
|
|
660
|
+
|
|
661
|
+
Including options for one or several Prometheus push gateways, and pushing as CDF Time Series.
|
|
537
662
|
"""
|
|
538
663
|
|
|
539
664
|
push_gateways: list[_PushGatewayConfig] | None
|
|
@@ -541,6 +666,13 @@ class MetricsConfig:
|
|
|
541
666
|
server: _PromServerConfig | None
|
|
542
667
|
|
|
543
668
|
def start_pushers(self, cdf_client: CogniteClient, cancellation_token: CancellationToken | None = None) -> None:
|
|
669
|
+
"""
|
|
670
|
+
Starts the configured metrics pushers.
|
|
671
|
+
|
|
672
|
+
Args:
|
|
673
|
+
cdf_client: An instance of CogniteClient to use for pushing metrics to CDF.
|
|
674
|
+
cancellation_token: Optional cancellation token to stop the pushers gracefully.
|
|
675
|
+
"""
|
|
544
676
|
self._pushers: list[AbstractMetricsPusher] = []
|
|
545
677
|
self._clear_on_stop: dict[PrometheusPusher, int] = {}
|
|
546
678
|
|
|
@@ -589,6 +721,11 @@ class MetricsConfig:
|
|
|
589
721
|
start_http_server(self.server.port, self.server.host, registry=REGISTRY)
|
|
590
722
|
|
|
591
723
|
def stop_pushers(self) -> None:
|
|
724
|
+
"""
|
|
725
|
+
DEPRECATED. Use cancellation_token to stop pushers instead.
|
|
726
|
+
|
|
727
|
+
Manually stop pushers and clear gateways if configured.
|
|
728
|
+
"""
|
|
592
729
|
pushers = self.__dict__.get("_pushers") or []
|
|
593
730
|
|
|
594
731
|
for pusher in pushers:
|
|
@@ -599,11 +736,15 @@ class MetricsConfig:
|
|
|
599
736
|
_logger.debug("Waiting %d seconds before clearing gateways", wait_time)
|
|
600
737
|
|
|
601
738
|
sleep(wait_time)
|
|
602
|
-
for pusher in self._clear_on_stop
|
|
739
|
+
for pusher in self._clear_on_stop:
|
|
603
740
|
pusher.clear_gateway()
|
|
604
741
|
|
|
605
742
|
|
|
606
743
|
class ConfigType(Enum):
|
|
744
|
+
"""
|
|
745
|
+
Type of configuration, either local or remote.
|
|
746
|
+
"""
|
|
747
|
+
|
|
607
748
|
LOCAL = "local"
|
|
608
749
|
REMOTE = "remote"
|
|
609
750
|
|
|
@@ -619,7 +760,7 @@ class _BaseConfig:
|
|
|
619
760
|
@dataclass
|
|
620
761
|
class BaseConfig(_BaseConfig):
|
|
621
762
|
"""
|
|
622
|
-
Basis for an extractor config, containing config version, ``CogniteConfig`` and ``LoggingConfig
|
|
763
|
+
Basis for an extractor config, containing config version, ``CogniteConfig`` and ``LoggingConfig``.
|
|
623
764
|
"""
|
|
624
765
|
|
|
625
766
|
version: str | int | None
|
|
@@ -629,7 +770,7 @@ class BaseConfig(_BaseConfig):
|
|
|
629
770
|
@dataclass
|
|
630
771
|
class RawDestinationConfig:
|
|
631
772
|
"""
|
|
632
|
-
Configuration parameters for using Raw
|
|
773
|
+
Configuration parameters for using Raw.
|
|
633
774
|
"""
|
|
634
775
|
|
|
635
776
|
database: str
|
|
@@ -639,26 +780,26 @@ class RawDestinationConfig:
|
|
|
639
780
|
@dataclass
|
|
640
781
|
class RawStateStoreConfig(RawDestinationConfig):
|
|
641
782
|
"""
|
|
642
|
-
Configuration of a state store based on CDF RAW
|
|
783
|
+
Configuration of a state store based on CDF RAW.
|
|
643
784
|
"""
|
|
644
785
|
|
|
645
|
-
upload_interval: TimeIntervalConfig = TimeIntervalConfig("30s")
|
|
786
|
+
upload_interval: TimeIntervalConfig = field(default_factory=lambda: TimeIntervalConfig("30s"))
|
|
646
787
|
|
|
647
788
|
|
|
648
789
|
@dataclass
|
|
649
790
|
class LocalStateStoreConfig:
|
|
650
791
|
"""
|
|
651
|
-
Configuration of a state store using a local JSON file
|
|
792
|
+
Configuration of a state store using a local JSON file.
|
|
652
793
|
"""
|
|
653
794
|
|
|
654
795
|
path: Path
|
|
655
|
-
save_interval: TimeIntervalConfig = TimeIntervalConfig("30s")
|
|
796
|
+
save_interval: TimeIntervalConfig = field(default_factory=lambda: TimeIntervalConfig("30s"))
|
|
656
797
|
|
|
657
798
|
|
|
658
799
|
@dataclass
|
|
659
800
|
class StateStoreConfig:
|
|
660
801
|
"""
|
|
661
|
-
Configuration of the State Store, containing ``LocalStateStoreConfig`` or ``RawStateStoreConfig
|
|
802
|
+
Configuration of the State Store, containing ``LocalStateStoreConfig`` or ``RawStateStoreConfig``.
|
|
662
803
|
"""
|
|
663
804
|
|
|
664
805
|
raw: RawStateStoreConfig | None = None
|
|
@@ -677,6 +818,7 @@ class StateStoreConfig:
|
|
|
677
818
|
cdf_client: CogniteClient object to use in case of a RAW state store (ignored otherwise)
|
|
678
819
|
default_to_local: If true, return a LocalStateStore if no state store is configured. Otherwise return a
|
|
679
820
|
NoStateStore
|
|
821
|
+
cancellation_token: Cancellation token to pass to created state stores
|
|
680
822
|
|
|
681
823
|
Returns:
|
|
682
824
|
An (uninitialized) state store
|
|
@@ -713,12 +855,22 @@ class StateStoreConfig:
|
|
|
713
855
|
|
|
714
856
|
|
|
715
857
|
class RegExpFlag(Enum):
|
|
858
|
+
"""
|
|
859
|
+
Flags for regular expressions.
|
|
860
|
+
"""
|
|
861
|
+
|
|
716
862
|
IGNORECASE = "ignore-case"
|
|
717
863
|
IC = "i"
|
|
718
864
|
ASCII = "ascii-only"
|
|
719
865
|
A = "a"
|
|
720
866
|
|
|
721
867
|
def get_regex_flag(self) -> int:
|
|
868
|
+
"""
|
|
869
|
+
Returns the corresponding regex flag for the enum value.
|
|
870
|
+
|
|
871
|
+
Returns:
|
|
872
|
+
The regex flag corresponding to the enum value.
|
|
873
|
+
"""
|
|
722
874
|
if self in (RegExpFlag.IGNORECASE, RegExpFlag.IC):
|
|
723
875
|
return re.IGNORECASE
|
|
724
876
|
elif self.value in (RegExpFlag.ASCII, RegExpFlag.A):
|
|
@@ -729,7 +881,7 @@ class RegExpFlag(Enum):
|
|
|
729
881
|
@dataclass
|
|
730
882
|
class IgnorePattern:
|
|
731
883
|
"""
|
|
732
|
-
Configuration for regexp for ignore pattern
|
|
884
|
+
Configuration for regexp for ignore pattern.
|
|
733
885
|
"""
|
|
734
886
|
|
|
735
887
|
pattern: str
|
|
@@ -749,6 +901,12 @@ class IgnorePattern:
|
|
|
749
901
|
return re.compile(self.pattern, flag)
|
|
750
902
|
|
|
751
903
|
def __post_init__(self) -> None:
|
|
904
|
+
"""
|
|
905
|
+
Validate the configuration after initialization.
|
|
906
|
+
|
|
907
|
+
Raises:
|
|
908
|
+
ValueError: If both 'options' and 'flags' are specified, or if neither is specified.
|
|
909
|
+
"""
|
|
752
910
|
if self.options is not None and self.flags is not None:
|
|
753
911
|
raise ValueError("Only one of either 'options' or 'flags' can be specified.")
|
|
754
912
|
if self.options is None and self.flags is None:
|
|
@@ -762,19 +920,27 @@ class IgnorePattern:
|
|
|
762
920
|
|
|
763
921
|
class CastableInt(int):
|
|
764
922
|
"""
|
|
765
|
-
Represents an integer in a config schema.
|
|
766
|
-
|
|
923
|
+
Represents an integer in a config schema.
|
|
924
|
+
|
|
925
|
+
The difference from regular int is that the value if this type can be either a string or an integer in the yaml
|
|
926
|
+
file.
|
|
767
927
|
"""
|
|
768
928
|
|
|
769
929
|
def __new__(cls, value: Any) -> "CastableInt":
|
|
770
930
|
"""
|
|
771
|
-
Returns value as is if it's int.
|
|
772
|
-
Raises ValueError if conversion is unsuccessful or value is of not supported type.
|
|
931
|
+
Returns value as is if it's int.
|
|
773
932
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
933
|
+
If it's str or bytes try to convert to int.
|
|
934
|
+
|
|
935
|
+
Type check is required to avoid unexpected behavior, such as implicitly casting booleans, floats and other types
|
|
936
|
+
supported by standard int.
|
|
777
937
|
|
|
938
|
+
Args:
|
|
939
|
+
value: The value to be casted to int.
|
|
940
|
+
|
|
941
|
+
Raises:
|
|
942
|
+
ValueError: If the value can not be converted to an int.
|
|
943
|
+
"""
|
|
778
944
|
if not isinstance(value, int | str | bytes):
|
|
779
945
|
raise ValueError(f"CastableInt cannot be created form value {value!r} of type {type(value)!r}.")
|
|
780
946
|
|
|
@@ -783,14 +949,21 @@ class CastableInt(int):
|
|
|
783
949
|
|
|
784
950
|
class PortNumber(CastableInt):
|
|
785
951
|
"""
|
|
786
|
-
|
|
787
|
-
|
|
952
|
+
Represents a port number in a config schema.
|
|
953
|
+
|
|
954
|
+
It represents a valid port number (0 to 65535) and allows the value to be of either str or int type. If the value is
|
|
955
|
+
not a valid port number raises a ValueError at instantiation.
|
|
788
956
|
"""
|
|
789
957
|
|
|
790
958
|
def __new__(cls, value: Any) -> "PortNumber":
|
|
791
959
|
"""
|
|
792
|
-
Try to
|
|
793
|
-
|
|
960
|
+
Try to cast the value to an integer and validate it as a port number.
|
|
961
|
+
|
|
962
|
+
Args:
|
|
963
|
+
value: The value to be casted to a port number.
|
|
964
|
+
|
|
965
|
+
Raises:
|
|
966
|
+
ValueError: If the value is not a valid port number (not an int or out of range).
|
|
794
967
|
"""
|
|
795
968
|
value = super().__new__(cls, value)
|
|
796
969
|
|