esd-services-api-client 2.6.2a155.dev2__tar.gz → 2.6.2a158.dev4__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 (59) hide show
  1. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/PKG-INFO +2 -2
  2. esd_services_api_client-2.6.2a158.dev4/esd_services_api_client/_version.py +1 -0
  3. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/README.md +0 -5
  4. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/core/app_core.py +17 -78
  5. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/core/app_dependencies.py +25 -0
  6. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/core/serializers.py +5 -5
  7. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/input/payload_reader.py +1 -1
  8. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/telemetry/user_telemetry_recorder.py +7 -5
  9. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/pyproject.toml +2 -2
  10. esd_services_api_client-2.6.2a155.dev2/esd_services_api_client/_version.py +0 -1
  11. esd_services_api_client-2.6.2a155.dev2/esd_services_api_client/nexus/abstractions/metrics_provider_factory.py +0 -70
  12. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/LICENSE +0 -0
  13. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/README.md +0 -0
  14. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/__init__.py +0 -0
  15. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/beast/__init__.py +0 -0
  16. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/beast/v3/__init__.py +0 -0
  17. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/beast/v3/_connector.py +0 -0
  18. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/beast/v3/_models.py +0 -0
  19. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/boxer/README.md +0 -0
  20. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/boxer/__init__.py +0 -0
  21. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/boxer/_auth.py +0 -0
  22. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/boxer/_base.py +0 -0
  23. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/boxer/_connector.py +0 -0
  24. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/boxer/_models.py +0 -0
  25. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/common/__init__.py +0 -0
  26. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/crystal/__init__.py +0 -0
  27. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/crystal/_api_versions.py +0 -0
  28. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/crystal/_connector.py +0 -0
  29. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/crystal/_models.py +0 -0
  30. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/__init__.py +0 -0
  31. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/abstractions/__init__.py +0 -0
  32. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/abstractions/algrorithm_cache.py +0 -0
  33. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/abstractions/input_object.py +0 -0
  34. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/abstractions/logger_factory.py +0 -0
  35. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/abstractions/nexus_object.py +0 -0
  36. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/abstractions/socket_provider.py +0 -0
  37. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/algorithms/__init__.py +0 -0
  38. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/algorithms/_baseline_algorithm.py +0 -0
  39. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/algorithms/_remote_algorithm.py +0 -0
  40. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/algorithms/distributed.py +0 -0
  41. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/algorithms/forked_algorithm.py +0 -0
  42. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/algorithms/minimalistic.py +0 -0
  43. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/algorithms/recursive.py +0 -0
  44. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/configurations/__init__.py +0 -0
  45. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/configurations/algorithm_configuration.py +0 -0
  46. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/core/__init__.py +0 -0
  47. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/exceptions/__init__.py +0 -0
  48. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/exceptions/_nexus_error.py +0 -0
  49. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/exceptions/cache_errors.py +0 -0
  50. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/exceptions/input_reader_error.py +0 -0
  51. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/exceptions/startup_error.py +0 -0
  52. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/input/__init__.py +0 -0
  53. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/input/input_processor.py +0 -0
  54. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/input/input_reader.py +0 -0
  55. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/modules/__init__.py +0 -0
  56. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/modules/astra_client_module.py +0 -0
  57. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/modules/mlflow_module.py +0 -0
  58. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/telemetry/__init__.py +0 -0
  59. {esd_services_api_client-2.6.2a155.dev2 → esd_services_api_client-2.6.2a158.dev4}/esd_services_api_client/nexus/telemetry/recorder.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: esd-services-api-client
3
- Version: 2.6.2a155.dev2
3
+ Version: 2.6.2a158.dev4
4
4
  Summary: Python clients for ESD services
5
5
  License: Apache 2.0
6
6
  Author: ECCO Sneaks & Data
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.11
14
14
  Provides-Extra: azure
15
15
  Provides-Extra: nexus
16
- Requires-Dist: adapta[datadog,storage] (>=3.3,<4.0)
16
+ Requires-Dist: adapta[datadog,storage] (>=3.4,<3.5)
17
17
  Requires-Dist: azure-identity (>=1.7,<1.8) ; extra == "azure"
18
18
  Requires-Dist: dataclasses-json (>=0.6.0,<0.7.0)
19
19
  Requires-Dist: httpx (>=0.27.0,<0.28.0) ; extra == "nexus"
@@ -0,0 +1 @@
1
+ __version__ = 'v2.6.2a158.dev4'
@@ -302,10 +302,6 @@ async def main():
302
302
  "(value of y:{y})": {"y": payload.y},
303
303
  "(request_id:{request_id})": {"request_id": run_args.request_id}
304
304
  }
