malevich-coretools 0.3.67__py3-none-any.whl → 0.3.69__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,3 +1,4 @@
1
+ from .dm_utils import * # noqa: F403
1
2
  from .secondary import logs_streaming # noqa: F401
2
3
  from .tools import vast_settings # noqa: F401
3
4
  from .utils import * # noqa: F403
@@ -133,6 +133,10 @@ class KeysValues(Operation):
133
133
  data: Dict[str, str]
134
134
 
135
135
 
136
+ class Keys(BaseModel):
137
+ data: Dict[str, str]
138
+
139
+
136
140
  class ScaleInfo(BaseModel):
137
141
  taskId: Optional[Alias.Id] = None
138
142
  appId: Alias.Id
@@ -254,6 +258,10 @@ class ResultIds(BaseModel):
254
258
  ids: List[Alias.Id]
255
259
 
256
260
 
261
+ class ResultNames(BaseModel):
262
+ names: List[str]
263
+
264
+
257
265
  class FilesDirs(BaseModel):
258
266
  files: Dict[str, int]
259
267
  directories: List[str]
@@ -101,6 +101,8 @@ class AppEntity(BaseModel):
101
101
  image: JsonImage
102
102
  platform: str = "base"
103
103
  platformSettings: Optional[str] = None
104
+ requestedKeys: Optional[list[str]] = None # user secret keys
105
+ optionalKeys: Optional[list[str]] = None # user secret keys
104
106
 
105
107
  def internal(self) -> None:
106
108
  assert self.conditions is None or self.conditionsStructure is None, "should be set not more, than one of (conditions, conditionsStructure)"
