esd-services-api-client 2.5.14a148.dev5__py3-none-any.whl → 2.6.1__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.
- esd_services_api_client/__init__.py +1 -1
 - esd_services_api_client/boxer/_connector.py +5 -1
 - esd_services_api_client/nexus/README.md +12 -1
 - esd_services_api_client/nexus/abstractions/logger_factory.py +65 -7
 - esd_services_api_client/nexus/core/app_core.py +86 -10
 - esd_services_api_client/nexus/core/app_dependencies.py +7 -4
 - {esd_services_api_client-2.5.14a148.dev5.dist-info → esd_services_api_client-2.6.1.dist-info}/METADATA +3 -5
 - {esd_services_api_client-2.5.14a148.dev5.dist-info → esd_services_api_client-2.6.1.dist-info}/RECORD +10 -11
 - {esd_services_api_client-2.5.14a148.dev5.dist-info → esd_services_api_client-2.6.1.dist-info}/WHEEL +1 -1
 - esd_services_api_client/_version.py +0 -1
 - {esd_services_api_client-2.5.14a148.dev5.dist-info → esd_services_api_client-2.6.1.dist-info}/LICENSE +0 -0
 
| 
         @@ -20,7 +20,11 @@ import os 
     | 
|
| 
       20 
20 
     | 
    
         
             
            from functools import reduce
         
     | 
| 
       21 
21 
     | 
    
         
             
            from typing import Optional, Iterator, final
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
      
 23 
     | 
    
         
            +
            try:
         
     | 
| 
      
 24 
     | 
    
         
            +
                from adapta.security.clients import AzureClient
         
     | 
| 
      
 25 
     | 
    
         
            +
            except ImportError:
         
     | 
| 
      
 26 
     | 
    
         
            +
                pass
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
       24 
28 
     | 
    
         
             
            from adapta.utils import session_with_retries
         
     | 
| 
       25 
29 
     | 
    
         
             
            from requests import Session, Response
         
     | 
| 
       26 
30 
     | 
    
         | 
| 
         @@ -22,7 +22,7 @@ import socketserver 
     | 
|
| 
       22 
22 
     | 
    
         
             
            import threading
         
     | 
| 
       23 
23 
     | 
    
         
             
            from dataclasses import dataclass
         
     | 
| 
       24 
24 
     | 
    
         
             
            from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
         
     | 
| 
       25 
     | 
    
         
            -
            from typing import  
     | 
| 
      
 25 
     | 
    
         
            +
            from typing import Optional, Any
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
            import pandas
         
     | 
| 
       28 
28 
     | 
    
         
             
            from adapta.metrics import MetricsProvider
         
     | 
| 
         @@ -30,6 +30,7 @@ from adapta.storage.query_enabled_store import QueryEnabledStore 
     | 
|
| 
       30 
30 
     | 
    
         
             
            from dataclasses_json import DataClassJsonMixin
         
     | 
| 
       31 
31 
     | 
    
         
             
            from injector import inject
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
      
 33 
     | 
    
         
            +
            from esd_services_api_client.crystal import CrystalEntrypointArguments
         
     | 
| 
       33 
34 
     | 
    
         
             
            from esd_services_api_client.nexus.abstractions.algrorithm_cache import InputCache
         
     | 
| 
       34 
35 
     | 
    
         
             
            from esd_services_api_client.nexus.abstractions.logger_factory import LoggerFactory
         
     | 
| 
       35 
36 
     | 
    
         
             
            from esd_services_api_client.nexus.abstractions.nexus_object import AlgorithmResult
         
     | 
| 
         @@ -292,6 +293,15 @@ async def main(): 
     | 
|
| 
       292 
293 
     | 
    
         
             
                 Mock HTTP Server
         
     | 
| 
       293 
294 
     | 
    
         
             
                :return:
         
     | 
| 
       294 
295 
     | 
    
         
             
                """
         
     | 
| 
      
 296 
     | 
    
         
            +
                def tags_from_payload(payload: MyAlgorithmPayload, _: CrystalEntrypointArguments) -> dict[str, str]:
         
     | 
| 
      
 297 
     | 
    
         
            +
                    return {
         
     | 
| 
      
 298 
     | 
    
         
            +
                        "test_tag": str(payload.x)
         
     | 
| 
      
 299 
     | 
    
         
            +
                    }
         
     | 
| 
      
 300 
     | 
    
         
            +
                def enrich_from_payload(payload: MyAlgorithmPayload2, run_args: CrystalEntrypointArguments) -> dict[str, dict[str, str]]:
         
     | 
| 
      
 301 
     | 
    
         
            +
                    return {
         
     | 
| 
      
 302 
     | 
    
         
            +
                        "(value of y:{y})": {"y": payload.y},
         
     | 
| 
      
 303 
     | 
    
         
            +
                        "(request_id:{request_id})": {"request_id": run_args.request_id}
         
     | 
| 
      
 304 
     | 
    
         
            +
                    }
         
     | 
| 
       295 
305 
     | 
    
         
             
                with ThreadingHTTPServer(("localhost", 9876), MockRequestHandler) as server:
         
     | 
| 
       296 
306 
     | 
    
         
             
                    server_thread = threading.Thread(target=server.serve_forever)
         
     | 
| 
       297 
307 
     | 
    
         
             
                    server_thread.daemon = True
         
     | 
| 
         @@ -306,6 +316,7 @@ async def main(): 
     | 
|
| 
       306 
316 
     | 
    
         
             
                        .on_complete(ObjectiveAnalytics)
         
     | 
| 
       307 
317 
     | 
    
         
             
                        .inject_configuration(MyAlgorithmConfiguration)
         
     | 
| 
       308 
318 
     | 
    
         
             
                        .inject_payload(MyAlgorithmPayload, MyAlgorithmPayload2)
         
     | 
| 
      
 319 
     | 
    
         
            +
                        .with_log_enricher(tags_from_payload, enrich_from_payload)
         
     | 
| 
       309 
320 
     | 
    
         
             
                    )
         
     | 
| 
       310 
321 
     | 
    
         | 
| 
       311 
322 
     | 
    
         
             
                    await nexus.activate()
         
     | 
| 
         @@ -19,8 +19,9 @@ 
     | 
|
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
            import json
         
     | 
| 
       21 
21 
     | 
    
         
             
            import os
         
     | 
| 
      
 22 
     | 
    
         
            +
            from abc import ABC
         
     | 
| 
       22 
23 
     | 
    
         
             
            from logging import StreamHandler
         
     | 
| 
       23 
     | 
    
         
            -
            from typing import final,  
     | 
| 
      
 24 
     | 
    
         
            +
            from typing import final, TypeVar
         
     | 
| 
       24 
25 
     | 
    
         | 
| 
       25 
26 
     | 
    
         
             
            from adapta.logs import LoggerInterface, create_async_logger
         
     | 
| 
       26 
27 
     | 
    
         
             
            from adapta.logs.handlers.datadog_api_handler import DataDogApiHandler
         
     | 
| 
         @@ -29,13 +30,61 @@ from adapta.logs.models import LogLevel 
     | 
|
| 
       29 
30 
     | 
    
         
             
            TLogger = TypeVar("TLogger")  # pylint: disable=C0103:
         
     | 
| 
       30 
31 
     | 
    
         | 
| 
       31 
32 
     | 
    
         | 
| 
      
 33 
     | 
    
         
            +
            @final
         
     | 
| 
      
 34 
     | 
    
         
            +
            class BootstrapLogger(LoggerInterface, ABC):
         
     | 
| 
      
 35 
     | 
    
         
            +
                """
         
     | 