305
- def tag_metrics(payload: MyAlgorithmPayload2, run_args: CrystalEntrypointArguments) -> dict[str, str]:
306
- return {
307
- "country": payload.y,
308
- }
309
305
  with ThreadingHTTPServer(("localhost", 9876), MockRequestHandler) as server:
310
306
  server_thread = threading.Thread(target=server.serve_forever)
311
307
  server_thread.daemon = True
@@ -321,7 +317,6 @@ async def main():
321
317
  .inject_configuration(MyAlgorithmConfiguration)
322
318
  .inject_payload(MyAlgorithmPayload, MyAlgorithmPayload2)
323
319
  .with_log_enricher(tags_from_payload, enrich_from_payload)
324
- .with_metric_tagger(tag_metrics)
325
320
  )
326
321
 
327
322
  await nexus.activate()
@@ -45,9 +45,6 @@ from esd_services_api_client.nexus.abstractions.logger_factory import (
45
45
  LoggerFactory,
46
46
  BootstrapLoggerFactory,
47
47
  )
48
- from esd_services_api_client.nexus.abstractions.metrics_provider_factory import (
49
- MetricsProviderFactory,
50
- )
51
48
  from esd_services_api_client.nexus.abstractions.nexus_object import AlgorithmResult
52
49
  from esd_services_api_client.nexus.algorithms import (
53
50
  BaselineAlgorithm,
@@ -141,14 +138,6 @@ class Nexus:
141
138
  ] | None = None
142
139
  self._log_enrichment_delimiter: str = ", "
143
140
 
144
- self._metric_tagger: Callable[
145
- [
146
- AlgorithmPayload,
147
- CrystalEntrypointArguments,
148
- ],
149
- dict[str, str],
150
- ] | None = None
151
-
152
141
  attach_signal_handlers()
153
142
 
154
143
  @property
@@ -236,23 +225,6 @@ class Nexus:
236
225
  self._log_enrichment_delimiter = delimiter
237
226
  return self
238
227
 
239
- def with_metric_tagger(
240
- self,
241
- tagger: Callable[
242
- [
243
- AlgorithmPayload,
244
- CrystalEntrypointArguments,
245
- ],
246
- dict[str, str],
247
- ]
248
- | None = None,
249
- ) -> "Nexus":
250
- """
251
- Adds a metric `enricher` to be used with injected metrics provider to assign additional tags to emitted metrics.
252
- """
253
- self._metric_tagger = tagger
254
- return self
255
-
256
228
  def with_module(self, module: Type[Module]) -> "Nexus":
