malevich-coretools 0.2.17__py3-none-any.whl → 0.2.19__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 malevich-coretools might be problematic. Click here for more details.

@@ -1,2 +1,3 @@
1
+ from .secondary import logs_streaming # noqa: F401
1
2
  from .tools import vast_settings # noqa: F401
2
3
  from .utils import * # noqa: F403
@@ -346,8 +346,8 @@ class AppLog(BaseModel):
346
346
 
347
347
  class AppLogs(BaseModel):
348
348
  operationId: Alias.Id
349
- dagLogs: str
350
- data: Dict[str, AppLog]
349
+ dagLogs: str = ""
350
+ data: Dict[str, AppLog] = {}
351
351
  error: Optional[str] = None
352
352
 
353
353
 
@@ -8,6 +8,7 @@ class Config:
8
8
  TOKEN = os.environ.get("GITLAB_ACCESS_TOKEN") # FIXME
9
9
 
10
10
  HOST_PORT = None
11
+ KAFKA_HOST_PORT = None
11
12
  CORE_USERNAME = None
12
13
  CORE_PASSWORD = None
13
14
  VERBOSE = False
@@ -1,15 +1,18 @@
1
1
  import json
2
2
  import random as rand
3
3
  import string
4
- from typing import Any, Callable, Dict, Tuple, Union
4
+ from typing import Any, Callable, Dict, Optional, Tuple, Union
5
5
 
6
6
  from pydantic import BaseModel
7
7
 
8
8
  from malevich_coretools.abstract.abstract import Alias, AppLogs, LogsResult
9
9
  from malevich_coretools.secondary import Config
10
+ from malevich_coretools.secondary.kafka import handle_logs
10
11
 
11
12
  __mini__delimiter = "-" * 25
12
13
  __delimiter = "-" * 50
14
+ __colors = [f"\x1b[{i};20m" for i in range(31, 38)]
15
+ __color_reset = "\x1b[0m"
13
16
 
14
17
 
15
18
  def to_json(data: Union[Dict[str, Any], Alias.Json], condition_and_msg: Tuple[Callable[[Dict[str, Any]], bool], str] = (lambda _: True, "")) -> str:
@@ -53,7 +56,7 @@ def __show_logs_result(res: LogsResult): # noqa: ANN202
53
56
  print(logs)
54
57
 
55
58
 
56
- def __show_logs(app_logs: AppLogs, err: bool = False): # noqa: ANN202
59
+ def show_logs(app_logs: AppLogs, err: bool = False) -> None: # noqa: ANN202
57
60
  show = Config.logger.error if err else Config.logger.info
58
61
  show(f"operation_id = {app_logs.operationId}")
59
62
  if app_logs.error is not None:
@@ -73,10 +76,51 @@ def __show_logs(app_logs: AppLogs, err: bool = False): # noqa: ANN202
73
76
  print(__delimiter)
74
77
 
75
78
 
79
+ def show_logs_colored(app_logs: AppLogs, colors_dict: Optional[Dict[str, str]] = None) -> None:
80
+ """colors_dict - should be unique for all app_logs by operation_id"""
81
+ def format(log, color: Optional[str]) -> None:
82
+ if color is None:
83
+ Config.logger.warning(log)
84
+ else:
85
+ Config.logger.warning(color + log + __color_reset)
86
+
87
+ def get_color(name: str) -> str:
88
+ if colors_dict is None:
89
+ return None
90
+ color = colors_dict.get(name, None)
91
+ if color is None:
92
+ color = __colors[len(colors_dict) % len(__colors)]
93
+ colors_dict[name] = color
94
+ return color
95
+
96
+ if app_logs.error is not None:
97
+ format(f"error: {app_logs.error}", get_color("error"))
98
+ if len(app_logs.dagLogs) > 0:
99
+ color = get_color("dagLogs")
100
+ for line in app_logs.dagLogs.splitlines():
101
+ format(f"dag: {line}", color)
102
+ for app_name, app_log in app_logs.data.items():
103
+ color = get_color(f"${app_name}")
104
+ for i, logs_result in enumerate(app_log.data):
105
+ app_name_prefix = f"{app_name}${i}" if i != 0 else app_name
106
+ if len(logs_result.data) > 0:
107
+ for line in logs_result.data.splitlines():
108
+ format(f"{app_name_prefix}$main: {line}", color)
109
+ if len(logs_result.logs) > 0:
110
+ for run_id, logs in logs_result.logs.items():
111
+ user_logs = logs_result.userLogs.get(run_id, "")
112
+ if len(user_logs) > 0:
113
+ for line in user_logs.splitlines():
114
+ format(f"{app_name_prefix}${run_id}: {line}", color)
115
+ if len(logs) > 0:
116
+ for line in logs.splitlines():
117
+ format(f"{app_name_prefix}${run_id}: {line}", color)
118
+
119
+
76
120
  def show_logs_func(data: str, err: bool = False): # noqa: ANN201