@@ -0,0 +1,233 @@
1
+ from typing import (
2
+ Any,
3
+ AsyncIterable,
4
+ Coroutine,
5
+ Iterable,
6
+ List,
7
+ Literal,
8
+ Optional,
9
+ Union,
10
+ overload,
11
+ )
12
+
13
+ import malevich_coretools.funcs.dm_funcs as f
14
+
15
+
16
+ @overload
17
+ def dm_stream(
18
+ operation_id: str,
19
+ run_id: str,
20
+ bind_id: str,
21
+ *,
22
+ conn_url: Optional[str] = None,
23
+ is_async: Literal[False] = False,
24
+ ) -> Iterable:
25
+ pass
26
+
27
+
28
+ @overload
29
+ def dm_stream(
30
+ operation_id: str,
31
+ run_id: str,
32
+ bind_id: str,
33
+ *,
34
+ conn_url: Optional[str] = None,
35
+ is_async: Literal[True],
36
+ ) -> Coroutine[Any, Any, AsyncIterable]:
37
+ pass
38
+
39
+
40
+ def dm_stream(
41
+ operation_id: str,
42
+ run_id: str,
43
+ bind_id: str,
44
+ *,
45
+ conn_url: Optional[str] = None,
46
+ is_async: bool = False,
47
+ ) -> Union[Iterable, Coroutine[Any, Any, AsyncIterable]]:
48
+ if is_async:
49
+ return f.dm_stream_async(operation_id, run_id, bind_id, conn_url=conn_url)
50
+ return f.dm_stream(operation_id, run_id, bind_id, conn_url=conn_url)
51
+
52
+
53
+ @overload
54
+ def dm_continue(
55
+ operation_id: str,
56
+ run_id: str,
57
+ id: str,
58
+ data: Any,
59
+ *,
60
+ conn_url: Optional[str] = None,
61
+ is_async: Literal[False] = False,
62
+ ) -> None:
63
+ pass
64
+
65
+
66
+ @overload
67
+ def dm_continue(
68
+ operation_id: str,
69
+ run_id: str,
70
+ id: str,
71
+ data: Any,
72
+ *,
73
+ conn_url: Optional[str] = None,
74
+ is_async: Literal[True],
75
+ ) -> Coroutine[Any, Any, None]:
76
+ pass
77
+
78
+
79
+ def dm_continue(
80
+ operation_id: str,
81
+ run_id: str,
82
+ id: str,
83
+ data: Any,
84
+ *,
85
+ conn_url: Optional[str] = None,
86
+ is_async: bool = False,
87
+ ) -> Union[None, Coroutine[Any, Any, None]]:
88
+ if is_async:
89
+ return f.dm_continue_async(operation_id, run_id, id, data, conn_url=conn_url)
90
+ return f.dm_continue(operation_id, run_id, id, data, conn_url=conn_url)
91
+
92
+
93
+ @overload
94
+ def dm_state(
95
+ operation_id: str,
96
+ run_id: str,
97
+ bind_id: str,
98
+ key: Optional[str] = None,
99
+ index: Optional[int] = None,
100
+ *,
101
+ conn_url: Optional[str] = None,
102
+ is_async: Literal[False] = False,
103
+ ) -> Any:
104
+ pass
105
+
106
+
107
+ @overload
108
+ def dm_state(
109
+ operation_id: str,
110
+ run_id: str,
111
+ bind_id: str,
112
+ key: Optional[str] = None,
113
+ index: Optional[int] = None,
114
+ *,
115
+ conn_url: Optional[str] = None,
116
+ is_async: Literal[True],
117
+ ) -> Coroutine[Any, Any, Any]:
118
+ pass
119
+
120
+
121
+ def dm_state(
122
+ operation_id: str,
123
+ run_id: str,
124
+ bind_id: str,
125
+ key: Optional[str] = None,
126
+ index: Optional[int] = None,
127
+ *,
128
+ conn_url: Optional[str] = None,
129
+ is_async: bool = False,
130
+ ) -> Union[Any, Coroutine[Any, Any, Any]]:
131
+ if is_async:
132
+ return f.dm_state_async(operation_id, run_id, bind_id, key, index, conn_url=conn_url)
133
+ return f.dm_state(operation_id, run_id, bind_id, key, index, conn_url=conn_url)
134
+
135
+
136
+ @overload
137
+ def dm_journal_list(
138
+ operation_id: str,
139
+ run_id: str,
140
+ *,
141
+ conn_url: Optional[str] = None,
142
+ is_async: Literal[False] = False,
143
+ ) -> List[str]:
144
+ pass
145
+
146
+
147
+ @overload
148
+ def dm_journal_list(
149
+ operation_id: str,
150
+ run_id: str,
151
+ *,
152
+ conn_url: Optional[str] = None,
153
+ is_async: Literal[True],
154
+ ) -> Coroutine[Any, Any, List[str]]:
155
+ pass
156
+
157
+
158
+ def dm_journal_list(
159
+ operation_id: str,
160
+ run_id: str,
161
+ *,
162
+ conn_url: Optional[str] = None,
163
+ is_async: bool = False,
164
+ ) -> Union[List[str], Coroutine[Any, Any, List[str]]]:
165
+ if is_async:
166
+ return f.dm_journal_list_async(operation_id, run_id, conn_url=conn_url)
167
+ return f.dm_journal_list(operation_id, run_id, conn_url=conn_url)
168
+
169
+
170
+ @overload
171
+ def dm_journal(
172
+ operation_id: str,
173
+ run_id: str,
174
+ key: str,
175
+ is_stream: Literal[False] = False,
176
+ *,
177
+ conn_url: Optional[str] = None,
178
+ is_async: Literal[False] = False,
179
+ ) -> Any:
180
+ pass
181
+
182
+
183
+ @overload
184
+ def dm_journal(
185
+ operation_id: str,
186
+ run_id: str,
187
+ key: str,
188
+ is_stream: Literal[False] = False,
189
+ *,
190
+ conn_url: Optional[str] = None,
191
+ is_async: Literal[True],
192
+ ) -> Coroutine[Any, Any, Any]:
193
+ pass
194
+
195
+
196
+ @overload
197
+ def dm_journal(
198
+ operation_id: str,
199
+ run_id: str,
200
+ key: str,
201
+ is_stream: Literal[True],
202
+ *,
203
+ conn_url: Optional[str] = None,
204
+ is_async: Literal[False] = False,
205
+ ) -> Iterable:
206
+ pass
207
+
208
+
209
+ @overload
210
+ def dm_journal(
211
+ operation_id: str,
212
+ run_id: str,
213
+ key: str,
214
+ is_stream: Literal[True],
215
+ *,
216
+ conn_url: Optional[str] = None,
217
+ is_async: Literal[True],
218
+ ) -> Coroutine[Any, Any, AsyncIterable]:
219
+ pass
220
+
221
+
222
+ def dm_journal(
223
+ operation_id: str,
224
+ run_id: str,
225
+ key: str,
226
+ is_stream: bool = False,
227
+ *,
228
+ conn_url: Optional[str] = None,
229
+ is_async: bool = False,
230
+ ) -> Union[Any, Iterable, Coroutine[Any, Any, Union[Any, AsyncIterable]]]:
231
+ if is_async:
232
+ return f.dm_journal_async(operation_id, run_id, key, is_stream, conn_url=conn_url)
233
+ return f.dm_journal(operation_id, run_id, key, is_stream, conn_url=conn_url)
@@ -0,0 +1,162 @@
1
+ from http import HTTPStatus
2
+ from typing import Any, AsyncIterable, Iterable, List, Optional, Union
3
+
4
+ import aiohttp
5
+ import requests
6
+ from requests.models import Response
7
+
8
+ from malevich_coretools.secondary import Config
9
+ from malevich_coretools.secondary.const import * # noqa: F403
10
+
11
+
12
+ def dm_stream(operation_id: str, run_id: str, bind_id: str, conn_url: Optional[str]=None) -> Iterable:
13
+ return send_to_dm_stream(DM_STREAM(operation_id, run_id, bind_id), conn_url=conn_url)
14
+
15
+
16
+ async def dm_stream_async(operation_id: str, run_id: str, bind_id: str, conn_url: Optional[str]=None) -> AsyncIterable:
17
+ return await send_to_dm_stream_async(DM_STREAM(operation_id, run_id, bind_id), conn_url=conn_url)
18
+
19
+
20
+ def dm_continue(operation_id: str, run_id: str, id: str, data: Any, conn_url: Optional[str]=None) -> None:
21
+ return send_to_dm_post(DM_CONTINUE(operation_id, run_id, id), data, conn_url=conn_url)
22
+
23
+
24
+ async def dm_continue_async(operation_id: str, run_id: str, id: str, data: Any, conn_url: Optional[str]=None) -> None:
25
+ return await send_to_dm_post_async(DM_CONTINUE(operation_id, run_id, id), data, conn_url=conn_url)
26
+
27
+
28
+ def dm_state(operation_id: str, run_id: str, bind_id: str, key: Optional[str] = None, index: Optional[int] = None, conn_url: Optional[str]=None) -> Any:
29
+ return send_to_dm_get(DM_STATE(operation_id, run_id, bind_id, key, index), conn_url=conn_url)
30
+
31
+
32
+ async def dm_state_async(operation_id: str, run_id: str, bind_id: str, key: Optional[str] = None, index: Optional[int] = None, conn_url: Optional[str]=None) -> Any:
33
+ return await send_to_dm_get_async(DM_STATE(operation_id, run_id, bind_id, key, index), conn_url=conn_url)
34
+
35
+
36
+ def dm_journal_list(operation_id: str, run_id: str, conn_url: Optional[str]=None) -> List[str]:
37
+ return send_to_dm_get(DM_JOURNAL_LIST(operation_id, run_id), is_text=False, conn_url=conn_url)
38
+
39
+
40
+ async def dm_journal_list_async(operation_id: str, run_id: str, conn_url: Optional[str]=None) -> List[str]:
41
+ return await send_to_dm_get_async(DM_JOURNAL_LIST(operation_id, run_id), is_text=False, conn_url=conn_url)
42
+
43
+
44
+ def dm_journal(operation_id: str, run_id: str, key: str, is_stream: bool, conn_url: Optional[str]=None) -> Union[Any, Iterable]:
45
+ if is_stream:
46
+ return send_to_dm_stream(DM_JOURNAL(operation_id, run_id, key, is_stream), conn_url=conn_url)
47
+ return send_to_dm_get(DM_JOURNAL(operation_id, run_id, key, is_stream), conn_url=conn_url)
48
+
49
+
50
+ async def dm_journal_async(operation_id: str, run_id: str, key: str, is_stream: bool, conn_url: Optional[str]=None) -> Union[Any, AsyncIterable]:
51
+ if is_stream:
52
+ return await send_to_dm_stream_async(DM_JOURNAL(operation_id, run_id, key, is_stream), conn_url=conn_url)
53
+ return await send_to_dm_get_async(DM_JOURNAL(operation_id, run_id, key, is_stream), conn_url=conn_url)
54
+
55
+
56
+ #
57
+
58
+ def __check_response(path: str, response: Response): # noqa: ANN202
59
+ if response.status_code >= 400:
60
+ text = response.text
61
+ msg = f"failed: {text}" if len(text) > 0 else "failed"
62
+ Config.logger.error(f"{path} {msg}")
63
+
64
+ if response.reason is not None and len(response.reason) == 0:
65
+ response.reason = text
66
+ response.raise_for_status()
67
+
68
+
69
+ async def __async_check_response(response: aiohttp.ClientResponse, path: Optional[str] = None): # noqa: ANN202
70
+ if not response.ok:
71
+ text = await response.text()
72
+ if path is not None:
73
+ msg = f"failed: {text}" if len(text) > 0 else "failed"
74
+ Config.logger.error(f"{path} {msg}")
75
+ else:
76
+ Config.logger.error(text)
77
+
78
+ if response.reason is not None and len(response.reason) == 0:
79
+ response.reason = text
80
+ response.raise_for_status()
81
+
82
+
83
+ def send_to_dm_get(path: str, is_text: bool=True, conn_url: Optional[str]=None) -> Optional[Union[str, bytes]]:
84
+ host = Config.DM_HOST_PORT if conn_url is None else conn_url
85
+ assert host is not None, "dm host port not set"
86
+ response = requests.get(f"{host}{path}", headers=HEADERS)
87
+ __check_response(f"{host}{path}", response)
88
+ if response.status_code == HTTPStatus.NO_CONTENT:
89
+ return None
90
+ if is_text is True:
91
+ return response.text
92
+ elif is_text is False:
93
+ return response.json()
94
+ else:
95
+ return response.content
96
+
97
+
98
+ async def send_to_dm_get_async(path: str, is_text: bool=True, conn_url: Optional[str]=None, async_session = None) -> Optional[Union[str, bytes]]:
99
+ host = Config.DM_HOST_PORT if conn_url is None else conn_url
100
+ assert host is not None, "dm host port not set"
101
+ async with async_session or aiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False), timeout=aiohttp.ClientTimeout(total=None)) as session:
102
+ async with session.get(f"{host}{path}", headers=HEADERS) as response:
103
+ await __async_check_response(response, f"{host}{path}")
104
+ if response.status == HTTPStatus.NO_CONTENT:
105
+ return None
106
+ if is_text is True:
107
+ return await response.text()
108
+ elif is_text is False:
109
+ return await response.json()
110
+ else:
111
+ return await response.read()
112
+
113
+
114
+ def send_to_dm_post(path: str, operation: Optional[Any] = None, conn_url: Optional[str]=None) -> Optional[str]: # noqa: ANN401
115
+ host = Config.DM_HOST_PORT if conn_url is None else conn_url
116
+ assert host is not None, "dm host port not set"
117
+ response = requests.post(f"{host}{path}", data=operation, headers=HEADERS)
118
+ __check_response(f"{host}{path}", response)
119
+ if response.status_code == HTTPStatus.NO_CONTENT:
120
+ return None
121
+ return response.text
122
+
123
+
124
+ async def send_to_dm_post_async(path: str, operation: Optional[Any] = None, conn_url: Optional[str]=None, async_session=None) -> str: # noqa: ANN401
125
+ host = Config.DM_HOST_PORT if conn_url is None else conn_url
126
+ assert host is not None, "dm host port not set"
127
+ async with async_session or aiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False), timeout=aiohttp.ClientTimeout(total=None)) as session:
128
+ async with session.post(f"{host}{path}", data=operation, headers=HEADERS) as response:
129
+ await __async_check_response(response, f"{host}{path}")
130
+ if response.status == HTTPStatus.NO_CONTENT:
131
+ return None
132
+ return response.text()
133
+
134
+
135
+ def send_to_dm_stream(path: str, conn_url: Optional[str]=None) -> Iterable:
136
+ host = Config.DM_HOST_PORT if conn_url is None else conn_url
137
+ assert host is not None, "dm host port not set"
138
+
139
+ def stream_generator() -> None:
140
+ with requests.get(f"{host}{path}", headers=HEADERS, stream=True) as response:
141
+ __check_response(f"{host}{path}", response)
142
+ if response.status_code == HTTPStatus.NO_CONTENT:
143
+ return
144
+ for chunk in response.iter_content(chunk_size=4096):
145
+ if chunk:
146
+ yield chunk.decode("utf-8", errors="ignore")
147
+ return stream_generator()
148
+
149
+
150
+ async def send_to_dm_stream_async(path: str, conn_url: Optional[str]=None, async_session = None) -> AsyncIterable:
151
+ host = Config.DM_HOST_PORT if conn_url is None else conn_url
152
+ assert host is not None, "dm host port not set"
153
+
154
+ async def stream_generator() -> None:
155
+ async with async_session or aiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False), timeout=aiohttp.ClientTimeout(total=None)) as session:
156
+ async with session.get(f"{host}{path}", headers=HEADERS) as response:
157
+ await __async_check_response(response, f"{host}{path}")
158
+ if response.status == HTTPStatus.NO_CONTENT:
159
+ return
160
+ async for chunk in response.content.iter_any():
161
+ yield chunk.decode("utf-8", errors="ignore")
162
+ return stream_generator()
@@ -531,6 +531,39 @@ def get_ping(*args, **kwargs) -> Alias.Info:
531
531
  async def get_ping_async(*args, **kwargs) -> Alias.Info:
532
532
  return await send_to_core_get_async(PING, *args, **kwargs, is_text=True)
533
533
 
534
+
535
+ def get_secret_keys(*args, **kwargs) -> ResultNames:
536
+ return model_from_json(send_to_core_get(SECRET_KEYS_MAIN, *args, **kwargs), ResultNames)
537
+
538
+
539
+ async def get_secret_keys_async(*args, **kwargs) -> ResultNames:
540
+ return model_from_json(await send_to_core_get_async(SECRET_KEYS_MAIN, *args, **kwargs), ResultNames)
541
+
542
+
543
+ def post_secret_keys_name(name: str, wait: bool, *args, **kwargs) -> Alias.Info:
544
+ return send_to_core_modify(SECRET_KEYS_NAME(name, wait), *args, **kwargs)
545
+
546
+
547
+ async def post_secret_keys_name_async(name: str, wait: bool, *args, **kwargs) -> Alias.Info:
548
+ return await send_to_core_modify_async(SECRET_KEYS_NAME(name, wait), *args, **kwargs)
549
+
550
+
551
+ def delete_secret_keys_name(name: str, wait: bool, *args, **kwargs) -> Alias.Info:
552
+ return send_to_core_modify(SECRET_KEYS_NAME(name, wait), *args, **kwargs, is_post=False)
553
+
554
+
555
+ async def delete_secret_keys_name_async(name: str, wait: bool, *args, **kwargs) -> Alias.Info:
556
+ return await send_to_core_modify_async(SECRET_KEYS_NAME(name, wait), *args, **kwargs, is_post=False)
557
+
558
+
559
+ def delete_secret_keys(wait: bool, *args, **kwargs) -> Alias.Info:
560
+ return send_to_core_modify(SECRET_KEYS_ALL(wait), *args, **kwargs, is_post=False)
561
+
562
+
563
+ async def delete_secret_keys_async(wait: bool, *args, **kwargs) -> Alias.Info:
564
+ return await send_to_core_modify_async(SECRET_KEYS_ALL(wait), *args, **kwargs, is_post=False)
565
+
566
+
534
567
  # UserShareController