257
229
  """
258
230
  Adds a (custom) DI module into the DI container.
@@ -345,59 +317,28 @@ class Nexus:
345
317
 
346
318
  bootstrap_logger.start()
347
319
 
348
- try:
349
- logger_fixed_template = {}
350
- logger_tags = {}
351
- metric_tags = {}
352
-
353
- for payload_type in self._payload_types:
320
+ for payload_type in self._payload_types:
321
+ try:
354
322
  payload = await self._get_payload(payload_type=payload_type)
355
323
  self._injector.binder.bind(
356
324
  payload.__class__, to=payload, scope=singleton
357
325
  )
358
- logger_fixed_template |= (
359
- self._log_enricher(payload, self._run_args)
360
- if self._log_enricher
361
- else {}
326
+ logger_factory = LoggerFactory(
327
+ fixed_template=None
328
+ if not self._log_enricher
329
+ else self._log_enricher(payload, self._run_args),
330
+ fixed_template_delimiter=self._log_enrichment_delimiter,
331
+ global_tags=self._log_tagger(payload, self._run_args),
362
332
  )
363
- logger_tags |= (
364
- self._log_tagger(payload, self._run_args)
365
- if self._log_tagger
366
- else {}
367
- )
368
- metric_tags |= (
369
- self._metric_tagger(payload, self._run_args)
370
- if self._metric_tagger
371
- else {}
333
+ # bind app-level LoggerFactory now
334
+ self._injector.binder.bind(
335
+ logger_factory.__class__,
336
+ to=logger_factory,
337
+ scope=singleton,
372
338
  )
373
-
374
- logger_factory = LoggerFactory(
375
- fixed_template=logger_fixed_template,
376
- fixed_template_delimiter=self._log_enrichment_delimiter,
377
- global_tags=logger_tags,
378
- )
379
- # bind app-level LoggerFactory now
380
- self._injector.binder.bind(
381
- logger_factory.__class__,
382
- to=logger_factory,
383
- scope=singleton,
384
- )
385
-
386
- # bind app-level MetricsProvider now
387
- metrics_provider = MetricsProviderFactory(
388
- global_tags=metric_tags,
389
- ).create_provider()
390
- self._injector.binder.bind(
391
- metrics_provider.__class__,
392
- to=metrics_provider,
393
- scope=singleton,
394
- )
395
- except BaseException as ex: # pylint: disable=broad-except
396
- bootstrap_logger.error("Error reading algorithm payload", ex)
397
-
398
- # ensure we flush bootstrap logger before we exit
399
- bootstrap_logger.stop()
400
- sys.exit(1)
339
+ except BaseException as ex: # pylint: disable=broad-except
340
+ bootstrap_logger.error("Error reading algorithm payload", ex)
341
+ sys.exit(1)
401
342
 
402
343
  bootstrap_logger.stop()
403
344
 
@@ -459,9 +400,7 @@ class Nexus:
459
400
  for on_complete_task_class in self._on_complete_tasks
460
401
  ]
461
402
  if len(on_complete_tasks) > 0:
462
- done, pending = await asyncio.wait(
463
- on_complete_tasks, return_when=asyncio.FIRST_EXCEPTION
464
- )
403
+ done, pending = await asyncio.wait(on_complete_tasks)
465
404
  if len(pending) > 0:
466
405
  root_logger.warning(
467
406
  "Some post-processing operations did not complete or failed. Please review application logs for more information"
@@ -17,11 +17,13 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
+ import json
20
21
  import os
21
22
  import re
22
23
  from pydoc import locate
23
24
  from typing import final, Type, Any
24
25
 
26
+ from adapta.metrics import MetricsProvider
25
27
  from adapta.storage.blob.base import StorageClient
26
28
  from adapta.storage.query_enabled_store import QueryEnabledStore
27
29
  from injector import Module, singleton, provider
@@ -49,6 +51,28 @@ from esd_services_api_client.nexus.core.serializers import (
49
51
  )
50
52
 
51
53
 
54
+ @final
55
+ class MetricsModule(Module):
56
+ """
57
+ Metrics provider module.
58
+ """
59
+
60
+ @singleton
61
+ @provider
62
+ def provide(self) -> MetricsProvider:
63
+ """
64
+ DI factory method.
65
+ """
66
+ metrics_class: Type[MetricsProvider] = locate(
67
+ os.getenv(
68
+ "NEXUS__METRIC_PROVIDER_CLASS",
69
+ "adapta.metrics.providers.datadog_provider.DatadogMetricsProvider",
70
+ )
71
+ )
72
+ metrics_settings = json.loads(os.getenv("NEXUS__METRIC_PROVIDER_CONFIGURATION"))
73
+ return metrics_class(**metrics_settings)
74
+
75
+
52
76
  @final
53
77
  class BootstrapLoggerFactoryModule(Module):
54
78
  """
@@ -213,6 +237,7 @@ class ServiceConfigurator:
213
237
  def __init__(self):