77
121
  try:
78
122
  app_logs = AppLogs.parse_raw(data)
79
- __show_logs(app_logs, err=err)
123
+ show_logs(app_logs, err=err)
80
124
  except BaseException:
81
125
  Config.logger.error("decode logs failed")
82
126
  show = Config.logger.error if err else Config.logger.info
@@ -92,3 +136,9 @@ def show_fail_app_info(data: str, err: bool): # noqa: ANN201
92
136
  except BaseException:
93
137
  Config.logger.error("decode unsuccessful app_info fail")
94
138
  print(data)
139
+
140
+
141
+ def logs_streaming(operation_id: str, kafka_host_port: Optional[str] = None, app_logs_show: Callable[[AppLogs], None] = show_logs_colored) -> None:
142
+ colors_dict = {}
143
+ for appLogs in handle_logs(operation_id, kafka_host_port=kafka_host_port):
144
+ app_logs_show(appLogs, colors_dict=colors_dict)
@@ -0,0 +1,32 @@
1
+ from typing import Generator, Optional
2
+
3
+ from kafka import KafkaConsumer
4
+
5
+ from malevich_coretools.abstract import AppLogs
6
+ from malevich_coretools.secondary import Config
7
+
8
+
9
+ def __logs_topic(operation_id: str) -> str:
10
+ return f"{operation_id}-logs"
11
+
12
+
13
+ def handle_logs(operation_id: str, kafka_host_port: Optional[str] = None) -> Generator[AppLogs, None, None]:
14
+ if kafka_host_port is None:
15
+ kafka_host_port = Config.KAFKA_HOST_PORT
16
+ assert kafka_host_port is not None, "kafka_host_port not set"
17
+
18
+ topic = __logs_topic(operation_id)
19
+ consumer = KafkaConsumer(topic, bootstrap_servers=kafka_host_port)
20
+
21
+ try:
22
+ for message in consumer:
23
+ if message.value == b'end':
24
+ return
25
+ try:
26
+ logs = AppLogs.model_validate_json(message.value)
27
+ except BaseException as ex:
28
+ Config.logger.error(message.value)
29
+ raise ex
30
+ yield logs
31
+ except KeyboardInterrupt:
32
+ pass
@@ -29,6 +29,12 @@ def set_host_port(host_port: str) -> None:
29
29
  Config.HOST_PORT = host_port
30
30
 
31
31
 
32
+ def set_kafka_host_port(host_port: str) -> None:
33
+ """update kafka host and port for malevich-kafka, example: `localhost:9092` """
34
+ assert len(host_port) > 0, "empty host port"
35
+ Config.KAFKA_HOST_PORT = host_port
36
+
37
+
32
38
  def set_conn_url(conn_url: str) -> None:
33
39
  """analogue set_host_port; update `conn_url` for malevich-core, example: `http://localhost:8080/` """
34
40
  set_host_port(conn_url)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: malevich-coretools
3
- Version: 0.2.17
3
+ Version: 0.2.19
4
4
  Author: Andrew Pogrebnoj
5
5
  Author-email: andrew@onjulius.co
6
6
  License-File: LICENSE
