blackant-sdk 1.0.2__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.
Files changed (70) hide show
  1. blackant/__init__.py +31 -0
  2. blackant/auth/__init__.py +10 -0
  3. blackant/auth/blackant_auth.py +518 -0
  4. blackant/auth/keycloak_manager.py +363 -0
  5. blackant/auth/request_id.py +52 -0
  6. blackant/auth/role_assignment.py +443 -0
  7. blackant/auth/tokens.py +57 -0
  8. blackant/client.py +400 -0
  9. blackant/config/__init__.py +0 -0
  10. blackant/config/docker_config.py +457 -0
  11. blackant/config/keycloak_admin_config.py +107 -0
  12. blackant/docker/__init__.py +12 -0
  13. blackant/docker/builder.py +616 -0
  14. blackant/docker/client.py +983 -0
  15. blackant/docker/dao.py +462 -0
  16. blackant/docker/registry.py +172 -0
  17. blackant/exceptions.py +111 -0
  18. blackant/http/__init__.py +8 -0
  19. blackant/http/client.py +125 -0
  20. blackant/patterns/__init__.py +1 -0
  21. blackant/patterns/singleton.py +20 -0
  22. blackant/services/__init__.py +10 -0
  23. blackant/services/dao.py +414 -0
  24. blackant/services/registry.py +635 -0
  25. blackant/utils/__init__.py +8 -0
  26. blackant/utils/initialization.py +32 -0
  27. blackant/utils/logging.py +337 -0
  28. blackant/utils/request_id.py +13 -0
  29. blackant/utils/store.py +50 -0
  30. blackant_sdk-1.0.2.dist-info/METADATA +117 -0
  31. blackant_sdk-1.0.2.dist-info/RECORD +70 -0
  32. blackant_sdk-1.0.2.dist-info/WHEEL +5 -0
  33. blackant_sdk-1.0.2.dist-info/top_level.txt +5 -0
  34. calculation/__init__.py +0 -0
  35. calculation/base.py +26 -0
  36. calculation/errors.py +2 -0
  37. calculation/impl/__init__.py +0 -0
  38. calculation/impl/my_calculation.py +144 -0
  39. calculation/impl/simple_calc.py +53 -0
  40. calculation/impl/test.py +1 -0
  41. calculation/impl/test_calc.py +36 -0
  42. calculation/loader.py +227 -0
  43. notifinations/__init__.py +8 -0
  44. notifinations/mail_sender.py +212 -0
  45. storage/__init__.py +0 -0
  46. storage/errors.py +10 -0
  47. storage/factory.py +26 -0
  48. storage/interface.py +19 -0
  49. storage/minio.py +106 -0
  50. task/__init__.py +0 -0
  51. task/dao.py +38 -0
  52. task/errors.py +10 -0
  53. task/log_adapter.py +11 -0
  54. task/parsers/__init__.py +0 -0
  55. task/parsers/base.py +13 -0
  56. task/parsers/callback.py +40 -0
  57. task/parsers/cmd_args.py +52 -0
  58. task/parsers/freetext.py +19 -0
  59. task/parsers/objects.py +50 -0
  60. task/parsers/request.py +56 -0
  61. task/resource.py +84 -0
  62. task/states/__init__.py +0 -0
  63. task/states/base.py +14 -0
  64. task/states/error.py +47 -0
  65. task/states/idle.py +12 -0
  66. task/states/ready.py +51 -0
  67. task/states/running.py +21 -0
  68. task/states/set_up.py +40 -0
  69. task/states/tear_down.py +29 -0
  70. task/task.py +358 -0
