wrd 0.1.41__py3-none-any.whl → 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.
dune/task_validator.py DELETED
@@ -1,324 +0,0 @@
1
- """
2
- Walidator konfiguracji zadań zgodnie ze standardem dune Task Configuration.
3
- """
4
-
5
- import os
6
- import yaml
7
- import socket
8
- import requests
9
- import shutil
10
- from pathlib import Path
11
- from typing import Dict, List, Any, Optional
12
- from pydantic import BaseModel, Field, validator
13
- from loguru import logger
14
- import subprocess
15
-
16
-
17
- class TaskMetadata(BaseModel):
18
- """Metadane zadania."""
19
- name: str
20
- description: str
21
- version: str
22
- created: str
23
- tags: List[str] = []
24
-
25
-
26
- class TaskDefinition(BaseModel):
27
- """Definicja zadania."""
28
- natural_language: str
29
- requirements: List[str]
30
- expected_output: Dict[str, Any]
31
-
32
-
33
- class RuntimeConfig(BaseModel):
34
- """Konfiguracja środowiska wykonawczego."""
35
- type: str = "docker"
36
- base_image: str = "python:3.11-slim"
37
- python_packages: Dict[str, List[str]]
38
- environment: Dict[str, List[str]]
39
-
40
-
41
- class ServiceDependency(BaseModel):
42
- """Definicja zależności usługowej."""
43
- name: str
44
- type: str
45
- required: bool = True
46
- connection: Dict[str, str]
47
- health_check: Dict[str, Any]
48
-
49
-
50
- class ManagedService(BaseModel):
51
- """Definicja zarządzanej usługi."""
52
- name: str
53
- type: str
54
- enabled: str = "true"
55
- config: Dict[str, Any]
56
-
57
-
58
- class ValidationRule(BaseModel):
59
- """Reguła walidacji."""
60
- type: str
61
- kwargs: Dict[str, Any] = {}
62
-
63
-
64
- class TaskConfiguration(BaseModel):
65
- """Główna konfiguracja zadania."""
66
- apiVersion: str
67
- kind: str
68
- metadata: TaskMetadata
69
- task: TaskDefinition
70
- runtime: RuntimeConfig
71
- services: Dict[str, Any]
72
- validation: Dict[str, List[ValidationRule]]
73
- monitoring: Dict[str, Any]
74
- security: Dict[str, Any]
75
- pipeline: Dict[str, Any]
76
- environments: Dict[str, Dict[str, Any]] = {}
77
-
78
-
79
- class TaskValidator:
80
- """Walidator konfiguracji zadań."""
81
-
82
- def __init__(self):
83
- self.validation_results = []
84
- self.warnings = []
85
- self.errors = []
86
-
87
- def load_config(self, config_path: str) -> TaskConfiguration:
88
- """Ładuje konfigurację z pliku YAML."""
89
- try:
90
- with open(config_path, 'r', encoding='utf-8') as f:
91
- config_data = yaml.safe_load(f)
92
-
93
- # Rozwiń zmienne środowiskowe
94
- config_data = self._expand_environment_variables(config_data)
95
-
96
- return TaskConfiguration(**config_data)
97
-
98
- except Exception as e:
99
- logger.error(f"Błąd ładowania konfiguracji: {e}")
100
- raise
101
-
102
- def _expand_environment_variables(self, data):
103
- """Rozszerza zmienne środowiskowe w konfiguracji."""
104
- if isinstance(data, dict):
105
- return {k: self._expand_environment_variables(v) for k, v in data.items()}
106
- elif isinstance(data, list):
107
- return [self._expand_environment_variables(item) for item in data]
108
- elif isinstance(data, str):
109
- # Prosta zamiana ${VAR} lub ${VAR:-default}
110
- import re
111
- def replace_var(match):
112
- var_expr = match.group(1)
113
- if ':-' in var_expr:
114
- var_name, default = var_expr.split(':-', 1)
115
- return os.getenv(var_name, default)
116
- else:
117
- return os.getenv(var_expr, match.group(0))
118
-
119
- return re.sub(r'\$\{([^}]+)\}', replace_var, data)
120
- else:
121
- return data
122
-
123
- def validate_pre_execution(self, config: TaskConfiguration) -> bool:
124
- """Wykonuje walidację przed wykonaniem zadania."""
125
- logger.info("Rozpoczynam walidację przed wykonaniem...")
126
-
127
- success = True
128
-
129
- # Waliduj połączenia z usługami
130
- success &= self._validate_service_connectivity(config)
131
-
132
- # Waliduj zmienne środowiskowe
133
- success &= self._validate_environment_variables(config)
134
-
135
- # Waliduj uprawnienia do plików
136
- success &= self._validate_file_permissions(config)
137
-
138
- # Waliduj miejsce na dysku
139
- success &= self._validate_disk_space(config)
140
-
141
- # Waliduj pakiety Python
142
- success &= self._validate_python_packages(config)
143
-
144
- return success
145
-
146
- def validate_post_execution(self, config: TaskConfiguration) -> bool:
147
- """Wykonuje walidację po wykonaniu zadania."""
148
- logger.info("Rozpoczynam walidację po wykonaniu...")
149
-
150
- success = True
151
-
152
- # Waliduj wygenerowane pliki
153
- success &= self._validate_output_files(config)
154
-
155
- # Waliduj strukturę katalogów
156
- success &= self._validate_directory_structure(config)
157
-
158
- return success
159
-
160
- def _validate_service_connectivity(self, config: TaskConfiguration) -> bool:
161
- """Sprawdza połączenie z wymaganymi usługami."""
162
- logger.info("Sprawdzanie połączeń z usługami...")
163
-
164
- success = True
165
- dependencies = config.services.get("dependencies", [])
166
-
167
- for dep in dependencies:
168
- service = ServiceDependency(**dep)
169
-
170
- if service.required:
171
- if not self._check_service_health(service):
172
- self.errors.append(f"Nie można połączyć z wymaganą usługą: {service.name}")
173
- success = False
174
- else:
175
- logger.success(f"✅ Usługa {service.name} dostępna")
176
- else:
177
- if not self._check_service_health(service):
178
- self.warnings.append(f"Opcjonalna usługa {service.name} niedostępna")
179
- logger.warning(f"⚠️ Opcjonalna usługa {service.name} niedostępna")
180
-
181
- return success
182
-
183
- def _check_service_health(self, service: ServiceDependency) -> bool:
184
- """Sprawdza dostępność konkretnej usługi."""
185
- try:
186
- health_check = service.health_check
187
-
188
- if health_check["type"] == "tcp_connect":
189
- host = service.connection.get("host", "localhost")
190
- port = int(service.connection.get("port", 80))
191
- timeout = int(health_check.get("timeout", "10s").replace("s", ""))
192
-
193
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
194
- sock.settimeout(timeout)
195
- result = sock.connect_ex((host, port))
196
- sock.close()
197
-
198
- return result == 0
199
-
200
- elif health_check["type"] == "http_get":
201
- url = service.connection["url"]
202
- endpoint = health_check.get("endpoint", "")
203
- timeout = int(health_check.get("timeout", "30s").replace("s", ""))
204
-
205
- response = requests.get(f"{url}{endpoint}", timeout=timeout)
206
- return response.status_code == 200
207
-
208
- except Exception as e:
209
- logger.debug(f"Health check failed for {service.name}: {e}")
210
- return False
211
-
212
- return False
213
-
214
- def _validate_environment_variables(self, config: TaskConfiguration) -> bool:
215
- """Sprawdza wymagane zmienne środowiskowe."""
216
- logger.info("Sprawdzanie zmiennych środowiskowych...")
217
-
218
- success = True
219
- required_vars = config.runtime.environment.get("required", [])
220
-
221
- for var in required_vars:
222
- if not os.getenv(var):
223
- self.errors.append(f"Brak wymaganej zmiennej środowiskowej: {var}")
224
- success = False
225
- else:
226
- logger.success(f"✅ Zmienna {var} ustawiona")
227
-
228
- return success
229
-
230
- def _validate_file_permissions(self, config: TaskConfiguration) -> bool:
231
- """Sprawdza uprawnienia do plików i katalogów."""
232
- logger.info("Sprawdzanie uprawnień do plików...")
233
-
234
- success = True
235
- output_dir = os.getenv("OUTPUT_DIR", "./output")
236
-
237
- # Sprawdź czy można tworzyć katalogi
238
- try:
239
- test_dir = Path(output_dir) / "test_permissions"
240
- test_dir.mkdir(parents=True, exist_ok=True)
241
-
242
- # Sprawdź czy można pisać pliki
243
- test_file = test_dir / "test.txt"
244
- test_file.write_text("test")
245
- test_file.unlink()
246
- test_dir.rmdir()
247
-
248
- logger.success(f"✅ Uprawnienia do zapisu w {output_dir}")
249
-
250
- except Exception as e:
251
- self.errors.append(f"Brak uprawnień do zapisu w {output_dir}: {e}")
252
- success = False
253
-
254
- return success
255
-
256
- def _validate_disk_space(self, config: TaskConfiguration) -> bool:
257
- """Sprawdza dostępne miejsce na dysku."""
258
- logger.info("Sprawdzanie miejsca na dysku...")
259
-
260
- output_dir = os.getenv("OUTPUT_DIR", "./output")
261
-
262
- try:
263
- # Sprawdź dostępne miejsce
264
- total, used, free = shutil.disk_usage(output_dir)
265
- free_mb = free // (1024 * 1024)
266
-
267
- if free_mb < 100: # Minimum 100MB
268
- self.warnings.append(f"Mało miejsca na dysku: {free_mb}MB")
269
- logger.warning(f"⚠️ Dostępne miejsce: {free_mb}MB")
270
- else:
271
- logger.success(f"✅ Dostępne miejsce: {free_mb}MB")
272
-
273
- except Exception as e:
274
- self.warnings.append(f"Nie można sprawdzić miejsca na dysku: {e}")
275
-
276
- return True
277
-
278
- def _validate_python_packages(self, config: TaskConfiguration) -> bool:
279
- """Sprawdza dostępność wymaganych pakietów Python."""
280
- logger.info("Sprawdzanie pakietów Python...")
281
-
282
- success = True
283
- required_packages = config.runtime.python_packages.get("required", [])
284
-
285
- for package in required_packages:
286
- package_name = package.split(">=")[0].split("==")[0]
287
-
288
- try:
289
- __import__(package_name)
290
- logger.success(f"✅ Pakiet {package_name} dostępny")
291
- except ImportError:
292
- logger.info(f"📦 Pakiet {package_name} będzie zainstalowany")
293
-
294
- return success
295
-
296
- def _validate_output_files(self, config: TaskConfiguration) -> bool:
297
- """Sprawdza czy zostały wygenerowane oczekiwane pliki."""
298
- logger.info("Sprawdzanie wygenerowanych plików...")
299
-
300
- success = True
301
- expected_output = config.task.expected_output
302
-
303
- if expected_output.get("type") == "file_structure":
304
- pattern = expected_output.get("pattern", "")
305
- # Tutaj można zaimplementować sprawdzanie wzorca plików
306
- logger.info(f"Sprawdzanie wzorca: {pattern}")
307
-
308
- return success
309
-
310
- def _validate_directory_structure(self, config: TaskConfiguration) -> bool:
311
- """Sprawdza strukturę katalogów."""
312
- logger.info("Sprawdzanie struktury katalogów...")
313
-
314
- # Implementacja sprawdzania struktury
315
- return True
316
-
317
- def generate_validation_report(self) -> Dict[str, Any]:
318
- """Generuje raport walidacji."""
319
- return {
320
- "validation_passed": len(self.errors) == 0,
321
- "errors": self.errors,
322
- "warnings": self.warnings,
323
- "total_checks": len(self.validation_results)
324
- }