535
568
 
536
569
 
@@ -681,6 +714,47 @@ async def delete_register_login_async(login: str, wait: bool, *args, **kwargs) -
681
714
  Config.logger.info(info)
682
715
  return info
683
716
 
717
+
718
+ def get_register_keys(*args, **kwargs) -> Keys:
719
+ return model_from_json(send_to_core_get(REGISTER_KEYS(None), *args, **kwargs), Keys)
720
+
721
+
722
+ async def get_register_keys_async(*args, **kwargs) -> Keys:
723
+ return model_from_json(await send_to_core_get_async(REGISTER_KEYS(None), *args, **kwargs), Keys)
724
+
725
+
726
+ def get_register_keys_name(name: str, *args, **kwargs) -> str:
727
+ return send_to_core_get(REGISTER_KEYS_NAME(name, None), *args, **kwargs, is_text=True)
728
+
729
+
730
+ async def get_register_keys_name_async(name: str, *args, **kwargs) -> str:
731
+ return await send_to_core_get_async(REGISTER_KEYS_NAME(name, None), *args, **kwargs, is_text=True)
732
+
733
+
734
+ def post_register_keys(data: Keys, wait: bool, *args, **kwargs) -> Alias.Info:
735
+ return send_to_core_modify(REGISTER_KEYS(wait), data, *args, **kwargs)
736
+
737
+
738
+ async def post_register_keys_async(data: Keys, wait: bool, *args, **kwargs) -> Alias.Info:
739
+ return await send_to_core_modify_async(REGISTER_KEYS(wait), data, *args, **kwargs)
740
+
741
+
742
+ def delete_register_keys_name(name: str, wait: bool, *args, **kwargs) -> Alias.Info:
743
+ return send_to_core_modify(REGISTER_KEYS_NAME(name, wait), *args, **kwargs, is_post=False)
744
+
745
+
746
+ async def delete_register_keys_name_async(name: str, wait: bool, *args, **kwargs) -> Alias.Info:
747
+ return await send_to_core_modify_async(REGISTER_KEYS_NAME(name, wait), *args, **kwargs, is_post=False)
748
+
749
+
750
+ def delete_register_keys(wait: bool, *args, **kwargs) -> Alias.Info:
751
+ return send_to_core_modify(REGISTER_KEYS(wait), *args, **kwargs, is_post=False)
752
+
753
+
754
+ async def delete_register_keys_async(wait: bool, *args, **kwargs) -> Alias.Info:
755
+ return await send_to_core_modify_async(REGISTER_KEYS(wait), *args, **kwargs, is_post=False)
756
+
757
+
684
758
  # UserAppsController
685
759
 
686
760
 
@@ -8,6 +8,7 @@ class Config:
8
8
  TOKEN = os.environ.get("GITLAB_ACCESS_TOKEN") # FIXME
9
9
 
10
10
  HOST_PORT = None
11
+ DM_HOST_PORT = None
11
12
  KAFKA_HOST_PORT = None
12
13
  CORE_USERNAME = None
13
14
  CORE_PASSWORD = None
@@ -97,6 +97,9 @@ PING = "ping"
97
97
  # MAPPING = lambda wait: with_wait(f"{COMMON_MAIN}/mapping", wait)
98
98
  # MAPPING_ID = lambda id, wait: with_wait(f"{COMMON_MAIN}/mapping/{urllib.parse.quote(str(id), safe='')}", wait)
99
99
  # COMMON_ALL = lambda wait: with_wait(f"{COMMON_MAIN}/all", wait)
100
+ SECRET_KEYS_MAIN = f"{API_VERSION}/secretKeys"
101
+ SECRET_KEYS_NAME = lambda name, wait: with_wait(f"{SECRET_KEYS_MAIN}/name/{urllib.parse.quote(str(name), safe='')}", wait)
102
+ SECRET_KEYS_ALL = lambda wait: with_wait(f"{SECRET_KEYS_MAIN}/all", wait)
100
103
 
101
104
  ## UserShareController
102
105
  SHARE_MAIN = f"{API_VERSION}/share"
@@ -112,6 +115,8 @@ REGISTER_MAIN = f"{API_VERSION}/register"
112
115
  REGISTER = REGISTER_MAIN
113
116
  REGISTER_LOGIN = lambda login, wait: with_wait(f"{REGISTER_MAIN}/login/{urllib.parse.quote(str(login), safe='')}", wait)
114
117
  REGISTER_ALL = f"{REGISTER_MAIN}/all"
118
+ REGISTER_KEYS = lambda wait: with_wait(f"{REGISTER_MAIN}/keys", wait)
119
+ REGISTER_KEYS_NAME = lambda name, wait: with_wait(f"{REGISTER_MAIN}/keys/{urllib.parse.quote(str(name), safe='')}", wait)
115
120
 
116
121
  ## UserAppsController
117
122
  USER_APPS_MAIN = f"{API_VERSION}/userApps"
@@ -239,3 +244,10 @@ KAFKA_SEND = f"{MANAGER_MAIN}/kafkaMsg"
239
244
  ## BatchController
240
245
  BATCH_MAIN = f"{API_VERSION}/batch"