| 
      
 36 
     | 
    
         
            +
                Dummy class to separate bootstrap logging from core app loggers
         
     | 
| 
      
 37 
     | 
    
         
            +
                """
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            @final
         
     | 
| 
      
 41 
     | 
    
         
            +
            class BootstrapLoggerFactory:
         
     | 
| 
      
 42 
     | 
    
         
            +
                """
         
     | 
| 
      
 43 
     | 
    
         
            +
                Bootstrap logger provisioner.
         
     | 
| 
      
 44 
     | 
    
         
            +
                Bootstrap loggers do not use enriched properties since they are initialized before payload is deserialized.
         
     | 
| 
      
 45 
     | 
    
         
            +
                """
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def __init__(self):
         
     | 
| 
      
 48 
     | 
    
         
            +
                    self._log_handlers = [
         
     | 
| 
      
 49 
     | 
    
         
            +
                        StreamHandler(),
         
     | 
| 
      
 50 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 51 
     | 
    
         
            +
                    if "NEXUS__DATADOG_LOGGER_CONFIGURATION" in os.environ:
         
     | 
| 
      
 52 
     | 
    
         
            +
                        self._log_handlers.append(
         
     | 
| 
      
 53 
     | 
    
         
            +
                            DataDogApiHandler(
         
     | 
| 
      
 54 
     | 
    
         
            +
                                **json.loads(os.getenv("NEXUS__DATADOG_LOGGER_CONFIGURATION"))
         
     | 
| 
      
 55 
     | 
    
         
            +
                            )
         
     | 
| 
      
 56 
     | 
    
         
            +
                        )
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                def create_logger(self, request_id: str, algorithm_name: str) -> LoggerInterface:
         
     | 
| 
      
 59 
     | 
    
         
            +
                    """
         
     | 
| 
      
 60 
     | 
    
         
            +
                    Creates an async-safe logger for the provided class name.
         
     | 
| 
      
 61 
     | 
    
         
            +
                    """
         
     | 
| 
      
 62 
     | 
    
         
            +
                    return create_async_logger(
         
     | 
| 
      
 63 
     | 
    
         
            +
                        logger_type=BootstrapLogger.__class__,
         
     | 
| 
      
 64 
     | 
    
         
            +
                        log_handlers=self._log_handlers,
         
     | 
| 
      
 65 
     | 
    
         
            +
                        min_log_level=LogLevel(os.getenv("NEXUS__LOG_LEVEL", "INFO")),
         
     | 
| 
      
 66 
     | 
    
         
            +
                        global_tags={
         
     | 
| 
      
 67 
     | 
    
         
            +
                            "request_id": request_id,
         
     | 
| 
      
 68 
     | 
    
         
            +
                            "algorithm": algorithm_name,
         
     | 
| 
      
 69 
     | 
    
         
            +
                        },
         
     | 
| 
      
 70 
     | 
    
         
            +
                    )
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
       32 
73 
     | 
    
         
             
            @final
         
     | 
| 
       33 
74 
     | 
    
         
             
            class LoggerFactory:
         
     | 
| 
       34 
75 
     | 
    
         
             
                """
         
     | 
| 
       35 
76 
     | 
    
         
             
                Async logger provisioner.
         
     | 
| 
       36 