214
238
  self._injection_binds = [
215
239
  BootstrapLoggerFactoryModule(),
240
+ MetricsModule(),
216
241
  CrystalReceiverClientModule(),
217
242
  QueryEnabledStoreModule(),
218
243
  StorageClientModule(),
@@ -2,10 +2,10 @@
2
2
  from typing import final, Any, TypeVar, Type
3
3
 
4
4
  import pandas
5
- from adapta.storage.models.format import (
6
- DataFrameParquetSerializationFormat,
5
+ from adapta.storage.models.format import SerializationFormat
6
+ from adapta.storage.models.formatters import (
7
+ PandasDataFrameParquetSerializationFormat,
7
8
  DictJsonSerializationFormat,
8
- SerializationFormat,
9
9
  )
10
10
 
11
11
  T = TypeVar("T") # pylint: disable=C0103
@@ -59,7 +59,7 @@ class TelemetrySerializer(Serializer):
59
59
  def __init__(self):
60
60
  super().__init__(
61
61
  default_serialization_formats={
62
- pandas.DataFrame: DataFrameParquetSerializationFormat,
62
+ pandas.DataFrame: PandasDataFrameParquetSerializationFormat,
63
63
  dict: DictJsonSerializationFormat,
64
64
  }
65
65
  )
@@ -72,7 +72,7 @@ class ResultSerializer(Serializer):
72
72
  def __init__(self):
73
73
  super().__init__(
74
74
  default_serialization_formats={
75
- pandas.DataFrame: DataFrameParquetSerializationFormat,
75
+ pandas.DataFrame: PandasDataFrameParquetSerializationFormat,
76
76
  dict: DictJsonSerializationFormat,
77
77
  }
78
78
  )
@@ -21,7 +21,7 @@ from dataclasses import dataclass
21
21
 
22
22
  from typing import final, Optional, Type
23
23
 
24
- from adapta.storage.models.format import DictJsonSerializationFormat
24
+ from adapta.storage.models.formatters import DictJsonSerializationFormat
25
25
  from adapta.utils import session_with_retries
26
26
 
27
27
  from dataclasses_json import DataClassJsonMixin
@@ -43,7 +43,9 @@ class UserTelemetry:
43
43
  """
44
44
 
45
45
  def __init__(
46
- self, telemetry: DataFrame, *telemetry_path_segments: UserTelemetryPathSegment
46
+ self,
47
+ telemetry: DataFrame,
48
+ *telemetry_path_segments: UserTelemetryPathSegment,
47
49
  ):
48
50
  self._telemetry = telemetry
49
51
  self._telemetry_path_segments = telemetry_path_segments
@@ -143,6 +145,8 @@ class UserTelemetryRecorder(Generic[TPayload, TResult], ABC):
143
145
  )
144
146
  return
145
147
 
148
+ serializer = self._serializer.get_serialization_format(telemetry.telemetry)
149
+
146
150
  self._storage_client.save_data_as_blob(
147
151
  data=telemetry.telemetry,
148
152
  blob_path=DataSocket(
@@ -152,13 +156,11 @@ class UserTelemetryRecorder(Generic[TPayload, TResult], ABC):
152
156
  "telemetry_group=user",
153
157
  f"recorder_class={self.__class__.alias()}",
154
158
  telemetry.telemetry_path, # path join eliminates empty segments
155
- run_id,
159
+ serializer().get_output_name(output_name=run_id),
156
160
  ),
157
161
  data_format="null",
158
162
  ).parse_data_path(),
159
- serialization_format=self._serializer.get_serialization_format(
160
- telemetry.telemetry
161
- ),
163
+ serialization_format=serializer,
162
164
  overwrite=True,
163
165
  )
164
166
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "esd-services-api-client"
3
- version = "v2.6.2a155.dev2"
3
+ version = "v2.6.2a158.dev4"
4
4
  description = "Python clients for ESD services"
5
5
  authors = ["ECCO Sneaks & Data <esdsupport@ecco.com>"]
6
6
  maintainers = ['GZU <gzu@ecco.com>', 'JRB <ext-jrb@ecco.com>', 'VISA <visa@ecco.com>']
@@ -10,7 +10,7 @@ repository = 'https://github.com/SneaksAndData/esd-services-api-client'
10
10
 
11
11
  [tool.poetry.dependencies]
12
12
  python = ">=3.11,<3.12"
13
- adapta = { version = "^3.3", extras = ["storage", "datadog"] }
13
+ adapta = { version = "~3.4", extras = ["storage", "datadog"] }
14
14
  dataclasses-json = "^0.6.0"
15
15
  pycryptodome = "~3.15"
16
16
  azure-identity = { version = "~1.7", optional = true }
@@ -1 +0,0 @@
1
- __version__ = 'v2.6.2a155.dev2'
@@ -1,70 +0,0 @@
1
- """
2
- Metrics provider factory.
3
- """
4
-
5
- # Copyright (c) 2023-2024. ECCO Sneaks & Data
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
- #
19
-
20
- import json
21
- import os
22
- from pydoc import locate
23
- from typing import final
24
-
25
- from adapta.metrics import MetricsProvider
26
- from adapta.metrics.providers.datadog_provider import DatadogMetricsProvider
27
-
28
-
29
- @final
30
- class MetricsProviderFactory:
31
- """
32
- Async logger provisioner.
33
- """
34
-
35
- def __init__(
36
- self,
37
- global_tags: dict[str, str] | None = None,
38
- ):
39
- self._global_tags = global_tags
40
- self._metrics_class: type[MetricsProvider] = locate(
41
- os.getenv(
42
- "NEXUS__METRICS_PROVIDER_CLASS",
43
- "adapta.metrics.providers.datadog_provider.DatadogMetricsProvider",
44
- )
45
- )
46
- self._metrics_settings: dict = json.loads(
47
- os.getenv("NEXUS__METRICS_PROVIDER_CONFIGURATION")
48
- )
49
-
50
- def create_provider(
51
- self,
52
- ) -> MetricsProvider:
53
- """
54
- Creates a metrics provider enriched with additional tags for each metric emitted by this algorithm.
55
- In case of DatadogMetricsProvider, takes care of UDP/UDS specific initialization.
56
- """
57
- self._metrics_settings["fixed_tags"] = (
58
- self._metrics_settings.get("fixed_tags", {}) | self._global_tags
59
- )
60
-
61
- if type(self._metrics_class) is DatadogMetricsProvider:
62
- assert isinstance(self._metrics_class, DatadogMetricsProvider)
63
-
64
- if self._metrics_settings["protocol"] == "udp":
65
- return self._metrics_class.udp(**self._metrics_settings)
66
-
67
- if self._metrics_settings["protocol"] == "uds":
68
- return self._metrics_class.uds(**self._metrics_settings)
69
-
70
- return self._metrics_class(**self._metrics_settings)