241
246
  BATCH = BATCH_MAIN
247
+
248
+ ##### DM
249
+ DM_STREAM = lambda operationId, runId, bindId : f"stream/{operationId}/{runId}/{bindId}"
250
+ DM_CONTINUE = lambda operationId, runId, id: f"continue/{operationId}/{runId}/{id}"
251
+ DM_STATE = lambda operationId, runId, bindId, key, index : with_key_values(f"state/{operationId}/{runId}/{bindId}", {"key": key, "index": index})
252
+ DM_JOURNAL_LIST = lambda operationId, runId : f"journal/{operationId}/{runId}"
253
+ DM_JOURNAL = lambda operationId, runId, key, stream : with_key_values(f"journal/{operationId}/{runId}/{key}", {"stream": stream})
@@ -47,15 +47,24 @@ def set_host_port(host_port: str) -> None:
47
47
  Config.HOST_PORT = host_port
48
48
 
49
49
 
50
+ def set_dm_host_port(host_port: str) -> None:
51
+ """update host and port for malevich-dm, example: `http://localhost:8000/` """
52
+ assert len(host_port) > 0, "empty host port"
53
+ host_port = host_port if host_port[-1] == "/" else f"{host_port}/"
54
+ Config.DM_HOST_PORT = host_port
55
+
56
+
50
57
  def set_kafka_host_port(host_port: str) -> None:
51
58
  """update kafka host and port for malevich-kafka, example: `localhost:9092` """
52
59
  assert len(host_port) > 0, "empty host port"
53
60
  Config.KAFKA_HOST_PORT = host_port
54
61
 
55
62
 
56
- def set_conn_url(conn_url: str) -> None:
63
+ def set_conn_url(conn_url: str, dm_url: Optional[str] = None) -> None:
57
64
  """analogue set_host_port; update `conn_url` for malevich-core, example: `http://localhost:8080/` """
58
65
  set_host_port(conn_url)
66
+ if dm_url is not None:
67
+ set_dm_host_port(dm_url)
59
68
 
60
69
 
61
70
  def set_verbose(verbose: bool) -> None:
@@ -3124,6 +3133,202 @@ def ping(
3124
3133
  return f.get_ping_async(with_auth=False, conn_url=conn_url)
3125
3134
  return f.get_ping(with_auth=False, conn_url=conn_url)
3126
3135
 
3136
+
3137
+ @overload
3138
+ def get_secret_keys(
3139
+ *,
3140
+ auth: Optional[AUTH] = None,
3141
+ conn_url: Optional[str] = None,
3142
+ batcher: Optional[Batcher] = None,
3143
+ is_async: Literal[False] = False,
3144
+ ) -> Coroutine[Any, Any, ResultNames]:
3145
+ pass
3146
+
3147
+
3148
+ @overload
3149
+ def get_secret_keys(
3150
+ *,
3151
+ auth: Optional[AUTH] = None,
3152
+ conn_url: Optional[str] = None,
3153
+ batcher: Optional[Batcher] = None,
3154
+ is_async: Literal[False] = False,
3155
+ ) -> ResultNames:
3156
+ pass
3157
+
3158
+
3159
+ def get_secret_keys(
3160
+ *,
3161
+ auth: Optional[AUTH] = None,
3162
+ conn_url: Optional[str] = None,
3163
+ batcher: Optional[Batcher] = None,
3164
+ is_async: bool = False,
3165
+ ) -> Union[ResultNames, Coroutine[Any, Any, ResultNames]]:
3166
+ if batcher is None:
3167
+ batcher = Config.BATCHER
3168
+ if batcher is not None:
3169
+ return batcher.add("getSecretKeys", result_model=ResultNames)
3170
+ if is_async:
3171
+ return f.get_secret_keys_async(auth=auth, conn_url=conn_url)
3172
+ return f.get_secret_keys(auth=auth, conn_url=conn_url)
3173
+
3174
+
3175
+ @overload
3176
+ def create_secret_key(
3177
+ name: str,
3178
+ wait: bool = True,
3179
+ *,
3180
+ auth: Optional[AUTH] = None,
3181
+ conn_url: Optional[str] = None,
3182
+ batcher: Optional[Batcher] = None,
3183
+ is_async: Literal[False] = False,
3184
+ ) -> Alias.Info:
3185
+ pass
3186
+
3187
+
3188
+ @overload
3189
+ def create_secret_key(
3190
+ name: str,
3191
+ wait: bool = True,
3192
+ *,
3193
+ auth: Optional[AUTH] = None,
3194
+ conn_url: Optional[str] = None,
3195
+ batcher: Optional[Batcher] = None,
3196
+ is_async: Literal[True],
3197
+ ) -> Coroutine[Any, Any, Alias.Info]:
3198
+ pass
3199
+
3200
+
3201
+ def create_secret_key(
3202
+ name: str,
3203
+ wait: bool = True,
3204
+ *,
3205
+ auth: Optional[AUTH] = None,
3206
+ conn_url: Optional[str] = None,
3207
+ batcher: Optional[Batcher] = None,
3208
+ is_async: bool = False,
3209
+ ) -> Union[Alias.Info, Coroutine[Any, Any, Alias.Info]]:
3210
+ if batcher is None:
3211
+ batcher = Config.BATCHER
3212
+ if batcher is not None:
3213
+ return batcher.add("postSecretKeysByName", vars={"name": name})
3214
+ if is_async:
3215
+ return f.post_secret_keys_name_async(
3216
+ name,
3217
+ wait=wait,
3218
+ auth=auth,
3219
+ conn_url=conn_url,
3220
+ )
3221
+ return f.post_secret_keys_name(
3222
+ name,
3223
+ wait=wait,
3224
+ auth=auth,
3225
+ conn_url=conn_url,
3226
+ )
3227
+
3228
+
3229
+ @overload
3230
+ def delete_secret_key(
3231
+ name: str,
3232
+ wait: bool = True,
3233
+ *,
3234
+ auth: Optional[AUTH] = None,
3235
+ conn_url: Optional[str] = None,
3236
+ batcher: Optional[Batcher] = None,
3237
+ is_async: Literal[False] = False,
3238
+ ) -> Alias.Info:
3239
+ pass
3240
+
3241
+
3242
+ @overload
3243
+ def delete_secret_key(
3244
+ name: str,
3245
+ wait: bool = True,
3246
+ *,
3247
+ auth: Optional[AUTH] = None,
3248
+ conn_url: Optional[str] = None,
3249
+ batcher: Optional[Batcher] = None,
3250
+ is_async: Literal[True],
3251
+ ) -> Coroutine[Any, Any, Alias.Info]:
3252
+ pass
3253
+
3254
+
3255
+ def delete_secret_key(
3256
+ name: str,
3257
+ wait: bool = True,
3258
+ *,
3259
+ auth: Optional[AUTH] = None,
3260
+ conn_url: Optional[str] = None,
3261
+ batcher: Optional[Batcher] = None,
3262
+ is_async: bool = False,
3263
+ ) -> Union[Alias.Info, Coroutine[Any, Any, Alias.Info]]:
3264
+ if batcher is None:
3265
+ batcher = Config.BATCHER
3266
+ if batcher is not None:
3267
+ return batcher.add("deleteSecretKeysByName", vars={"name": name})
3268
+ if is_async:
3269
+ return f.delete_secret_keys_name_async(
3270
+ name,
3271
+ wait=wait,
3272
+ auth=auth,
3273
+ conn_url=conn_url,
3274
+ )
3275
+ return f.delete_secret_keys_name(
3276
+ name,
3277
+ wait=wait,
3278
+ auth=auth,
3279
+ conn_url=conn_url,
3280
+ )
3281
+
3282
+
3283
+ @overload
3284
+ def delete_secret_keys(
3285
+ wait: bool = True,
3286
+ *,
3287
+ auth: Optional[AUTH] = None,
3288
+ conn_url: Optional[str] = None,
3289
+ batcher: Optional[Batcher] = None,
3290
+ is_async: Literal[False] = False,
3291
+ ) -> Alias.Info:
3292
+ pass
3293
+
3294
+
3295
+ @overload
3296
+ def delete_secret_keys(
3297
+ wait: bool = True,
3298
+ *,
3299
+ auth: Optional[AUTH] = None,
3300
+ conn_url: Optional[str] = None,
3301
+ batcher: Optional[Batcher] = None,
3302
+ is_async: Literal[True],
3303
+ ) -> Coroutine[Any, Any, Alias.Info]:
3304
+ pass
3305
+
3306
+
3307
+ def delete_secret_keys(
3308
+ wait: bool = True,
3309
+ *,
3310
+ auth: Optional[AUTH] = None,
3311
+ conn_url: Optional[str] = None,
3312
+ batcher: Optional[Batcher] = None,
3313
+ is_async: bool = False,
3314
+ ) -> Union[Alias.Info, Coroutine[Any, Any, Alias.Info]]:
3315
+ if batcher is None:
3316
+ batcher = Config.BATCHER
3317
+ if batcher is not None:
3318
+ return batcher.add("deleteSecretKeys")
3319
+ if is_async:
3320
+ return f.delete_secret_keys_async(
3321
+ wait=wait,
3322
+ auth=auth,
3323
+ conn_url=conn_url,
3324
+ )
3325
+ return f.delete_secret_keys(
3326
+ wait=wait,
3327
+ auth=auth,
3328
+ conn_url=conn_url,
3329
+ )
3330
+
3331
+
3127
3332
  # UserShare
3128
3333
 
3129
3334
 
@@ -3882,6 +4087,243 @@ def delete_user(
3882
4087
  return f.delete_register(auth=auth, conn_url=conn_url)
3883
4088
 
3884
4089
 
4090
+ @overload
4091
+ def get_user_keys(
4092
+ *,
4093
+ auth: Optional[AUTH] = None,
4094
+ conn_url: Optional[str] = None,
4095
+ batcher: Optional[Batcher] = None,
4096
+ is_async: Literal[False] = False,
4097
+ ) -> Keys:
4098
+ pass
4099
+
4100
+
4101
+ @overload
4102
+ def get_user_keys(
4103
+ *,
4104
+ auth: Optional[AUTH] = None,
4105
+ conn_url: Optional[str] = None,
4106
+ batcher: Optional[Batcher] = None,
4107
+ is_async: Literal[True],
4108
+ ) -> Coroutine[Any, Any, Keys]:
4109
+ pass
4110
+
4111
+
4112
+ def get_user_keys(
4113
+ *,
4114
+ auth: Optional[AUTH] = None,
4115
+ conn_url: Optional[str] = None,
4116
+ batcher: Optional[Batcher] = None,
4117
+ is_async: bool = False,
4118
+ ) -> Union[Keys, Coroutine[Any, Any, Keys]]:
4119
+ if batcher is None:
4120
+ batcher = Config.BATCHER
4121
+ if batcher is not None:
4122
+ return batcher.add("getKeys", result_model=Keys)
4123
+ if is_async:
4124
+ return f.get_register_keys_async(auth=auth, conn_url=conn_url)
4125
+ return f.get_register_keys(auth=auth, conn_url=conn_url)
4126
+
4127
+
4128
+ @overload
4129
+ def get_user_key(
4130
+ name: str,
4131
+ *,
4132
+ auth: Optional[AUTH] = None,
4133
+ conn_url: Optional[str] = None,
4134
+ batcher: Optional[Batcher] = None,
4135
+ is_async: Literal[False] = False,
4136
+ ) -> str:
4137
+ pass
4138
+
4139
+
4140
+ @overload
4141
+ def get_user_key(
4142
+ name: str,
4143
+ *,
4144
+ auth: Optional[AUTH] = None,
4145
+ conn_url: Optional[str] = None,
4146
+ batcher: Optional[Batcher] = None,
4147
+ is_async: Literal[True],
4148
+ ) -> Coroutine[Any, Any, str]:
4149
+ pass
4150
+
4151
+
4152
+ def get_user_key(
4153
+ name: str,
4154
+ *,
4155
+ auth: Optional[AUTH] = None,
4156
+ conn_url: Optional[str] = None,
4157
+ batcher: Optional[Batcher] = None,
4158
+ is_async: bool = False,
4159
+ ) -> Union[str, Coroutine[Any, Any, str]]:
4160
+ if batcher is None:
4161
+ batcher = Config.BATCHER
4162
+ if batcher is not None:
4163
+ return batcher.add("getKeysByName", vars={"name": name})
4164
+ if is_async:
4165
+ return f.get_register_keys_name_async(name, auth=auth, conn_url=conn_url)
4166
+ return f.get_register_keys_name(name, auth=auth, conn_url=conn_url)
4167
+
4168
+
4169
+ @overload
4170
+ def update_user_keys(
4171
+ keys: Dict[str, str],
4172
+ wait: bool = True,
4173
+ *,
4174
+ auth: Optional[AUTH] = None,
4175
+ conn_url: Optional[str] = None,
4176
+ batcher: Optional[Batcher] = None,
4177
+ is_async: Literal[False] = False,
4178
+ ) -> Alias.Info:
4179
+ pass
4180
+
4181
+
4182
+ @overload
4183
+ def update_user_keys(
4184
+ keys: Dict[str, str],
4185
+ wait: bool = True,
4186
+ *,
4187
+ auth: Optional[AUTH] = None,
4188
+ conn_url: Optional[str] = None,
4189
+ batcher: Optional[Batcher] = None,
4190
+ is_async: Literal[True],
4191
+ ) -> Coroutine[Any, Any, Alias.Info]:
4192
+ pass
4193
+
4194
+
4195
+ def update_user_keys(
4196
+ keys: Dict[str, str],
4197
+ wait: bool = True,
4198
+ *,
4199
+ auth: Optional[AUTH] = None,
4200
+ conn_url: Optional[str] = None,
4201
+ batcher: Optional[Batcher] = None,
4202
+ is_async: bool = False,
4203
+ ) -> Union[Alias.Info, Coroutine[Any, Any, Alias.Info]]:
4204
+ if batcher is None:
4205
+ batcher = Config.BATCHER
4206
+ data = Keys(data=keys)
4207
+ if batcher is not None:
4208
+ return batcher.add("postKeys", data=data)
4209
+ if is_async:
4210
+ return f.post_register_keys_async(
4211
+ data,
4212
+ wait=wait,
4213
+ auth=auth,
4214
+ conn_url=conn_url,
4215
+ )
4216
+ return f.post_register_keys(
4217
+ data,
4218
+ wait=wait,
4219
+ auth=auth,
4220
+ conn_url=conn_url,
4221
+ )
4222
+
4223
+
4224
+ @overload
4225
+ def delete_user_key(
4226
+ name: str,
4227
+ wait: bool = True,
4228
+ *,
4229
+ auth: Optional[AUTH] = None,
4230
+ conn_url: Optional[str] = None,
4231
+ batcher: Optional[Batcher] = None,
4232
+ is_async: Literal[False] = False,
4233
+ ) -> Alias.Info:
4234
+ pass
4235
+
4236
+
4237
+ @overload
4238
+ def delete_user_key(
4239
+ name: str,
4240
+ wait: bool = True,
4241
+ *,
4242
+ auth: Optional[AUTH] = None,
4243
+ conn_url: Optional[str] = None,
4244
+ batcher: Optional[Batcher] = None,
4245
+ is_async: Literal[True],
4246
+ ) -> Coroutine[Any, Any, Alias.Info]:
4247
+ pass
4248
+
4249
+
4250
+ def delete_user_key(
4251
+ name: str,
4252
+ wait: bool = True,
4253
+ *,
4254
+ auth: Optional[AUTH] = None,
4255
+ conn_url: Optional[str] = None,
4256
+ batcher: Optional[Batcher] = None,
4257
+ is_async: bool = False,
4258
+ ) -> Union[Alias.Info, Coroutine[Any, Any, Alias.Info]]:
4259
+ if batcher is None:
4260
+ batcher = Config.BATCHER
4261
+ if batcher is not None:
4262
+ return batcher.add("deleteKeysByName", vars={"name": name})
4263
+ if is_async:
4264
+ return f.delete_register_keys_name_async(
4265
+ name,
4266
+ wait=wait,
4267
+ auth=auth,
4268
+ conn_url=conn_url,
4269
+ )
4270
+ return f.delete_register_keys_name(
4271
+ name,
4272
+ wait=wait,
4273
+ auth=auth,
4274
+ conn_url=conn_url,
4275
+ )
4276
+
4277
+
4278
+ @overload
4279
+ def delete_user_keys(
4280
+ wait: bool = True,
4281
+ *,
4282
+ auth: Optional[AUTH] = None,
4283
+ conn_url: Optional[str] = None,
4284
+ batcher: Optional[Batcher] = None,
4285
+ is_async: Literal[False] = False,
4286
+ ) -> Alias.Info:
4287
+ pass
4288
+
4289
+
4290
+ @overload
4291
+ def delete_user_keys(
4292
+ wait: bool = True,
4293
+ *,
4294
+ auth: Optional[AUTH] = None,
4295
+ conn_url: Optional[str] = None,
4296
+ batcher: Optional[Batcher] = None,
4297
+ is_async: Literal[True],
4298
+ ) -> Coroutine[Any, Any, Alias.Info]:
4299
+ pass
4300
+
4301
+
4302
+ def delete_user_keys(
4303
+ wait: bool = True,
4304
+ *,
4305
+ auth: Optional[AUTH] = None,
4306
+ conn_url: Optional[str] = None,
4307
+ batcher: Optional[Batcher] = None,
4308
+ is_async: bool = False,
4309
+ ) -> Union[Alias.Info, Coroutine[Any, Any, Alias.Info]]:
4310
+ if batcher is None:
4311
+ batcher = Config.BATCHER
4312
+ if batcher is not None:
4313
+ return batcher.add("deleteKeys")
4314
+ if is_async:
4315
+ return f.delete_register_keys_async(
4316
+ wait=wait,
4317
+ auth=auth,
4318
+ conn_url=conn_url,
4319
+ )
4320
+ return f.delete_register_keys(
4321
+ wait=wait,
4322
+ auth=auth,
4323
+ conn_url=conn_url,
4324
+ )
4325
+
4326
+
3885
4327
  # UserApps
3886
4328
 
3887
4329
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: malevich-coretools
3
- Version: 0.3.67
3
+ Version: 0.3.69
4
4
  Author: Andrew Pogrebnoj
5
5
  Author-email: andrew@onjulius.co
6
6
  License-File: LICENSE
@@ -1,9 +1,10 @@
1
- malevich_coretools/__init__.py,sha256=DJtPESxkCZD2SbTZTrR_x0TKDQ4MJpmBqGw5YpKYidM,134
2
- malevich_coretools/utils.py,sha256=o_uH_HJKs4od0ExFmG4LMwZ1pH4V6_90QYxn_sgVyC8,276863
1
+ malevich_coretools/__init__.py,sha256=0WUBUhATgnU3tctwv0AxzvRr0zRlW6V5INQljBCLRzo,172
2
+ malevich_coretools/dm_utils.py,sha256=WvjtqVaAiwahej-oMnB5JJKFiAcTRiyNStDu0WpifHs,4775
3
+ malevich_coretools/utils.py,sha256=7YuOpRQ6uV78EnkIiTyVvcj81cIzq8fv529YuImPg98,287286
3
4
  malevich_coretools/abstract/__init__.py,sha256=6vQ08c8HPYyT_pPkKlc-EwQKE8xG3HTEo2p_GiI5rik,142
4
- malevich_coretools/abstract/abstract.py,sha256=SSmGmn2U4hBV3-e1Fxi1SsfgddB4TTE4_VFRR6VMP7g,17732
5
+ malevich_coretools/abstract/abstract.py,sha256=nkCCC12CTYR5UNJOZzSbUYieRGPhJSsn5KjlJ8MVbrs,17835
5
6
  malevich_coretools/abstract/operations.py,sha256=cWlo2xzW-rzkTInzpDjBYeL68KfLYqSpZJRzCQ4OzjA,3070
6
- malevich_coretools/abstract/pipeline.py,sha256=yjeDaU-i2yNqnQTSwe9Kdv44dzf-p5AWk_qXxvoYvhM,7530
7
+ malevich_coretools/abstract/pipeline.py,sha256=gwVaPZAiV75OCti4wKNusbY8E2XzWyWnh1tngRnH7xk,7664
7
8
  malevich_coretools/abstract/statuses.py,sha256=9ISSw_evsylBshLXoU44TCoFOrZm4bXIxyAFFDqdUWc,333
8
9
  malevich_coretools/admin/__init__.py,sha256=zdIcHs3T_NZ8HYWts-O7OpBEWHIu779QDZMGF5HRCLg,35
9
10
  malevich_coretools/admin/utils.py,sha256=mGu-zge5FHW2Z2TDhE3YOhOlw2x8NA2CV_XKsY-g4nE,10378
@@ -11,18 +12,19 @@ malevich_coretools/batch/__init__.py,sha256=taxyZl8YOZd2EBd3leN6slzMkejUtjQ64Na3
11
12
  malevich_coretools/batch/utils.py,sha256=FRmCYU-zr-RjgT1Mo3CUNcB2mW1t_gKCJazcMx6aIW4,7719
12
13
  malevich_coretools/funcs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
14
  malevich_coretools/funcs/checks.py,sha256=Q5pRtRevQrGv_-SMbn2GgYnulhclDLBXdRtbw2QOYKU,223
14
- malevich_coretools/funcs/funcs.py,sha256=JcRnt-wiOBOz-xt463Jv5ma8DmXXnR3R_5ALXWZAoZY,85988
15
+ malevich_coretools/funcs/dm_funcs.py,sha256=Z0oSzMb9x6N2yANbIICz6erF9fJ5drg3Zheh-_VTPx4,7812
16
+ malevich_coretools/funcs/funcs.py,sha256=A0h1iZYYzIZBKIBy1dvozezY3lzyNkXXkOdgA8t2kt0,89066
15
17
  malevich_coretools/funcs/helpers.py,sha256=nYbUdtAuSSa9VMr7Oy2y0yvEMLv9EI1jzGq6eynuNLU,13573
16
18
  malevich_coretools/secondary/__init__.py,sha256=048HqvG36_1WdDVZK_RuECmaf14Iq2fviUysG1inlaE,78
17
- malevich_coretools/secondary/config.py,sha256=hRlSJuPQnhKyt1wmOAJX_XmcliaO0fPGbW94AE_Mazs,463
18
- malevich_coretools/secondary/const.py,sha256=rZ8d2tmBmiDEk5zhLKMe6mZRnwMvFrquJeK0RlTNzWw,15386
19
+ malevich_coretools/secondary/config.py,sha256=cjqKiWLm6m1kArOq4DWOHaNxKT_kHP9WUyHVkYe3UeI,487
20
+ malevich_coretools/secondary/const.py,sha256=ssrzKajWNzdRsVbOLjzgVqCI2W9m31yOkgvhZNiEfFk,16360
19
21
  malevich_coretools/secondary/helpers.py,sha256=V5xNv-Rt4SNkthTcNnMtYPjiYfoHmwUR8ApU8qFmzT0,7986
20
22
  malevich_coretools/secondary/kafka_utils.py,sha256=SIUnBFyfwsquN6MAUrEkKCw-1l7979Znl7OTQSX2UKo,989
21
23
  malevich_coretools/tools/__init__.py,sha256=jDxlCa5Dr6Y43qlI7JwsRAlBkKmFeTHTEnjNUvu-0iw,46
22
24
  malevich_coretools/tools/abstract.py,sha256=B1RW1FeNHrQ6r1k-cQZ4k4noCRXkIGt-JUwVoXEDkAg,4466
23
25
  malevich_coretools/tools/vast.py,sha256=63tvy70qQV9vnK0eWytlgjBGSnfA7l3kSIDgACBbMMs,12893
24
- malevich_coretools-0.3.67.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
25
- malevich_coretools-0.3.67.dist-info/METADATA,sha256=NyxNf6rMc1Q-bscMz5eHBbtm1hhdtbfdRAjY4FHg47k,347
26
- malevich_coretools-0.3.67.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- malevich_coretools-0.3.67.dist-info/top_level.txt,sha256=wDX3s1Tso0otBPNrFRfXqyNpm48W4Bp5v6JfbITO2Z8,19
28
- malevich_coretools-0.3.67.dist-info/RECORD,,
26
+ malevich_coretools-0.3.69.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
27
+ malevich_coretools-0.3.69.dist-info/METADATA,sha256=-cIlf5_7QM6Vm5Nar7S6fQN4QgoVj80aGOOxikwuNe4,347
28
+ malevich_coretools-0.3.69.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
29
+ malevich_coretools-0.3.69.dist-info/top_level.txt,sha256=wDX3s1Tso0otBPNrFRfXqyNpm48W4Bp5v6JfbITO2Z8,19
30
+ malevich_coretools-0.3.69.dist-info/RECORD,,