77 
     | 
    
         
             
                """
         
     | 
| 
       37 
78 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
                def __init__( 
     | 
| 
      
 79 
     | 
    
         
            +
                def __init__(
         
     | 
| 
      
 80 
     | 
    
         
            +
                    self,
         
     | 
| 
      
 81 
     | 
    
         
            +
                    fixed_template: dict[str, dict[str, str]] | None = None,
         
     | 
| 
      
 82 
     | 
    
         
            +
                    fixed_template_delimiter: str = None,
         
     | 
| 
      
 83 
     | 
    
         
            +
                    global_tags: dict[str, str] | None = None,
         
     | 
| 
      
 84 
     | 
    
         
            +
                ):
         
     | 
| 
      
 85 
     | 
    
         
            +
                    self._global_tags = global_tags
         
     | 
| 
      
 86 
     | 
    
         
            +
                    self._fixed_template = fixed_template
         
     | 
| 
      
 87 
     | 
    
         
            +
                    self._fixed_template_delimiter = fixed_template_delimiter or ", "
         
     | 
| 
       39 
88 
     | 
    
         
             
                    self._log_handlers = [
         
     | 
| 
       40 
89 
     | 
    
         
             
                        StreamHandler(),
         
     | 
| 
       41 
90 
     | 
    
         
             
                    ]
         
     | 
| 
         @@ -45,12 +94,20 @@ class LoggerFactory: 
     | 
|
| 
       45 
94 
     | 
    
         
             
                                **json.loads(os.getenv("NEXUS__DATADOG_LOGGER_CONFIGURATION"))
         
     | 
| 
       46 
95 
     | 
    
         
             
                            )
         
     | 
| 
       47 
96 
     | 
    
         
             
                        )
         
     | 
| 
      
 97 
     | 
    
         
            +
                    if "NEXUS__LOGGER_FIXED_TEMPLATE" in os.environ:
         
     | 
| 
      
 98 
     | 
    
         
            +
                        self._fixed_template = self._fixed_template | json.loads(
         
     | 
| 
      
 99 
     | 
    
         
            +
                            os.getenv("NEXUS__LOGGER_FIXED_TEMPLATE")
         
     | 
| 
      
 100 
     | 
    
         
            +
                        )
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                    if "NEXUS__LOGGER_FIXED_TEMPLATE_DELIMITER" in os.environ:
         
     | 
| 
      
 103 
     | 
    
         
            +
                        self._fixed_template_delimiter = (
         
     | 
| 
      
 104 
     | 
    
         
            +
                            self._fixed_template_delimiter
         
     | 
| 
      
 105 
     | 
    
         
            +
                            or os.getenv("NEXUS__LOGGER_FIXED_TEMPLATE")
         
     | 
| 
      
 106 
     | 
    
         
            +
                        )
         
     | 
| 
       48 
107 
     | 
    
         | 
| 
       49 
108 
     | 
    
         
             
                def create_logger(
         
     | 
| 
       50 
109 
     | 
    
         
             
                    self,
         
     | 
| 
       51 
     | 
    
         
            -
                    logger_type:  
     | 
| 
       52 
     | 
    
         
            -
                    fixed_template: Optional[Dict[str, Dict[str, str]]] = None,
         
     | 
| 
       53 
     | 
    
         
            -
                    fixed_template_delimiter=", ",
         
     | 
| 
      
 110 
     | 
    
         
            +
                    logger_type: type[TLogger],
         
     | 
| 
       54 
111 
     | 
    
         
             
                ) -> LoggerInterface:
         
     | 
| 
       55 
112 
     | 
    
         
             
                    """
         
     | 
| 
       56 
113 
     | 
    
         
             
                    Creates an async-safe logger for the provided class name.
         
     | 
| 
         @@ -59,6 +116,7 @@ class LoggerFactory: 
     | 
|
| 
       59 
116 
     | 
    
         
             
                        logger_type=logger_type,
         
     | 
| 
       60 
117 
     | 
    
         
             
                        log_handlers=self._log_handlers,
         
     | 
| 
       61 
118 
     | 
    
         
             
                        min_log_level=LogLevel(os.getenv("NEXUS__LOG_LEVEL", "INFO")),
         
     | 
| 
       62 
     | 
    
         
            -
                        fixed_template= 
     | 
| 
       63 
     | 
    
         
            -
                        fixed_template_delimiter= 
     | 
| 
      
 119 
     | 
    
         
            +
                        fixed_template=self._fixed_template,
         
     | 
| 
      
 120 
     | 
    
         
            +
                        fixed_template_delimiter=self._fixed_template_delimiter,
         
     | 
| 
      
 121 
     | 
    
         
            +
                        global_tags=self._global_tags,
         
     | 
| 
       64 
122 
     | 
    
         
             
                    )
         
     | 
| 
         @@ -23,7 +23,7 @@ import platform 
     | 
|
| 
       23 
23 
     | 
    
         
             
            import signal
         
     | 
| 
       24 
24 
     | 
    
         
             
            import sys
         
     | 
| 
       25 
25 
     | 
    
         
             
            import traceback
         
     | 
| 
       26 
     | 
    
         
            -
            from typing import final, Type, Optional
         
     | 
| 
      
 26 
     | 
    
         
            +
            from typing import final, Type, Optional, Callable
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
            import backoff
         
     | 
| 
       29 
29 
     | 
    
         
             
            import urllib3.exceptions
         
     | 
| 
         @@ -41,7 +41,10 @@ from esd_services_api_client.crystal import ( 
     | 
|
| 
       41 
41 
     | 
    
         
             
                AlgorithmRunResult,
         
     | 
| 
       42 
42 
     | 
    
         
             
                CrystalEntrypointArguments,
         
     | 
| 
       43 
43 
     | 
    
         
             
            )
         
     | 
| 
       44 
     | 
    
         
            -
            from esd_services_api_client.nexus.abstractions.logger_factory import  
     | 
| 
      
 44 
     | 
    
         
            +
            from esd_services_api_client.nexus.abstractions.logger_factory import (
         
     | 
| 
      
 45 
     | 
    
         
            +
                LoggerFactory,
         
     | 
| 
      
 46 
     | 
    
         
            +
                BootstrapLoggerFactory,
         
     | 
| 
      
 47 
     | 
    
         
            +
            )
         
     | 
| 
       45 
48 
     | 
    
         
             
            from esd_services_api_client.nexus.abstractions.nexus_object import AlgorithmResult
         
     | 
| 
       46 