@@ -1,20 +1,21 @@
1
- malevich_coretools/__init__.py,sha256=88IRvwNti4YOMJc6RaVRutwurJzP23g30D-rgo04Fgc,82
2
- malevich_coretools/utils.py,sha256=bk2xYQaGrcdQbyNiEuR2TkPFbdh-oxQD4qvfnEUXj_I,65142
1
+ malevich_coretools/__init__.py,sha256=DJtPESxkCZD2SbTZTrR_x0TKDQ4MJpmBqGw5YpKYidM,134
2
+ malevich_coretools/utils.py,sha256=BlzS_hfWzvqFWaE-dbdcH8oDdgwzMwEcsW9jnFWQNSw,65365
3
3
  malevich_coretools/abstract/__init__.py,sha256=ZWtP4gFLpNVFXzlMKXEK4iMnUqqMg07pL8yKGSJd6QI,38
4
- malevich_coretools/abstract/abstract.py,sha256=zRyUW_PHJvL8NNABZZL3PV_05qkYKp6ugAkfyls95V4,9232
4
+ malevich_coretools/abstract/abstract.py,sha256=wQ_1e8KfWWqHs6xSIQk1j2Ph5OO8saxMcmMdnUB4bo0,9242
5
5
  malevich_coretools/admin/__init__.py,sha256=zdIcHs3T_NZ8HYWts-O7OpBEWHIu779QDZMGF5HRCLg,35
6
6
  malevich_coretools/admin/utils.py,sha256=NE0Mw_Tytsi0PLD62_sI8tUVZNQaRrtUaa4oFwfUt84,1497
7
7
  malevich_coretools/funcs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  malevich_coretools/funcs/funcs.py,sha256=LGOarZ-nyBVo8V96EMU4zRTyz42aTEa5p4ECam6lzSw,32368
9
9
  malevich_coretools/funcs/helpers.py,sha256=Y8v6uyawYl2_G0XmhmiVLqGIUzvxnkpKF0ODA9vrB3Y,1276
10
10
  malevich_coretools/secondary/__init__.py,sha256=048HqvG36_1WdDVZK_RuECmaf14Iq2fviUysG1inlaE,78
11
- malevich_coretools/secondary/config.py,sha256=b7RysQTkPKib8FEhfm3uU7TPvz8vgWLlqakvZN5NFs4,391
11
+ malevich_coretools/secondary/config.py,sha256=Lrnh3xl2WPqWF3TvbcPoUnj4LRtceY4pUSMl-4_pQcI,418
12
12
  malevich_coretools/secondary/const.py,sha256=2_Uer7-sCRdHRoAyl-LsEBPnQd5BHloWAOzyvs_ZQyI,9592
13
- malevich_coretools/secondary/helpers.py,sha256=lcWN1ctfVQa5KFqh5mXdp_16hA3TXhJGe4mtNdQHnUA,3072
13
+ malevich_coretools/secondary/helpers.py,sha256=DnQ1J6Kw1AdN2SicRUz5naFZOC3THgCUjUgMfPsMxDg,5365
14
+ malevich_coretools/secondary/kafka.py,sha256=SIUnBFyfwsquN6MAUrEkKCw-1l7979Znl7OTQSX2UKo,989
14
15
  malevich_coretools/tools/__init__.py,sha256=jDxlCa5Dr6Y43qlI7JwsRAlBkKmFeTHTEnjNUvu-0iw,46
15
16
  malevich_coretools/tools/vast.py,sha256=u1cnfylSgq3nYfonXbTy1zwor3OPkhD3vRf2OnqlMZY,12504
16
- malevich_coretools-0.2.17.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
17
- malevich_coretools-0.2.17.dist-info/METADATA,sha256=li4ALUaC86aHorIDMCkH7vvyqqhkptY2GvM0DnW9HfM,237
18
- malevich_coretools-0.2.17.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
19
- malevich_coretools-0.2.17.dist-info/top_level.txt,sha256=wDX3s1Tso0otBPNrFRfXqyNpm48W4Bp5v6JfbITO2Z8,19
20
- malevich_coretools-0.2.17.dist-info/RECORD,,
17
+ malevich_coretools-0.2.19.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
18
+ malevich_coretools-0.2.19.dist-info/METADATA,sha256=SDxX7twPtlbc-j41EHwdeqrjHYIJSnWKP3YzRtEvtMw,237
19
+ malevich_coretools-0.2.19.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
20
+ malevich_coretools-0.2.19.dist-info/top_level.txt,sha256=wDX3s1Tso0otBPNrFRfXqyNpm48W4Bp5v6JfbITO2Z8,19
21
+ malevich_coretools-0.2.19.dist-info/RECORD,,