@@ -0,0 +1,337 @@
1
+ # src/blackant/utils/logging.py
2
+ """BlackAnt SDK Logging module.
3
+
4
+ This module provides unified logging functionality for the entire BlackAnt SDK.
5
+ Supports colorized console output, file logging, and request tracking.
6
+ """
7
+
8
+ import logging
9
+ import sys
10
+ import threading
11
+ import re
12
+ from datetime import datetime
13
+ from pathlib import Path
14
+ from typing import Optional, Dict, Union
15
+ from colorama import Fore, Style, init
16
+
17
+ init(autoreset=True)
18
+
19
+
20
+ class CustomFormatter(logging.Formatter):
21
+ """Custom formatter with colorized log levels and abbreviated level names."""
22
+
23
+ LEVEL_ABBREVIATIONS = {
24
+ logging.DEBUG: "DBG",
25
+ logging.INFO: "INF",
26
+ logging.WARNING: "WAR",
27
+ logging.ERROR: "ERR",
28
+ logging.CRITICAL: "CRT",
29
+ }
30
+
31
+ LEVEL_COLORS = {
32
+ logging.DEBUG: Fore.WHITE,
33
+ logging.INFO: Fore.CYAN,
34
+ logging.WARNING: Fore.YELLOW,
35
+ logging.ERROR: Fore.RED,
36
+ logging.CRITICAL: Fore.LIGHTRED_EX,
37
+ }
38
+
39
+ def __init__(self, use_colors: bool = True, include_request_id: bool = True):
40
+ self.use_colors = use_colors
41
+ self.include_request_id = include_request_id
42
+
43
+ if include_request_id:
44
+ template = (
45
+ "[{asctime}].[{name}].[{levelname}].[{request_id}] -> "
46
+ "{message} \t || {module}:{funcName}"
47
+ )
48
+ else:
49
+ template = "[{asctime}].[{name}].[{levelname}] -> {message} \t || {module}:{funcName}"
50
+
51
+ super().__init__(template, style="{", datefmt="%Y-%m-%d %H:%M:%S")
52
+
53
+ def format(self, record: logging.LogRecord) -> str:
54
+ if self.include_request_id:
55
+ request_id = getattr(record, "request_id", "NO-REQ-ID")
56
+ record.request_id = request_id
57
+
58
+ level_abbr = self.LEVEL_ABBREVIATIONS.get(record.levelno, record.levelname[:3])
59
+
60
+ if self.use_colors:
61
+ color = self.LEVEL_COLORS.get(record.levelno, "")
62
+ levelname_colored = f"{color}{level_abbr}{Style.RESET_ALL}"
63
+ msg_colored = f"{color}{record.getMessage()}{Style.RESET_ALL}"
64
+ else:
65
+ levelname_colored = level_abbr
66
+ msg_colored = record.getMessage()
67
+
68
+ record_copy = logging.makeLogRecord(record.__dict__)
69
+ record_copy.levelname = levelname_colored
70
+ record_copy.msg = msg_colored
71
+
72
+ return super().format(record_copy)
73
+
74
+
75
+ class SensitiveDataFilter(logging.Filter): # pylint: disable=too-few-public-methods
76
+ """Filter to scrub sensitive data from log messages."""
77
+
78
+ DEFAULT_PATTERNS = [
79
+ r"Bearer\s+[A-Za-z0-9\-_]+",
80
+ r'token["\s:=]+[A-Za-z0-9\-_\.]+',
81
+ r'password["\s:=]+\S+',
82
+ r'api_key["\s:=]+[A-Za-z0-9\-_]+',
83
+ r"Authorization:\s*[^\s]+",
84
+ r"X-API-Key:\s*[^\s]+",
85
+ ]
86
+
87
+ def __init__(self, patterns: Optional[list] = None):
88
+ super().__init__()
89
+ self.patterns = patterns or self.DEFAULT_PATTERNS
90
+ self._compiled_patterns = [re.compile(pattern, re.IGNORECASE) for pattern in self.patterns]
91
+
92
+ def filter(self, record: logging.LogRecord) -> bool:
93
+ message = record.getMessage()
94
+ for pattern in self._compiled_patterns:
95
+ message = pattern.sub("[REDACTED]", message)
96
+
97
+ record.msg = message
98
+ record.args = ()
99
+
100
+ return True
101
+
102
+
103
+ class RequestIdFilter(logging.Filter):
104
+ """Filter that adds request ID context to log records."""
105
+
106
+ def __init__(self):
107
+ super().__init__()
108
+ self._local = threading.local()
109
+
110
+ def set_request_id(self, request_id: str):
111
+ self._local.request_id = request_id
112
+
113
+ def clear_request_id(self):
114
+ if hasattr(self._local, "request_id"):
115
+ delattr(self._local, "request_id")
116
+
117
+ def get_request_id(self) -> Optional[str]:
118
+ return getattr(self._local, "request_id", None)
119
+
120
+ def filter(self, record: logging.LogRecord) -> bool:
121
+ request_id = self.get_request_id()
122
+ record.request_id = request_id or "NO-REQ-ID"
123
+ return True
124
+
125
+
126
+ class LoggerManager: # pylint: disable=too-many-instance-attributes
127
+ """Central logger manager for the BlackAnt SDK."""
128
+
129
+ def __init__( # pylint: disable=too-many-arguments
130
+ self,
131
+ app_name: str = "BlackAnt",
132
+ default_log_file: Optional[str] = None,
133
+ log_level: Union[str, int] = logging.INFO,
134
+ enable_colors: bool = True,
135
+ enable_request_tracking: bool = True,
136
+ enable_sensitive_filter: bool = True,
137
+ ):
138
+ self.app_name = app_name
139
+ self.enable_colors = enable_colors
140
+ self.enable_request_tracking = enable_request_tracking
141
+ self.enable_sensitive_filter = enable_sensitive_filter
142
+
143
+ if default_log_file is None:
144
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
145
+ default_log_file = f"{app_name.lower()}_{timestamp}.log"
146
+
147
+ self.log_file = Path(default_log_file)
148
+
149
+ self.request_id_filter = RequestIdFilter() if enable_request_tracking else None
150
+ self.sensitive_filter = SensitiveDataFilter() if enable_sensitive_filter else None
151
+
152
+ self._setup_root_logger(log_level)
153
+
154
+ self._module_loggers: Dict[str, logging.Logger] = {}
155
+
156
+ def _setup_root_logger(self, log_level: Union[str, int]):
157
+ root_logger = logging.getLogger(self.app_name)
158
+ root_logger.setLevel(log_level)
159
+ root_logger.propagate = False
160
+
161
+ for handler in root_logger.handlers[:]:
162
+ root_logger.removeHandler(handler)
163
+
164
+ console_handler = self._create_console_handler()
165
+ root_logger.addHandler(console_handler)
166
+
167
+ file_handler = self._create_file_handler(self.log_file)
168
+ root_logger.addHandler(file_handler)
169
+
170
+ self.root_logger = root_logger
171
+
172
+ def _create_console_handler(self) -> logging.StreamHandler:
173
+ handler = logging.StreamHandler(sys.stdout)
174
+ handler.setLevel(logging.INFO)
175
+
176
+ formatter = CustomFormatter(
177
+ use_colors=self.enable_colors, include_request_id=self.enable_request_tracking
178
+ )
179
+ handler.setFormatter(formatter)
180
+
181
+ if self.request_id_filter:
182
+ handler.addFilter(self.request_id_filter)
183
+
184
+ if self.sensitive_filter:
185
+ handler.addFilter(self.sensitive_filter)
186
+
187
+ return handler
188
+
189
+ def _create_file_handler(self, log_file: Path) -> logging.FileHandler:
190
+ log_file.parent.mkdir(parents=True, exist_ok=True)
191
+
192
+ handler = logging.FileHandler(log_file, mode="w", encoding="utf-8")
193
+ handler.setLevel(logging.DEBUG)
194
+
195
+ formatter = CustomFormatter(
196
+ use_colors=False, include_request_id=self.enable_request_tracking
197
+ )
198
+ handler.setFormatter(formatter)
199
+
200
+ if self.request_id_filter:
201
+ handler.addFilter(self.request_id_filter)
202
+
203
+ if self.sensitive_filter:
204
+ handler.addFilter(self.sensitive_filter)
205
+
206
+ return handler
207
+
208
+ def get_logger(self, name: str) -> logging.Logger:
209
+ full_name = f"{self.app_name}.{name}" if name else self.app_name
210
+
211
+ if full_name not in self._module_loggers:
212
+ logger = logging.getLogger(full_name)
213
+ logger.setLevel(self.root_logger.level)
214
+
215
+ if not logger.handlers:
216
+ logger.parent = self.root_logger
217
+
218
+ self._module_loggers[full_name] = logger
219
+
220
+ return self._module_loggers[full_name]
221
+
222
+ def set_request_id(self, request_id: str):
223
+ if self.request_id_filter:
224
+ self.request_id_filter.set_request_id(request_id)
225
+
226
+ def clear_request_id(self):
227
+ if self.request_id_filter:
228
+ self.request_id_filter.clear_request_id()
229
+
230
+ def update_log_file(self, new_log_file: Union[str, Path]):
231
+ new_path = Path(new_log_file)
232
+
233
+ for handler in self.root_logger.handlers[:]:
234
+ if isinstance(handler, logging.FileHandler):
235
+ self.root_logger.removeHandler(handler)
236
+ handler.close()
237
+
238
+ new_file_handler = self._create_file_handler(new_path)
239
+ self.root_logger.addHandler(new_file_handler)
240
+
241
+ self.log_file = new_path
242
+ self.root_logger.info("Log file updated to: %s", new_path)
243
+
244
+ def set_level(self, level: Union[str, int]):
245
+ self.root_logger.setLevel(level)
246
+ for logger in self._module_loggers.values():
247
+ logger.setLevel(level)
248
+
249
+ def enable_debug_mode(self):
250
+ self.set_level(logging.DEBUG)
251
+
252
+ for handler in self.root_logger.handlers:
253
+ if isinstance(handler, logging.StreamHandler) and handler.stream == sys.stdout:
254
+ handler.setLevel(logging.DEBUG)
255
+
256
+
257
+ _logger_manager: Optional[LoggerManager] = None
258
+
259
+
260
+ def init_logging( # pylint: disable=too-many-arguments
261
+ app_name: str = "BlackAnt",
262
+ log_file: Optional[str] = None,
263
+ log_level: Union[str, int] = logging.INFO,
264
+ enable_colors: bool = True,
265
+ enable_request_tracking: bool = True,
266
+ enable_sensitive_filter: bool = True,
267
+ ) -> LoggerManager:
268
+ global _logger_manager # pylint: disable=global-statement,invalid-name
269
+
270
+ _logger_manager = LoggerManager(
271
+ app_name=app_name,
272
+ default_log_file=log_file,
273
+ log_level=log_level,
274
+ enable_colors=enable_colors,
275
+ enable_request_tracking=enable_request_tracking,
276
+ enable_sensitive_filter=enable_sensitive_filter,
277
+ )
278
+
279
+ return _logger_manager
280
+
281
+
282
+ def get_logger(name: str = "") -> logging.Logger:
283
+ global _logger_manager # pylint: disable=global-statement,invalid-name
284
+
285
+ if _logger_manager is None:
286
+ _logger_manager = init_logging()
287
+
288
+ return _logger_manager.get_logger(name)
289
+
290
+
291
+ def set_request_id(request_id: str):
292
+ if _logger_manager:
293
+ _logger_manager.set_request_id(request_id)
294
+
295
+
296
+ def clear_request_id():
297
+ if _logger_manager:
298
+ _logger_manager.clear_request_id()
299
+
300
+
301
+ def update_log_file(new_log_file: Union[str, Path]):
302
+ if _logger_manager:
303
+ _logger_manager.update_log_file(new_log_file)
304
+
305
+
306
+ def set_log_level(level: Union[str, int]):
307
+ if _logger_manager:
308
+ _logger_manager.set_level(level)
309
+
310
+
311
+ def enable_debug_mode():
312
+ if _logger_manager:
313
+ _logger_manager.enable_debug_mode()
314
+
315
+
316
+ def gb_to_mb(gigabytes: float) -> int:
317
+ return int(gigabytes * 1024)
318
+
319
+
320
+ if __name__ == "__main__":
321
+ init_logging(app_name="BlackAnt-Demo", log_level="DEBUG")
322
+
323
+ main_logger = get_logger("main")
324
+ http_logger = get_logger("http")
325
+
326
+ main_logger.debug("Debug message")
327
+ main_logger.info("Info message")
328
+ main_logger.warning("Warning message")
329
+ main_logger.error("Error message")
330
+
331
+ set_request_id("req_demo_12345")
332
+ http_logger.info("Message with request ID")
333
+
334
+ clear_request_id()
335
+ main_logger.info("Message without request ID")
336
+
337
+ http_logger.info("Token test: Bearer secret_token_123")
@@ -0,0 +1,13 @@
1
+ import uuid
2
+ import time
3
+
4
+
5
+ class RequestIdGenerator: # pylint: disable=too-few-public-methods
6
+ def __init__(self, header_name="X-Request-ID"):
7
+ self.header_name = header_name
8
+ self._counter = 0
9
+
10
+ def generate_id(self):
11
+ self._counter += 1
12
+ timestamp = int(time.time() * 1000)
13
+ return f"req_{timestamp}_{self._counter}_{uuid.uuid4().hex[:8]}"
@@ -0,0 +1,50 @@
1
+ """Runtime data storage module for BlackAnt SDK.
2
+
3
+ Provides thread-safe storage using threading.local() for storing
4
+ data across different modules and components.
5
+ """
6
+
7
+ from typing import Any
8
+ import threading
9
+
10
+ from ..patterns.singleton import Singleton
11
+
12
+
13
+ class Store(metaclass=Singleton): # pylint: disable=too-few-public-methods
14
+ """Base class for runtime data storage.
15
+
16
+ Thread-safe storage implementation using threading.local().
17
+ All specific stores (auth tokens, request IDs) inherit from this class.
18
+ """
19
+
20
+ __tls = threading.local()
21
+
22
+ def _get(self, name: str):
23
+ """Get data from thread-local storage.
24
+
25
+ Args:
26
+ name (str): Attribute name to retrieve.
27
+
28
+ Returns:
29
+ Any or None: Attribute value or None if not set.
30
+ """
31
+ if not hasattr(self.__tls, name):
32
+ return None
33
+ return self.__tls.__getattribute__(name)
34
+
35
+ def _set(self, name: str, value: Any):
36
+ """Set data in thread-local storage.
37
+
38
+ Args:
39
+ name (str): Attribute name to set.
40
+ value (Any): Value to store.
41
+ """
42
+ self.__tls.__setattr__(name, value)
43
+
44
+ def _del(self, name: str):
45
+ """Delete data from thread-local storage.
46
+
47
+ Args:
48
+ name (str): Attribute name to delete.
49
+ """
50
+ self.__tls.__delattr__(name)
@@ -0,0 +1,117 @@
1
+ Metadata-Version: 2.4
2
+ Name: blackant-sdk
3
+ Version: 1.0.2
4
+ Summary: Python SDK for Docker operations with automatic authentication through BlackAnt platform
5
+ Author-email: Balázs Milán <milan.balazs@uni-obuda.hu>
6
+ Maintainer-email: BlackAnt Development Team <dev@blackant.app>
7
+ License: Proprietary - Óbudai Egyetem
8
+ Project-URL: Homepage, https://env.blackant.app/systemdevelopers/blackant_sdk
9
+ Project-URL: Documentation, https://docs.blackant.app
10
+ Project-URL: Repository, https://env.blackant.app/systemdevelopers/blackant_sdk
11
+ Project-URL: Bug Tracker, https://env.blackant.app/systemdevelopers/blackant_sdk/-/issues
12
+ Keywords: docker,sdk,authentication,blackant,container,orchestration,swarm
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Classifier: Topic :: System :: Distributed Computing
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Operating System :: OS Independent
21
+ Requires-Python: >=3.11
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: flask>=2.3.2
24
+ Requires-Dist: flask-restful>=0.3.10
25
+ Requires-Dist: waitress>=2.1.2
26
+ Requires-Dist: minio>=6.0.0
27
+ Requires-Dist: requests>=2.31.0
28
+ Requires-Dist: docker>=4.4.3
29
+ Requires-Dist: urllib3<2.0
30
+ Requires-Dist: gunicorn>=21.2.0
31
+ Requires-Dist: colorama>=0.4.6
32
+ Requires-Dist: python-keycloak>=3.0.0
33
+ Requires-Dist: PyJWT>=2.8.0
34
+ Provides-Extra: dev
35
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
36
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
37
+ Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
38
+ Requires-Dist: sphinx>=5.0.0; extra == "dev"
39
+ Requires-Dist: sphinx-rtd-theme>=1.0.0; extra == "dev"
40
+ Provides-Extra: test
41
+ Requires-Dist: pytest>=7.0.0; extra == "test"
42
+ Requires-Dist: pytest-cov>=4.0.0; extra == "test"
43
+ Requires-Dist: pytest-mock>=3.10.0; extra == "test"
44
+ Provides-Extra: docs
45
+ Requires-Dist: sphinx>=5.0.0; extra == "docs"
46
+ Requires-Dist: sphinx-rtd-theme>=1.0.0; extra == "docs"
47
+
48
+ # Python REST API docker template
49
+
50
+ A simple template to implement REST APIs using Python Flask & docker.
51
+
52
+ ## Build arguments
53
+
54
+ ### INSTALL_DEBUG_TOOLS
55
+
56
+ If it's set to True, ptvsd is installed during build to be able to do live debugging.
57
+
58
+ ## Environment variables
59
+
60
+ ### CALCULATION_NAME
61
+
62
+ Name of the calculation. Mandatory parameter.
63
+
64
+ ### SERVER_PORT
65
+
66
+ Port which on the server runs. Default: 5000
67
+
68
+ ### DEBUG_MODE
69
+
70
+ A switch to select between debug and release mode. If it is set to True, a Flask server will be started in debug mode and a ptvsd server. Otherwise, it is served using gevent production server. Default: False
71
+
72
+ ### OBJECT_STORAGE_URL
73
+
74
+ Url for the object storage. Mandatory if the code uses object storage.
75
+
76
+ ### OBJECT_STORAGE_ACCESS_KEY
77
+
78
+ Public key for the object storage.
79
+
80
+ ### OBJECT_STORAGE_SECRET_KEY
81
+
82
+ Private key for the object storage.
83
+
84
+ ### SCHEDULER_URL
85
+
86
+ Callback url of the scheduler.
87
+
88
+ ## Commands
89
+
90
+ ### Build
91
+
92
+ ```sh
93
+ docker-compose build
94
+ ```
95
+
96
+ ### Run
97
+
98
+ ```sh
99
+ docker-compose up
100
+ ```
101
+
102
+ ### Create task
103
+
104
+ You can use the tools/send_request.py script to send a simple request to the calculation container.
105
+
106
+ ### Debug
107
+
108
+ If you use Visual Studio Code, there is a debug configuration called Python: Remote Attach which will start a debug session and connect to your running container.
109
+
110
+ ## Documentation
111
+
112
+ Full HTML and PDF documentation can be generated from any revision using the generate_documentation job in the CI.
113
+ After the job have run successfully, the artifacts are stored for one day.
114
+ If it's necessary it can be rerun any time.
115
+
116
+
117
+ ......
@@ -0,0 +1,70 @@
1
+ blackant/__init__.py,sha256=THZWaFP_eIFEDVsIQC5HSCY9k2nGeR1TQ3rNhdlScEM,746
2
+ blackant/client.py,sha256=dsF-vPDzhv8Bx_OoakP4NC5dnbYRfkB4MHXcIAsIr9I,15180
3
+ blackant/exceptions.py,sha256=6y9FwBlO_ntYmVyJfrhKVUUnAHaA0wkyJx2WtddU1Ts,2845
4
+ blackant/auth/__init__.py,sha256=Ax1FqQsZNucr4CEUCqeZkrnbWN8Fx72IHFg3PZzbd2A,289
5
+ blackant/auth/blackant_auth.py,sha256=eLZ2T17kxRyl54LII1roGsyxkM-hMAWyqgi_HowwSLQ,19113
6
+ blackant/auth/keycloak_manager.py,sha256=6ubCAC8lR-6d5UyEXdX4X7aKTo3NF3N1kZ5KnPUcOOA,11708
7
+ blackant/auth/request_id.py,sha256=vWh-GX6f7aQAgvj2XINqn_8gJVgQ0a3bk_B3JqrtGaQ,1396
8
+ blackant/auth/role_assignment.py,sha256=Y14FIxSys9ICrYkVEERW3t2IyUyZwGODalXLV6kmD0c,14865
9
+ blackant/auth/tokens.py,sha256=A8fdd4a6KS24PmuiHvNgJCH5UJRGNfgm8wO6Q0hY4vE,1498
10
+ blackant/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ blackant/config/docker_config.py,sha256=80VM0kvUV-AWbzB2qDCFOHog9MDklsXdfsB3wEFRtX0,15049
12
+ blackant/config/keycloak_admin_config.py,sha256=a4de2bCd_PjuCXajQIzZko7YaPJVmifQlvNVK8M3iTU,3370
13
+ blackant/docker/__init__.py,sha256=RtBjt7fX4cUjszHtlH6izgFOXPDqhCUYU7NOUALQCF0,362
14
+ blackant/docker/builder.py,sha256=pGOyHTVvZLn9hTFu-VX2V4YGo2e2aur2l95i3ZdHp6s,24728
15
+ blackant/docker/client.py,sha256=i0JG7FCBeR9-gstom1rMTwc4ZCKVmMj0QIxyEXi_7fg,37405
16
+ blackant/docker/dao.py,sha256=bNtGhArc3kzD19QpeYoXNYvRwr7Bk3NsQ0DirohlYdA,17258
17
+ blackant/docker/registry.py,sha256=lGTECoCAklMe5-oD9bJDM1q9wq35YYDt6TM7hQdyM1I,5813
18
+ blackant/http/__init__.py,sha256=s54aPP80f6AWCEq2XS97CM2Z8-mAKamKaAlZgWy6-vE,207
19
+ blackant/http/client.py,sha256=DacZlA3MMNS6Ys0tWSNXT57avwN5Dr5PpX6Iekji5es,4597
20
+ blackant/patterns/__init__.py,sha256=iOEhKRqynyPbMNqDn1nHVWF6BoEq1htKtjjlJbmHp8U,48
21
+ blackant/patterns/singleton.py,sha256=LpNrQ5ct_tl9HIhDE4x7UDamezaMBDeiyDHXe9LwosU,610
22
+ blackant/services/__init__.py,sha256=UAPWaWiaPJ5XlvWtsqLO16eQkrkVAj4xzeeoyE9o3Vk,278
23
+ blackant/services/dao.py,sha256=4qm0MFIO2c0lkOUqOC8Fyp0tcF4MbBkF7RNcBdpuIWU,15187
24
+ blackant/services/registry.py,sha256=RPSTRPtKxa53NXxBVzW0TAdK3z8ai_ObnS47YjKCuE8,23473
25
+ blackant/utils/__init__.py,sha256=tzO_ZleysoT7Yf7kpI_io4udNAeH7c9cxwJqydEF5jA,130
26
+ blackant/utils/initialization.py,sha256=pe0fVfeV0mQkYdYJPoashTBTSNs4wQHtNEtABR2Jw7I,846
27
+ blackant/utils/logging.py,sha256=c1bNgWido4j1mD6p8l8pVhYCZgWfarP-R439pBOrIP8,10700
28
+ blackant/utils/request_id.py,sha256=RzuiIhlyVWLbAnSWmFh9pfwzPzLPxkLs3i8dyCxY92I,383
29
+ blackant/utils/store.py,sha256=Vewqt42Ne5e_m9DTxEnxA3afyhsyrNbuPrq4Y0v5P90,1348
30
+ calculation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ calculation/base.py,sha256=648e38zekvKsv4a7DL2skcjWX8ed7FDwSy6I3ubG7j4,529
32
+ calculation/errors.py,sha256=h5jZmvA76RApr4vIUqkyTYmjk3NzxknUjlWqNZDelcU,46
33
+ calculation/loader.py,sha256=Jrt3dadpgU2b-UhNhZrdAuFGN2gzyrlcgnHNjbGtXk8,8005
34
+ calculation/impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
+ calculation/impl/my_calculation.py,sha256=dsi5pDfgiCGOCZ7Rivjs7n5fiBCuB9Q8GOT4VR5v-0U,5054
36
+ calculation/impl/simple_calc.py,sha256=xhTlEt8oIz-oHDxtT_Iz3zSPjTl23a_XleC8kJUYdeU,1245
37
+ calculation/impl/test.py,sha256=_P06owSXxM9cK3FeeyYPXi17Km3-n394C_LYfMhUlbA,13
38
+ calculation/impl/test_calc.py,sha256=iSr4OUsupJpnug8SVl32-qWiLjP3iGrJc8I4W7JfAJk,954
39
+ notifinations/__init__.py,sha256=eOVctP2iedEe94bzz01B_0hqhNr8pFq9j7Qq9a2xK5o,175
40
+ notifinations/mail_sender.py,sha256=bx3jRShq4EjPesfIzP6vfmdB8XL8fi0ilMnURhWy_YY,7958
41
+ storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ storage/errors.py,sha256=ja71c2WQbtsamIRbFO4ea66Lr7SpIh8kWhf0h7gValI,187
43
+ storage/factory.py,sha256=ki2lYvA5JrxWQVZ3WX3Tykldo1q6F-20eAKudMo5Iig,905
44
+ storage/interface.py,sha256=87pQJ3uW8EJ4uLMi07iQxPaVM0HhUTXrshcUlRFSSM4,420
45
+ storage/minio.py,sha256=VxP6JNa_ktuY-0LB8-jvDGb9dm193pBgD3JFmKJOVhY,3985
46
+ task/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
+ task/dao.py,sha256=Qs7-ACKWtWaWTwV1nuoRMOHXQObj_Z9vWNI-SPTvNaI,1012
48
+ task/errors.py,sha256=O6Uwj2benf3bs6AKtdkrPCtP_jPXWTS5nepUWEy3NZM,163
49
+ task/log_adapter.py,sha256=HmXpus2fYuRcPlUgSMFByqj7HZoFwQ2ABv28sEZ3uPk,323
50
+ task/resource.py,sha256=n0rOvOu4tYD9v9zEFxl-pZmp9NjqT-8Cqzb3ErEq68g,3307
51
+ task/task.py,sha256=_b0P-lM9LtLZxvmRIHWgrecziG_TuaUTVZifFs7hv2s,13314
52
+ task/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ task/parsers/base.py,sha256=VUpZrPJPTnwAvPzxqvI0MgkzEW-550996izlFGJm2uI,249
54
+ task/parsers/callback.py,sha256=dgQFc3n3tlGcd7qhK_BYe-RRXxh3OLHznHiaqzGCwgw,1038
55
+ task/parsers/cmd_args.py,sha256=lUjZD6T27elvx1qQdia0WiXlXjLIgGeztB10MK6PqH8,1684
56
+ task/parsers/freetext.py,sha256=KA5g1tyb648RXHpl8XY6h-UVAvWNrEnZiuJt7bw8QFM,545
57
+ task/parsers/objects.py,sha256=fQcRVEQjQ1UxlWrt6kEfqzH3JaQqFX_ON4ign_omuZ0,1555
58
+ task/parsers/request.py,sha256=dfV1ow8e1tb1Cdmb0FBIagGCynFHfNWftBX40I10QAE,1859
59
+ task/states/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
+ task/states/base.py,sha256=xsh2CoLoOcAcjpQrZri8F9sYbBv8StdCMl-9hJqRQsE,263
61
+ task/states/error.py,sha256=19Vpvvmx-qHG2zgtGfHK7ULHx6ZCisMdcPNVPSNDZDA,1766
62
+ task/states/idle.py,sha256=3JYb8-_eJ5NlirMWOaEh_OUP7HtjqqyBIQye-nzoRYQ,326
63
+ task/states/ready.py,sha256=kMpC6qY_IGkLc1JpaH_jf_NcZgC4vyLzoEZhYMDOwZA,1967
64
+ task/states/running.py,sha256=HVkkZlC7xOV5M3NnJAf4SWyVE5JqT2LhZokIbRyskbQ,773
65
+ task/states/set_up.py,sha256=NsoEGKVL_E3hQFIm3p3Bv6uC7J0DOPzTc8UZrMEVR1g,1634
66
+ task/states/tear_down.py,sha256=xq6xSC2Q_Yuky047kRP4fSwM992PILIOYBZbOl1RIDA,1050
67
+ blackant_sdk-1.0.2.dist-info/METADATA,sha256=uzdQjvqBJNSYM414ju-eN0aHA7JbSiMWCdi4hfRZUkg,3615
68
+ blackant_sdk-1.0.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
69
+ blackant_sdk-1.0.2.dist-info/top_level.txt,sha256=MZZ_UBTnah0fs9yzTmlavd4Z0HuJDD3alhfGlB79ZIE,48
70
+ blackant_sdk-1.0.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,5 @@
1
+ blackant
2
+ calculation
3
+ notifinations
4
+ storage
5
+ task
File without changes
calculation/base.py ADDED
@@ -0,0 +1,26 @@
1
+ import abc
2
+
3
+
4
+ class CalculationBase:
5
+ def __init__(self, logger):
6
+ self._logger = logger
7
+
8
+ @abc.abstractproperty
9
+ def result(self):
10
+ raise NotImplementedError
11
+
12
+ @abc.abstractmethod
13
+ def set_up(self):
14
+ raise NotImplementedError
15
+
16
+ @abc.abstractmethod
17
+ def run(self):
18
+ raise NotImplementedError
19
+
20
+ @abc.abstractmethod
21
+ def tear_down(self):
22
+ raise NotImplementedError
23
+
24
+ @abc.abstractmethod
25
+ def stop(self):
26
+ raise NotImplementedError
calculation/errors.py ADDED
@@ -0,0 +1,2 @@
1
+ class CalculationError(Exception):
2
+ pass
File without changes