49 
     | 
    
         
             
            from esd_services_api_client.nexus.algorithms import (
         
     | 
| 
       47 
50 
     | 
    
         
             
                BaselineAlgorithm,
         
     | 
| 
         @@ -119,6 +122,21 @@ class Nexus: 
     | 
|
| 
       119 
122 
     | 
    
         
             
                    self._algorithm_run_task: Optional[asyncio.Task] = None
         
     | 
| 
       120 
123 
     | 
    
         
             
                    self._on_complete_tasks: list[type[UserTelemetryRecorder]] = []
         
     | 
| 
       121 
124 
     | 
    
         
             
                    self._payload_types: list[type[AlgorithmPayload]] = []
         
     | 
| 
      
 125 
     | 
    
         
            +
                    self._log_enricher: Callable[
         
     | 
| 
      
 126 
     | 
    
         
            +
                        [
         
     | 
| 
      
 127 
     | 
    
         
            +
                            AlgorithmPayload,
         
     | 
| 
      
 128 
     | 
    
         
            +
                            CrystalEntrypointArguments,
         
     | 
| 
      
 129 
     | 
    
         
            +
                        ],
         
     | 
| 
      
 130 
     | 
    
         
            +
                        dict[str, dict[str, str]],
         
     | 
| 
      
 131 
     | 
    
         
            +
                    ] | None = None
         
     | 
| 
      
 132 
     | 
    
         
            +
                    self._log_tagger: Callable[
         
     | 
| 
      
 133 
     | 
    
         
            +
                        [
         
     | 
| 
      
 134 
     | 
    
         
            +
                            AlgorithmPayload,
         
     | 
| 
      
 135 
     | 
    
         
            +
                            CrystalEntrypointArguments,
         
     | 
| 
      
 136 
     | 
    
         
            +
                        ],
         
     | 
| 
      
 137 
     | 
    
         
            +
                        dict[str, str],
         
     | 
| 
      
 138 
     | 
    
         
            +
                    ] | None = None
         
     | 
| 
      
 139 
     | 
    
         
            +
                    self._log_enrichment_delimiter: str = ", "
         
     | 
| 
       122 
140 
     | 
    
         | 
| 
       123 
141 
     | 
    
         
             
                    attach_signal_handlers()
         
     | 
| 
       124 
142 
     | 
    
         | 
| 
         @@ -177,6 +195,36 @@ class Nexus: 
     | 
|
| 
       177 
195 
     | 
    
         | 
| 
       178 
196 
     | 
    
         
             
                    return self
         
     | 
| 
       179 
197 
     | 
    
         | 
| 
      
 198 
     | 
    
         
            +
                def with_log_enricher(
         
     | 
| 
      
 199 
     | 
    
         
            +
                    self,
         
     | 
| 
      
 200 
     | 
    
         
            +
                    tagger: Callable[
         
     | 
| 
      
 201 
     | 
    
         
            +
                        [
         
     | 
| 
      
 202 
     | 
    
         
            +
                            AlgorithmPayload,
         
     | 
| 
      
 203 
     | 
    
         
            +
                            CrystalEntrypointArguments,
         
     | 
| 
      
 204 
     | 
    
         
            +
                        ],
         
     | 
| 
      
 205 
     | 
    
         
            +
                        dict[str, str],
         
     | 
| 
      
 206 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 207 
     | 
    
         
            +
                    | None,
         
     | 
| 
      
 208 
     | 
    
         
            +
                    enricher: Callable[
         
     | 
| 
      
 209 
     | 
    
         
            +
                        [
         
     | 
| 
      
 210 
     | 
    
         
            +
                            AlgorithmPayload,
         
     | 
| 
      
 211 
     | 
    
         
            +
                            CrystalEntrypointArguments,
         
     | 
| 
      
 212 
     | 
    
         
            +
                        ],
         
     | 
| 
      
 213 
     | 
    
         
            +
                        dict[str, dict[str, str]],
         
     | 
| 
      
 214 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 215 
     | 
    
         
            +
                    | None = None,
         
     | 
| 
      
 216 
     | 
    
         
            +
                    delimiter: str = ", ",
         
     | 
| 
      
 217 
     | 
    
         
            +
                ) -> "Nexus":
         
     | 
| 
      
 218 
     | 
    
         
            +
                    """
         
     | 
| 
      
 219 
     | 
    
         
            +
                    Adds a log `tagger` and a log `enricher` to be used with injected logger.
         
     | 
| 
      
 220 
     | 
    
         
            +
                    A log `tagger` will add key-value tags to each emitted log message, and those tags can be inferred from the payload and entrypoint arguments.
         
     | 
| 
      
 221 
     | 
    
         
            +
                    A log `enricher` will add additional static templated content to log messages, and render those templates using payload properties entrypoint argyments.
         
     | 
| 
      
 222 
     | 
    
         
            +
                    """
         
     | 
| 
      
 223 
     | 
    
         
            +
                    self._log_tagger = tagger
         
     | 
| 
      
 224 
     | 
    
         
            +
                    self._log_enricher = enricher
         
     | 
| 
      
 225 
     | 
    
         
            +
                    self._log_enrichment_delimiter = delimiter
         
     | 
| 
      
 226 
     | 
    
         
            +
                    return self
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
       180 
228 
     | 
    
         
             
                def with_module(self, module: Type[Module]) -> "Nexus":
         
     | 
| 
       181 
229 
     | 
    
         
             
                    """
         
     | 
| 
       182 
230 
     | 
    
         
             
                    Adds a (custom) DI module into the DI container.
         
     | 
| 
         @@ -260,11 +308,14 @@ class Nexus: 
     | 
|
| 
       260 
308 
     | 
    
         | 
| 
       261 
309 
     | 
    
         
             
                    self._injector = Injector(self._configurator.injection_binds)
         
     | 
| 
       262 
310 
     | 
    
         | 
| 
       263 
     | 
    
         
            -
                     
     | 
| 
       264 
     | 
    
         
            -
                         
     | 
| 
      
 311 
     | 
    
         
            +
                    bootstrap_logger: LoggerInterface = self._injector.get(
         
     | 
| 
      
 312 
     | 
    
         
            +
                        BootstrapLoggerFactory
         
     | 
| 
      
 313 
     | 
    
         
            +
                    ).create_logger(
         
     | 
| 
      
 314 
     | 
    
         
            +
                        request_id=self._run_args.request_id,
         
     | 
| 
      
 315 
     | 
    
         
            +
                        algorithm_name=os.getenv("CRYSTAL__ALGORITHM_NAME"),
         
     | 
| 
       265 
316 
     | 
    
         
             
                    )
         
     | 
| 
       266 
317 
     | 
    
         | 
| 
       267 
     | 
    
         
            -
                     
     | 
| 
      
 318 
     | 
    
         
            +
                    bootstrap_logger.start()
         
     | 
| 
       268 
319 
     | 
    
         | 
| 
       269 
320 
     | 
    
         
             
                    for payload_type in self._payload_types:
         
     | 
| 
       270 
321 
     | 
    
         
             
                        try:
         
     | 
| 
         @@ -272,10 +323,31 @@ class Nexus: 
     | 
|
| 
       272 
323 
     | 
    
         
             
                            self._injector.binder.bind(
         
     | 
| 
       273 
324 
     | 
    
         
             
                                payload.__class__, to=payload, scope=singleton
         
     | 
| 
       274 
325 
     | 
    
         
             
                            )
         
     | 
| 
      
 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),
         
     | 
| 
      
 332 
     | 
    
         
            +
                            )
         
     | 
| 
      
 333 
     | 
    
         
            +
                            # bind app-level LoggerFactory now
         
     | 
| 
      
 334 
     | 
    
         
            +
                            self._injector.binder.bind(
         
     | 
| 
      
 335 
     | 
    
         
            +
                                logger_factory.__class__,
         
     | 
| 
      
 336 
     | 
    
         
            +
                                to=logger_factory,
         
     | 
| 
      
 337 
     | 
    
         
            +
                                scope=singleton,
         
     | 
| 
      
 338 
     | 
    
         
            +
                            )
         
     | 
| 
       275 
339 
     | 
    
         
             
                        except BaseException as ex:  # pylint: disable=broad-except
         
     | 
| 
       276 
     | 
    
         
            -
                             
     | 
| 
      
 340 
     | 
    
         
            +
                            bootstrap_logger.error("Error reading algorithm payload", ex)
         
     | 
| 
       277 
341 
     | 
    
         
             
                            sys.exit(1)
         
     | 
| 
       278 
342 
     | 
    
         | 
| 
      
 343 
     | 
    
         
            +
                    bootstrap_logger.stop()
         
     | 
| 
      
 344 
     | 
    
         
            +
             
     | 
| 
      
 345 
     | 
    
         
            +
                    root_logger: LoggerInterface = self._injector.get(LoggerFactory).create_logger(
         
     | 
| 
      
 346 
     | 
    
         
            +
                        logger_type=self.__class__,
         
     | 
| 
      
 347 
     | 
    
         
            +
                    )
         
     | 
| 
      
 348 
     | 
    
         
            +
             
     | 
| 
      
 349 
     | 
    
         
            +
                    root_logger.start()
         
     | 
| 
      
 350 
     | 
    
         
            +
             
     | 
| 
       279 
351 
     | 
    
         
             
                    algorithm: BaselineAlgorithm = self._injector.get(self._algorithm_class)
         
     | 
| 
       280 
352 
     | 
    
         
             
                    telemetry_recorder: TelemetryRecorder = self._injector.get(TelemetryRecorder)
         
     | 
| 
       281 
353 
     | 
    
         | 
| 
         @@ -289,14 +361,18 @@ class Nexus: 
     | 
|
| 
       289 
361 
     | 
    
         
             
                        self._algorithm_run_task = asyncio.create_task(
         
     | 
| 
       290 
362 
     | 
    
         
             
                            instance.run(**self._run_args.__dict__)
         
     | 
| 
       291 
363 
     | 
    
         
             
                        )
         
     | 
| 
       292 
     | 
    
         
            -
             
     | 
| 
      
 364 
     | 
    
         
            +
             
     | 
| 
      
 365 
     | 
    
         
            +
                        # avoid exception propagation to main thread, since we need to handle it later
         
     | 
| 
      
 366 
     | 
    
         
            +
                        await asyncio.wait(
         
     | 
| 
      
 367 
     | 
    
         
            +
                            [self._algorithm_run_task], return_when=asyncio.FIRST_EXCEPTION
         
     | 
| 
      
 368 
     | 
    
         
            +
                        )
         
     | 
| 
       293 
369 
     | 
    
         
             
                        ex = self._algorithm_run_task.exception()
         
     | 
| 
       294 
370 
     | 
    
         | 
| 
       295 
371 
     | 
    
         
             
                        if ex is not None:
         
     | 
| 
       296 
372 
     | 
    
         
             
                            root_logger.error(
         
     | 
| 
       297 
373 
     | 
    
         
             
                                "Algorithm {algorithm} run failed on Nexus version {version}",
         
     | 
| 
       298 
374 
     | 
    
         
             
                                ex,
         
     | 
| 
       299 
     | 
    
         
            -
                                algorithm= 
     | 
| 
      
 375 
     | 
    
         
            +
                                algorithm=algorithm.__class__.__name__,
         
     | 
| 
       300 
376 
     | 
    
         
             
                                version=__version__,
         
     | 
| 
       301 
377 
     | 
    
         
             
                            )
         
     | 
| 
       302 
378 
     | 
    
         | 
| 
         @@ -307,8 +383,8 @@ class Nexus: 
     | 
|
| 
       307 
383 
     | 
    
         | 
| 
       308 
384 
     | 
    
         
             
                        # record telemetry
         
     | 
| 
       309 
385 
     | 
    
         
             
                        root_logger.info(
         
     | 
| 
       310 
     | 
    
         
            -
                            "Recording telemetry for the run { 
     | 
| 
       311 
     | 
    
         
            -
                             
     | 
| 
      
 386 
     | 
    
         
            +
                            "Recording telemetry for the run {run_id}",
         
     | 
| 
      
 387 
     | 
    
         
            +
                            run_id=self._run_args.request_id,
         
     | 
| 
       312 
388 
     | 
    
         
             
                        )
         
     | 
| 
       313 
389 
     | 
    
         
             
                        async with telemetry_recorder as recorder:
         
     | 
| 
       314 
390 
     | 
    
         
             
                            await recorder.record(
         
     | 
| 
         @@ -30,7 +30,9 @@ from injector import Module, singleton, provider 
     | 
|
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
            from esd_services_api_client.crystal import CrystalConnector
         
     | 
| 
       32 
32 
     | 
    
         
             
            from esd_services_api_client.nexus.abstractions.algrorithm_cache import InputCache
         
     | 
| 
       33 
     | 
    
         
            -
            from esd_services_api_client.nexus.abstractions.logger_factory import  
     | 
| 
      
 33 
     | 
    
         
            +
            from esd_services_api_client.nexus.abstractions.logger_factory import (
         
     | 
| 
      
 34 
     | 
    
         
            +
                BootstrapLoggerFactory,
         
     | 
| 
      
 35 
     | 
    
         
            +
            )
         
     | 
| 
       34 
36 
     | 
    
         
             
            from esd_services_api_client.nexus.abstractions.socket_provider import (
         
     | 
| 
       35 
37 
     | 
    
         
             
                ExternalSocketProvider,
         
     | 
| 
       36 
38 
     | 
    
         
             
            )
         
     | 
| 
         @@ -72,18 +74,18 @@ class MetricsModule(Module): 
     | 
|
| 
       72 
74 
     | 
    
         | 
| 
       73 
75 
     | 
    
         | 
| 
       74 
76 
     | 
    
         
             
            @final
         
     | 
| 
       75 
     | 
    
         
            -
            class  
     | 
| 
      
 77 
     | 
    
         
            +
            class BootstrapLoggerFactoryModule(Module):
         
     | 
| 
       76 
78 
     | 
    
         
             
                """
         
     | 
| 
       77 
79 
     | 
    
         
             
                Logger factory module.
         
     | 
| 
       78 
80 
     | 
    
         
             
                """
         
     | 
| 
       79 
81 
     | 
    
         | 
| 
       80 
82 
     | 
    
         
             
                @singleton
         
     | 
| 
       81 
83 
     | 
    
         
             
                @provider
         
     | 
| 
       82 
     | 
    
         
            -
                def provide(self) ->  
     | 
| 
      
 84 
     | 
    
         
            +
                def provide(self) -> BootstrapLoggerFactory:
         
     | 
| 
       83 
85 
     | 
    
         
             
                    """
         
     | 
| 
       84 
86 
     | 
    
         
             
                    DI factory method.
         
     | 
| 
       85 
87 
     | 
    
         
             
                    """
         
     | 
| 
       86 
     | 
    
         
            -
                    return  
     | 
| 
      
 88 
     | 
    
         
            +
                    return BootstrapLoggerFactory()
         
     | 
| 
       87 
89 
     | 
    
         | 
| 
       88 
90 
     | 
    
         | 
| 
       89 
91 
     | 
    
         
             
            @final
         
     | 
| 
         @@ -234,6 +236,7 @@ class ServiceConfigurator: 
     | 
|
| 
       234 
236 
     | 
    
         | 
| 
       235 
237 
     | 
    
         
             
                def __init__(self):
         
     | 
| 
       236 
238 
     | 
    
         
             
                    self._injection_binds = [
         
     | 
| 
      
 239 
     | 
    
         
            +
                        BootstrapLoggerFactoryModule(),
         
     | 
| 
       237 
240 
     | 
    
         
             
                        MetricsModule(),
         
     | 
| 
       238 
241 
     | 
    
         
             
                        CrystalReceiverClientModule(),
         
     | 
| 
       239 
242 
     | 
    
         
             
                        QueryEnabledStoreModule(),
         
     | 
| 
         @@ -1,21 +1,19 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            Metadata-Version: 2.3
         
     | 
| 
       2 
2 
     | 
    
         
             
            Name: esd-services-api-client
         
     | 
| 
       3 
     | 
    
         
            -
            Version: 2. 
     | 
| 
      
 3 
     | 
    
         
            +
            Version: 2.6.1
         
     | 
| 
       4 
4 
     | 
    
         
             
            Summary: Python clients for ESD services
         
     | 
| 
       5 
5 
     | 
    
         
             
            License: Apache 2.0
         
     | 
| 
       6 
6 
     | 
    
         
             
            Author: ECCO Sneaks & Data
         
     | 
| 
       7 
7 
     | 
    
         
             
            Author-email: esdsupport@ecco.com
         
     | 
| 
       8 
8 
     | 
    
         
             
            Maintainer: GZU
         
     | 
| 
       9 
9 
     | 
    
         
             
            Maintainer-email: gzu@ecco.com
         
     | 
| 
       10 
     | 
    
         
            -
            Requires-Python: >=3. 
     | 
| 
      
 10 
     | 
    
         
            +
            Requires-Python: >=3.11,<3.12
         
     | 
| 
       11 
11 
     | 
    
         
             
            Classifier: License :: Other/Proprietary License
         
     | 
| 
       12 
12 
     | 
    
         
             
            Classifier: Programming Language :: Python :: 3
         
     | 
| 
       13 
     | 
    
         
            -
            Classifier: Programming Language :: Python :: 3.9
         
     | 
| 
       14 
     | 
    
         
            -
            Classifier: Programming Language :: Python :: 3.10
         
     | 
| 
       15 
13 
     | 
    
         
             
            Classifier: Programming Language :: Python :: 3.11
         
     | 
| 
       16 
14 
     | 
    
         
             
            Provides-Extra: azure
         
     | 
| 
       17 
15 
     | 
    
         
             
            Provides-Extra: nexus
         
     | 
| 
       18 
     | 
    
         
            -
            Requires-Dist: adapta[ 
     | 
| 
      
 16 
     | 
    
         
            +
            Requires-Dist: adapta[datadog,storage] (>=3.3,<4.0)
         
     | 
| 
       19 
17 
     | 
    
         
             
            Requires-Dist: azure-identity (>=1.7,<1.8) ; extra == "azure"
         
     | 
| 
       20 
18 
     | 
    
         
             
            Requires-Dist: dataclasses-json (>=0.6.0,<0.7.0)
         
     | 
| 
       21 
19 
     | 
    
         
             
            Requires-Dist: httpx (>=0.27.0,<0.28.0) ; extra == "nexus"
         
     | 
    
        {esd_services_api_client-2.5.14a148.dev5.dist-info → esd_services_api_client-2.6.1.dist-info}/RECORD
    RENAMED
    
    | 
         @@ -1,5 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            esd_services_api_client/__init__.py,sha256= 
     | 
| 
       2 
     | 
    
         
            -
            esd_services_api_client/_version.py,sha256=FrmlYBMHa48XHRqBIZUWCZDO-FJfblJzIeg6CSTLDmE,33
         
     | 
| 
      
 1 
     | 
    
         
            +
            esd_services_api_client/__init__.py,sha256=FJBUxZX7h17fr_sUs01bd-fSxy6eQ6zLaqD-pb5bvRo,648
         
     | 
| 
       3 
2 
     | 
    
         
             
            esd_services_api_client/beast/__init__.py,sha256=zNhXcHSP5w4P9quM1XP4oXVJEccvC_VScG41TZ0GzZ8,723
         
     | 
| 
       4 
3 
     | 
    
         
             
            esd_services_api_client/beast/v3/__init__.py,sha256=FtumtInoDyCCRE424Llqv8QZLRuwXzj-smyfu1od1nc,754
         
     | 
| 
       5 
4 
     | 
    
         
             
            esd_services_api_client/beast/v3/_connector.py,sha256=VqxiCzJWKERh42aZAIphzmOEG5cdOcKM0DQzG7eQ_-8,11479
         
     | 
| 
         @@ -8,19 +7,19 @@ esd_services_api_client/boxer/README.md,sha256=-MAhYUPvmEMcgx_lo_2PlH_gZI1lndGv8 
     | 
|
| 
       8 
7 
     | 
    
         
             
            esd_services_api_client/boxer/__init__.py,sha256=yDEcfL-9q0H91UWr-al-1iMJtVLv-oIXky6hUmFZs0g,785
         
     | 
| 
       9 
8 
     | 
    
         
             
            esd_services_api_client/boxer/_auth.py,sha256=q9vU4agH-s6HPpVTEdkXFA_RvO92hogOfjurfjHBmBg,7445
         
     | 
| 
       10 
9 
     | 
    
         
             
            esd_services_api_client/boxer/_base.py,sha256=LMKDArELZlWVKJH10coUFSSN8MFH6KfHCBncEDjsiIU,981
         
     | 
| 
       11 
     | 
    
         
            -
            esd_services_api_client/boxer/_connector.py,sha256= 
     | 
| 
      
 10 
     | 
    
         
            +
            esd_services_api_client/boxer/_connector.py,sha256=UsZnAUSXT9BeUAU8eoezEaADrqz8ab-jSp4MVa-e3eM,8716
         
     | 
| 
       12 
11 
     | 
    
         
             
            esd_services_api_client/boxer/_models.py,sha256=ursQIR_c9jcVfRKc0LH1OuVL2KFD6kqojyGBadRfRPI,1702
         
     | 
| 
       13 
12 
     | 
    
         
             
            esd_services_api_client/common/__init__.py,sha256=L-cEW1mVbnTJLCLG5V6Ucw7zBgx1zf0t1bYcQC1heyw,603
         
     | 
| 
       14 
13 
     | 
    
         
             
            esd_services_api_client/crystal/__init__.py,sha256=oeyJjdQ9EpTnIq6XnjPq5v0DWPdHqi4uEfRIcD1mNZA,792
         
     | 
| 
       15 
14 
     | 
    
         
             
            esd_services_api_client/crystal/_api_versions.py,sha256=GHbmV_5lP9fP72TZE0j_ZeQSeJjMRcRaBRxNJbz-MWQ,837
         
     | 
| 
       16 
15 
     | 
    
         
             
            esd_services_api_client/crystal/_connector.py,sha256=0CqBpPahozAnentM6ZZrH84s_D7SoWCShr5_cRQGMX8,13110
         
     | 
| 
       17 
16 
     | 
    
         
             
            esd_services_api_client/crystal/_models.py,sha256=j8SEbwp_iAKjn06i-0f8npmhQhs2YJlmQ3eHwc2TwQE,4366
         
     | 
| 
       18 
     | 
    
         
            -
            esd_services_api_client/nexus/README.md,sha256= 
     | 
| 
      
 17 
     | 
    
         
            +
            esd_services_api_client/nexus/README.md,sha256=hNFV_fzAGrG6_1yXE3o_GuLTKIWEia2FfedMh-Sg0ew,10619
         
     | 
| 
       19 
18 
     | 
    
         
             
            esd_services_api_client/nexus/__init__.py,sha256=sOgKKq3_LZGbLmQMtMS7lDw2hv027qownTmNIRV0BB8,627
         
     | 
| 
       20 
19 
     | 
    
         
             
            esd_services_api_client/nexus/abstractions/__init__.py,sha256=sOgKKq3_LZGbLmQMtMS7lDw2hv027qownTmNIRV0BB8,627
         
     | 
| 
       21 
20 
     | 
    
         
             
            esd_services_api_client/nexus/abstractions/algrorithm_cache.py,sha256=6GevJJ7mf1c_PImhKQ_4_6n652VyHlgK_12LNidirxs,3644
         
     | 
| 
       22 
21 
     | 
    
         
             
            esd_services_api_client/nexus/abstractions/input_object.py,sha256=RUKnhekuZwd_RVvnLGAxHa4wYDFJf6wEwWQI9f-o0lM,1761
         
     | 
| 
       23 
     | 
    
         
            -
            esd_services_api_client/nexus/abstractions/logger_factory.py,sha256= 
     | 
| 
      
 22 
     | 
    
         
            +
            esd_services_api_client/nexus/abstractions/logger_factory.py,sha256=oJStrOPir8J18E3ALhUTCQrj3rbjo2yuYrnjpDwLQg8,3947
         
     | 
| 
       24 
23 
     | 
    
         
             
            esd_services_api_client/nexus/abstractions/nexus_object.py,sha256=rLE42imCVGE6Px4Yu6X6C4b69gA1grK-7Md_SuCLN2Q,3115
         
     | 
| 
       25 
24 
     | 
    
         
             
            esd_services_api_client/nexus/abstractions/socket_provider.py,sha256=Rwa_aPErI4Es5AdyCd3EoGze7mg2D70u8kuc2UGEBaI,1729
         
     | 
| 
       26 
25 
     | 
    
         
             
            esd_services_api_client/nexus/algorithms/__init__.py,sha256=v4rPDf36r6AaHi_3K8isBKYU_fG8ct3w14KpUg2XRgg,976
         
     | 
| 
         @@ -33,8 +32,8 @@ esd_services_api_client/nexus/algorithms/recursive.py,sha256=uaCCl4q-st_KqbcmkdO 
     | 
|
| 
       33 
32 
     | 
    
         
             
            esd_services_api_client/nexus/configurations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       34 
33 
     | 
    
         
             
            esd_services_api_client/nexus/configurations/algorithm_configuration.py,sha256=eE7diX2PATCGkmqhvFOcZwXrr6vns4fqnJGmgNvhhZM,1091
         
     | 
| 
       35 
34 
     | 
    
         
             
            esd_services_api_client/nexus/core/__init__.py,sha256=sOgKKq3_LZGbLmQMtMS7lDw2hv027qownTmNIRV0BB8,627
         
     | 
| 
       36 
     | 
    
         
            -
            esd_services_api_client/nexus/core/app_core.py,sha256= 
     | 
| 
       37 
     | 
    
         
            -
            esd_services_api_client/nexus/core/app_dependencies.py,sha256= 
     | 
| 
      
 35 
     | 
    
         
            +
            esd_services_api_client/nexus/core/app_core.py,sha256=Lmkpq7Hy74EfMOi5vtjD82PpY7Lb84RVbXN5b82BxKs,15462
         
     | 
| 
      
 36 
     | 
    
         
            +
            esd_services_api_client/nexus/core/app_dependencies.py,sha256=1m7Oc9JCXyrU0qVZekYhpbXLQo20aQPQ-Bf8zEdjtqI,8704
         
     | 
| 
       38 
37 
     | 
    
         
             
            esd_services_api_client/nexus/core/serializers.py,sha256=Vk9FaEeDHXx3S7rPlYoWzsOcN6gzLzemsrjq6ytfaI0,2217
         
     | 
| 
       39 
38 
     | 
    
         
             
            esd_services_api_client/nexus/exceptions/__init__.py,sha256=feN33VdqB5-2bD9aJesJl_OlsKrNNo3hZCnQgKuaU9k,696
         
     | 
| 
       40 
39 
     | 
    
         
             
            esd_services_api_client/nexus/exceptions/_nexus_error.py,sha256=QvtY38mNoIA6t26dUN6UIsaPfljhtVNsbQVS7ksMb-Q,895
         
     | 
| 
         @@ -51,7 +50,7 @@ esd_services_api_client/nexus/modules/mlflow_module.py,sha256=d4y8XetGF37md4dEpE 
     | 
|
| 
       51 
50 
     | 
    
         
             
            esd_services_api_client/nexus/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       52 
51 
     | 
    
         
             
            esd_services_api_client/nexus/telemetry/recorder.py,sha256=-shxk2vYDTafJ0U3CzkHxIHBQtxVJ1ZNI4ST0p1YV2g,4801
         
     | 
| 
       53 
52 
     | 
    
         
             
            esd_services_api_client/nexus/telemetry/user_telemetry_recorder.py,sha256=NgnjSY64nEx1kslkdomENC6vMqkEOpfXggJXwm-NyFs,5163
         
     | 
| 
       54 
     | 
    
         
            -
            esd_services_api_client-2. 
     | 
| 
       55 
     | 
    
         
            -
            esd_services_api_client-2. 
     | 
| 
       56 
     | 
    
         
            -
            esd_services_api_client-2. 
     | 
| 
       57 
     | 
    
         
            -
            esd_services_api_client-2. 
     | 
| 
      
 53 
     | 
    
         
            +
            esd_services_api_client-2.6.1.dist-info/LICENSE,sha256=0gS6zXsPp8qZhzi1xaGCIYPzb_0e8on7HCeFJe8fOpw,10693
         
     | 
| 
      
 54 
     | 
    
         
            +
            esd_services_api_client-2.6.1.dist-info/METADATA,sha256=Y893K15f-VzKzAKxxs66BGwf8sCkGvMHe0hm_T3VL6Y,1058
         
     | 
| 
      
 55 
     | 
    
         
            +
            esd_services_api_client-2.6.1.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
         
     | 
| 
      
 56 
     | 
    
         
            +
            esd_services_api_client-2.6.1.dist-info/RECORD,,
         
     | 
| 
         @@ -1 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            __version__ = 'v2.5.14a148.dev5'
         
     | 
| 
         
            File without changes
         
     |