endoreg-db 0.8.3.9__py3-none-any.whl → 0.8.4.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.

Potentially problematic release.


This version of endoreg-db might be problematic. Click here for more details.

@@ -8,8 +8,10 @@ from pathlib import Path
8
8
 
9
9
  from django.core.management import call_command
10
10
  from django.core.management.base import BaseCommand
11
+
11
12
  from endoreg_db.models import ModelMeta
12
13
 
14
+
13
15
  class Command(BaseCommand):
14
16
  help = """
15
17
  Complete setup for EndoReg DB when used as an embedded app.
@@ -119,6 +121,15 @@ class Command(BaseCommand):
119
121
  self.stdout.write(self.style.ERROR(f"❌ Failed to create AI model metadata: {e}"))
120
122
  return
121
123
 
124
+ # Step 5.5: Validate and fix AI model active metadata
125
+ self.stdout.write("\n🔧 Step 5.5: Validating AI model active metadata...")
126
+ try:
127
+ self._validate_and_fix_ai_model_metadata()
128
+ self.stdout.write(self.style.SUCCESS("✅ AI model metadata validation completed"))
129
+ except Exception as e:
130
+ self.stdout.write(self.style.ERROR(f"❌ Failed to validate AI model metadata: {e}"))
131
+ return
132
+
122
133
  # Step 6: Verification
123
134
  self.stdout.write("\n🔍 Step 6: Verifying setup...")
124
135
  try:
@@ -137,12 +148,11 @@ class Command(BaseCommand):
137
148
  def _find_model_weights_file(self):
138
149
  """Find the model weights file in various possible locations."""
139
150
  # Check common locations for model weights
140
-
151
+
141
152
  if not ModelMeta.objects.exists():
142
153
  print("📦 No model metadata found — creating from Hugging Face...")
143
154
  ModelMeta.setup_default_from_huggingface(
144
- "wg-lux/colo_segmentation_RegNetX800MF_base",
145
- labelset_name="multilabel_classification_colonoscopy_default"
155
+ "wg-lux/colo_segmentation_RegNetX800MF_base", labelset_name="multilabel_classification_colonoscopy_default"
146
156
  )
147
157
  print("✅ Default ModelMeta created.")
148
158
  possible_paths = [
@@ -162,10 +172,8 @@ class Command(BaseCommand):
162
172
  return path
163
173
 
164
174
  self.stdout.write("Model weights file not found in standard locations")
165
-
166
- return None
167
-
168
175
 
176
+ return None
169
177
 
170
178
  def _verify_setup(self):
171
179
  """Verify that the setup was successful."""
@@ -205,5 +213,81 @@ class Command(BaseCommand):
205
213
  self.stdout.write(f"Found {meta_count} model metadata record(s)")
206
214
 
207
215
  self.stdout.write("Setup verification passed")
208
-
209
216
 
217
+ def _validate_and_fix_ai_model_metadata(self):
218
+ """
219
+ Validate that all AI models have proper active metadata and fix if necessary.
220
+ This addresses the "No model metadata found for this model" error.
221
+ """
222
+ from endoreg_db.models import AiModel, LabelSet, ModelMeta
223
+
224
+ all_models = AiModel.objects.all()
225
+ fixed_count = 0
226
+
227
+ for model in all_models:
228
+ self.stdout.write(f"Checking model: {model.name}")
229
+
230
+ # Check if model has metadata versions
231
+ metadata_count = model.metadata_versions.count()
232
+ self.stdout.write(f" Metadata versions: {metadata_count}")
233
+
234
+ if metadata_count == 0:
235
+ # Create metadata for models that don't have any
236
+ self.stdout.write(f" Creating metadata for {model.name}...")
237
+
238
+ # Use existing labelset or create default
239
+ labelset = LabelSet.objects.first()
240
+ if not labelset:
241
+ labelset = LabelSet.objects.create(name="default_colonoscopy_labels", description="Default colonoscopy classification labels")
242
+
243
+ # Create basic metadata
244
+ meta = ModelMeta.objects.create(
245
+ name=model.name,
246
+ version="1.0",
247
+ model=model,
248
+ labelset=labelset,
249
+ activation="sigmoid" if "classification" in model.name else "sigmoid",
250
+ mean="0.485,0.456,0.406", # ImageNet defaults
251
+ std="0.229,0.224,0.225", # ImageNet defaults
252
+ size_x=224,
253
+ size_y=224,
254
+ axes="CHW",
255
+ batchsize=32,
256
+ num_workers=4,
257
+ description=f"Auto-generated metadata for {model.name}",
258
+ )
259
+
260
+ model.active_meta = meta
261
+ model.save()
262
+ fixed_count += 1
263
+ self.stdout.write(f" ✅ Created and set metadata for {model.name}")
264
+
265
+ elif not model.active_meta:
266
+ # Model has metadata but no active meta set
267
+ first_meta = model.metadata_versions.first()
268
+ if first_meta:
269
+ self.stdout.write(f" Setting active metadata for {model.name}...")
270
+ model.active_meta = first_meta
271
+ model.save()
272
+ fixed_count += 1
273
+ self.stdout.write(f" ✅ Set active metadata: {first_meta.name} v{first_meta.version}")
274
+ else:
275
+ self.stdout.write(f" ⚠️ No metadata versions available for {model.name}")
276
+
277
+ else:
278
+ self.stdout.write(f" ✅ Model {model.name} has active metadata: {model.active_meta}")
279
+
280
+ # Verify all models can get latest version
281
+ self.stdout.write("\nTesting model metadata access...")
282
+ for model in all_models:
283
+ try:
284
+ latest = model.get_latest_version()
285
+ self.stdout.write(f" ✅ {model.name}: {latest}")
286
+ except Exception as e:
287
+ self.stdout.write(f" ❌ {model.name}: {e}")
288
+ raise Exception(f"Model {model.name} still has metadata issues: {e}")
289
+
290
+ if fixed_count > 0:
291
+ self.stdout.write(f"Fixed metadata for {fixed_count} model(s)")
292
+ else:
293
+ self.stdout.write("All models already had proper metadata")
@@ -0,0 +1,124 @@
1
+ """
2
+ Django management command to validate and fix AI model metadata issues.
3
+ This command addresses the "No model metadata found for this model" error.
4
+ """
5
+
6
+ from django.core.management.base import BaseCommand
7
+
8
+ from endoreg_db.models.metadata.model_meta_logic import validate_and_fix_ai_model_metadata_logic
9
+
10
+
11
+ class Command(BaseCommand):
12
+ help = """
13
+ Validate and fix AI model metadata to prevent processing errors.
14
+
15
+ This command:
16
+ - Checks all AI models for proper metadata configuration
17
+ - Creates missing metadata with sensible defaults
18
+ - Sets active metadata for models that don't have it
19
+ - Validates that all models can access their latest versions
20
+
21
+ Use this command to fix "No model metadata found for this model" errors.
22
+ """
23
+
24
+ def add_arguments(self, parser):
25
+ parser.add_argument(
26
+ "--dry-run",
27
+ action="store_true",
28
+ help="Show what would be fixed without making changes",
29
+ )
30
+ parser.add_argument(
31
+ "--force",
32
+ action="store_true",
33
+ help="Force recreation of existing metadata",
34
+ )
35
+
36
+ def handle(self, *args, **options):
37
+ dry_run = options.get("dry_run", False)
38
+ force = options.get("force", False)
39
+
40
+ self.stdout.write(self.style.SUCCESS("🔍 Validating AI model metadata..."))
41
+
42
+ if dry_run:
43
+ self.stdout.write(self.style.WARNING("🧪 DRY RUN MODE - No changes will be made"))
44
+
45
+ try:
46
+ if dry_run:
47
+ # In dry run, we just check and report issues
48
+ summary = self._check_ai_models_dry_run()
49
+ else:
50
+ # Actually fix the issues
51
+ summary = validate_and_fix_ai_model_metadata_logic()
52
+
53
+ # Report results
54
+ self._report_summary(summary)
55
+
56
+ if summary["errors"]:
57
+ self.stdout.write(self.style.ERROR("❌ Validation completed with errors"))
58
+ for error in summary["errors"]:
59
+ self.stdout.write(self.style.ERROR(f" - {error}"))
60
+ return
61
+
62
+ self.stdout.write(self.style.SUCCESS("✅ AI model metadata validation completed successfully"))
63
+
64
+ except Exception as e:
65
+ self.stdout.write(self.style.ERROR(f"❌ Validation failed: {e}"))
66
+ raise
67
+
68
+ def _check_ai_models_dry_run(self):
69
+ """Check AI models without making changes."""
70
+ from endoreg_db.models import AiModel
71
+
72
+ summary = {"models_checked": 0, "models_fixed": 0, "metadata_created": 0, "active_meta_set": 0, "errors": []}
73
+
74
+ all_models = AiModel.objects.all()
75
+ summary["models_checked"] = all_models.count()
76
+
77
+ for model in all_models:
78
+ self.stdout.write(f"Checking model: {model.name}")
79
+
80
+ metadata_count = model.metadata_versions.count()
81
+ self.stdout.write(f" Metadata versions: {metadata_count}")
82
+
83
+ if metadata_count == 0:
84
+ self.stdout.write(f" 🔧 Would create metadata for {model.name}")
85
+ summary["models_fixed"] += 1
86
+ summary["metadata_created"] += 1
87
+
88
+ elif not model.active_meta:
89
+ self.stdout.write(f" 🔧 Would set active metadata for {model.name}")
90
+ summary["models_fixed"] += 1
91
+ summary["active_meta_set"] += 1
92
+
93
+ else:
94
+ self.stdout.write(f" ✅ Model {model.name} has valid active metadata")
95
+
96
+ # Test metadata access
97
+ try:
98
+ latest = model.get_latest_version()
99
+ self.stdout.write(f" ✅ Can access latest version: {latest}")
100
+ except Exception as e:
101
+ error_msg = f"Model {model.name} metadata test failed: {e}"
102
+ self.stdout.write(self.style.ERROR(f" ❌ {error_msg}"))
103
+ summary["errors"].append(error_msg)
104
+
105
+ return summary
106
+
107
+ def _report_summary(self, summary):
108
+ """Report the validation summary."""
109
+ self.stdout.write("\n📊 Validation Summary:")
110
+ self.stdout.write(f" Models checked: {summary['models_checked']}")
111
+
112
+ if summary["models_fixed"] > 0:
113
+ self.stdout.write(f" Models fixed: {summary['models_fixed']}")
114
+
115
+ if summary["metadata_created"] > 0:
116
+ self.stdout.write(f" Metadata created: {summary['metadata_created']}")
117
+
118
+ if summary["active_meta_set"] > 0:
119
+ self.stdout.write(f" Active metadata set: {summary['active_meta_set']}")
120
+
121
+ if summary["errors"]:
122
+ self.stdout.write(f" Errors encountered: {len(summary['errors'])}")
123
+ else:
124
+ self.stdout.write(" No errors found")
@@ -18,18 +18,14 @@ if TYPE_CHECKING:
18
18
  from .model_meta import ModelMeta # Import ModelMeta for type hinting
19
19
 
20
20
 
21
- def get_latest_version_number_logic(
22
- cls: Type["ModelMeta"], meta_name: str, model_name: str
23
- ) -> int:
21
+ def get_latest_version_number_logic(cls: Type["ModelMeta"], meta_name: str, model_name: str) -> int:
24
22
  """
25
23
  Finds the highest numerical version for a given meta_name and model_name.
26
24
  Iterates through all versions, attempts to parse them as integers,
27
25
  and returns the maximum integer found. If no numeric versions are found,
28
26
  returns 0.
29
27
  """
30
- versions_qs = cls.objects.filter(
31
- name=meta_name, model__name=model_name
32
- ).values_list("version", flat=True)
28
+ versions_qs = cls.objects.filter(name=meta_name, model__name=model_name).values_list("version", flat=True)
33
29
 
34
30
  max_v = 0
35
31
  found_numeric_version = False
@@ -84,24 +80,17 @@ def create_from_file_logic(
84
80
 
85
81
  if requested_version:
86
82
  target_version = str(requested_version)
87
- existing = cls.objects.filter(
88
- name=meta_name, model=ai_model, version=target_version
89
- ).first()
83
+ existing = cls.objects.filter(name=meta_name, model=ai_model, version=target_version).first()
90
84
  if existing and not bump_if_exists:
91
85
  raise ValueError(
92
- f"ModelMeta '{meta_name}' version '{target_version}' for model '{model_name}' "
93
- f"already exists. Use bump_if_exists=True to increment."
86
+ f"ModelMeta '{meta_name}' version '{target_version}' for model '{model_name}' already exists. Use bump_if_exists=True to increment."
94
87
  )
95
88
  elif existing and bump_if_exists:
96
89
  target_version = str(latest_version_num + 1)
97
- logger.info(
98
- f"Bumping version for {meta_name}/{model_name} to {target_version}"
99
- )
90
+ logger.info(f"Bumping version for {meta_name}/{model_name} to {target_version}")
100
91
  else:
101
92
  target_version = str(latest_version_num + 1)
102
- logger.info(
103
- f"Setting next version for {meta_name}/{model_name} to {target_version}"
104
- )
93
+ logger.info(f"Setting next version for {meta_name}/{model_name} to {target_version}")
105
94
 
106
95
  # --- Prepare Weights File ---
107
96
  source_weights_path = Path(weights_file).resolve()
@@ -111,10 +100,7 @@ def create_from_file_logic(
111
100
  # Construct destination path within MEDIA_ROOT/WEIGHTS_DIR
112
101
  weights_filename = source_weights_path.name
113
102
  # Relative path for the FileField upload_to
114
- relative_dest_path = (
115
- Path(WEIGHTS_DIR.relative_to(STORAGE_DIR))
116
- / f"{meta_name}_v{target_version}_{weights_filename}"
117
- )
103
+ relative_dest_path = Path(WEIGHTS_DIR.relative_to(STORAGE_DIR)) / f"{meta_name}_v{target_version}_{weights_filename}"
118
104
  # Full path for shutil.copy
119
105
  full_dest_path = STORAGE_DIR / relative_dest_path
120
106
 
@@ -233,22 +219,14 @@ def get_model_meta_by_name_version_logic(
233
219
  try:
234
220
  return cls.objects.get(name=meta_name, model=ai_model, version=version)
235
221
  except Exception as exc:
236
- raise cls.DoesNotExist(
237
- f"ModelMeta '{meta_name}' version '{version}' for model '{model_name}' not found."
238
- ) from exc
222
+ raise cls.DoesNotExist(f"ModelMeta '{meta_name}' version '{version}' for model '{model_name}' not found.") from exc
239
223
  else:
240
224
  # Get latest version
241
- latest = (
242
- cls.objects.filter(name=meta_name, model=ai_model)
243
- .order_by("-date_created")
244
- .first()
245
- )
225
+ latest = cls.objects.filter(name=meta_name, model=ai_model).order_by("-date_created").first()
246
226
  if latest:
247
227
  return latest
248
228
  else:
249
- raise cls.DoesNotExist(
250
- f"No ModelMeta found for '{meta_name}' and model '{model_name}'."
251
- )
229
+ raise cls.DoesNotExist(f"No ModelMeta found for '{meta_name}' and model '{model_name}'.")
252
230
 
253
231
 
254
232
  import re
@@ -266,9 +244,7 @@ def infer_default_model_meta_from_hf(model_id: str) -> dict[str, Any]:
266
244
  """
267
245
 
268
246
  if not (info := model_info(model_id)):
269
- logger.info(
270
- f"Could not retrieve model info for {model_id}, using ColoReg segmentation defaults."
271
- )
247
+ logger.info(f"Could not retrieve model info for {model_id}, using ColoReg segmentation defaults.")
272
248
  return {
273
249
  "name": "wg-lux/colo_segmentation_RegNetX800MF_base",
274
250
  "activation": "sigmoid",
@@ -317,9 +293,7 @@ def infer_default_model_meta_from_hf(model_id: str) -> dict[str, Any]:
317
293
  }
318
294
 
319
295
 
320
- def setup_default_from_huggingface_logic(
321
- cls, model_id: str, labelset_name: str | None = None
322
- ):
296
+ def setup_default_from_huggingface_logic(cls, model_id: str, labelset_name: str | None = None):
323
297
  """
324
298
  Downloads model weights from Hugging Face and auto-fills ModelMeta fields.
325
299
  """
@@ -333,11 +307,7 @@ def setup_default_from_huggingface_logic(
333
307
  )
334
308
 
335
309
  ai_model, _ = AiModel.objects.get_or_create(name=meta["name"])
336
- labelset = (
337
- LabelSet.objects.first()
338
- if not labelset_name
339
- else LabelSet.objects.get(name=labelset_name)
340
- )
310
+ labelset = LabelSet.objects.first() if not labelset_name else LabelSet.objects.get(name=labelset_name)
341
311
 
342
312
  return create_from_file_logic(
343
313
  cls,
@@ -352,3 +322,99 @@ def setup_default_from_huggingface_logic(
352
322
  size_y=meta["size_y"],
353
323
  description=meta["description"],
354
324
  )
325
+
326
+
327
+ def validate_and_fix_ai_model_metadata_logic():
328
+ """
329
+ Validates that all AI models have proper active metadata and fixes any issues.
330
+ This prevents the "No model metadata found for this model" error.
331
+
332
+ Returns:
333
+ dict: Summary of fixes applied
334
+ """
335
+ from ..administration.ai.ai_model import AiModel
336
+ from ..label.label_set import LabelSet
337
+
338
+ summary = {"models_checked": 0, "models_fixed": 0, "metadata_created": 0, "active_meta_set": 0, "errors": []}
339
+
340
+ try:
341
+ all_models = AiModel.objects.all()
342
+ summary["models_checked"] = all_models.count()
343
+
344
+ for model in all_models:
345
+ logger.info(f"Validating model: {model.name}")
346
+
347
+ # Check if model has metadata versions
348
+ metadata_count = model.metadata_versions.count()
349
+
350
+ if metadata_count == 0:
351
+ # Create metadata for models that don't have any
352
+ logger.info(f"Creating metadata for {model.name}")
353
+
354
+ # Use existing labelset or create default
355
+ labelset = LabelSet.objects.first()
356
+ if not labelset:
357
+ labelset = LabelSet.objects.create(name="default_colonoscopy_labels", description="Default colonoscopy classification labels")
358
+
359
+ # Import here to avoid circular imports
360
+ from .model_meta import ModelMeta
361
+
362
+ # Create basic metadata
363
+ meta = ModelMeta.objects.create(
364
+ name=model.name,
365
+ version="1.0",
366
+ model=model,
367
+ labelset=labelset,
368
+ activation="sigmoid" if "classification" in model.name else "sigmoid",
369
+ mean="0.485,0.456,0.406", # ImageNet defaults
370
+ std="0.229,0.224,0.225", # ImageNet defaults
371
+ size_x=224,
372
+ size_y=224,
373
+ axes="CHW",
374
+ batchsize=32,
375
+ num_workers=4,
376
+ description=f"Auto-generated metadata for {model.name}",
377
+ )
378
+
379
+ model.active_meta = meta
380
+ model.save()
381
+ summary["models_fixed"] += 1
382
+ summary["metadata_created"] += 1
383
+ logger.info(f"Created and set metadata for {model.name}")
384
+
385
+ elif not model.active_meta:
386
+ # Model has metadata but no active meta set
387
+ first_meta = model.metadata_versions.first()
388
+ if first_meta:
389
+ logger.info(f"Setting active metadata for {model.name}")
390
+ model.active_meta = first_meta
391
+ model.save()
392
+ summary["models_fixed"] += 1
393
+ summary["active_meta_set"] += 1
394
+ logger.info(f"Set active metadata: {first_meta.name} v{first_meta.version}")
395
+ else:
396
+ error_msg = f"No metadata versions available for {model.name}"
397
+ logger.warning(error_msg)
398
+ summary["errors"].append(error_msg)
399
+
400
+ else:
401
+ logger.info(f"Model {model.name} has valid active metadata: {model.active_meta}")
402
+
403
+ # Verify all models can get latest version
404
+ logger.info("Testing model metadata access...")
405
+ for model in all_models:
406
+ try:
407
+ latest = model.get_latest_version()
408
+ logger.info(f"✅ {model.name}: {latest}")
409
+ except Exception as e:
410
+ error_msg = f"Model {model.name} metadata test failed: {e}"
411
+ logger.error(error_msg)
412
+ summary["errors"].append(error_msg)
413
+
414
+ return summary
415
+
416
+ except Exception as e:
417
+ error_msg = f"Validation failed: {e}"
418
+ logger.error(error_msg)
419
+ summary["errors"].append(error_msg)
420
+ return summary
@@ -55,7 +55,18 @@ class VideoImportService():
55
55
  self.project_root = Path(__file__).parent.parent.parent.parent
56
56
 
57
57
  # Track processed files to prevent duplicates
58
- self.processed_files = set(str(Path(ANONYM_VIDEO_DIR) / file) for file in os.listdir(ANONYM_VIDEO_DIR))
58
+ try:
59
+ # Ensure anonym_video directory exists before listing files
60
+ anonym_video_dir = Path(ANONYM_VIDEO_DIR)
61
+ if anonym_video_dir.exists():
62
+ self.processed_files = set(str(anonym_video_dir / file) for file in os.listdir(ANONYM_VIDEO_DIR))
63
+ else:
64
+ logger.info(f"Creating anonym_videos directory: {anonym_video_dir}")
65
+ anonym_video_dir.mkdir(parents=True, exist_ok=True)
66
+ self.processed_files = set()
67
+ except Exception as e:
68
+ logger.warning(f"Failed to initialize processed files tracking: {e}")
69
+ self.processed_files = set()
59
70
 
60
71
  # Central video instance and processing context
61
72
  self.current_video: Optional[VideoFile] = None
@@ -146,6 +157,9 @@ class VideoImportService():
146
157
  High-level helper that orchestrates the complete video import and anonymization process.
147
158
  Uses the central video instance pattern for improved state management.
148
159
  """
160
+ # DEFENSIVE: Initialize processing_context immediately to prevent KeyError crashes
161
+ self.processing_context = {'file_path': Path(file_path)}
162
+
149
163
  try:
150
164
  # Initialize processing context
151
165
  self._initialize_processing_context(file_path, center_name, processor_name,
@@ -182,7 +196,12 @@ class VideoImportService():
182
196
  return self.current_video
183
197
 
184
198
  except Exception as e:
185
- self.logger.error(f"Video import and anonymization failed for {file_path}: {e}")
199
+ # Safe file path access - handles cases where processing_context wasn't initialized
200
+ safe_file_path = getattr(self, 'processing_context', {}).get('file_path', file_path)
201
+ # Debug: Log context state for troubleshooting
202
+ context_keys = list(getattr(self, 'processing_context', {}).keys())
203
+ self.logger.debug(f"Context keys during error: {context_keys}")
204
+ self.logger.error(f"Video import and anonymization failed for {safe_file_path}: {e}")
186
205
  self._cleanup_on_error()
187
206
  raise
188
207
  finally:
@@ -969,6 +988,10 @@ class VideoImportService():
969
988
  This method is always called in the finally block of import_and_anonymize()
970
989
  to ensure the file lock is released even if processing fails.
971
990
  """
991
+ # DEFENSIVE: Ensure processing_context exists before accessing it
992
+ if not hasattr(self, 'processing_context'):
993
+ self.processing_context = {}
994
+
972
995
  try:
973
996
  # Release file lock if it was acquired
974
997
  lock_context = self.processing_context.get('_lock_context')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: endoreg-db
3
- Version: 0.8.3.9
3
+ Version: 0.8.4.1
4
4
  Summary: EndoReg Db Django App
5
5
  Project-URL: Homepage, https://info.coloreg.de
6
6
  Project-URL: Repository, https://github.com/wg-lux/endoreg-db
@@ -290,10 +290,11 @@ endoreg_db/management/commands/load_unit_data.py,sha256=tcux-iL-ByT2ApgmHEkLllZS
290
290
  endoreg_db/management/commands/load_user_groups.py,sha256=D7SK2FvZEHoE4TIXNGCjDw5_12MH9bpGZvoS7eEv0Os,1031
291
291
  endoreg_db/management/commands/register_ai_model.py,sha256=KixTfuQR6TUfRmzB5GOos16BFOz7NL4TzLzBkgtPPgE,2510
292
292
  endoreg_db/management/commands/reset_celery_schedule.py,sha256=U-m_FNRTw6LAwJoT9RUE4qrhmQXm7AyFToPcHYyJpIE,386
293
- endoreg_db/management/commands/setup_endoreg_db.py,sha256=efOXE6IQs4ey84tIncf6zXI2VVVRd7CYXbeuACFgkgI,9095
293
+ endoreg_db/management/commands/setup_endoreg_db.py,sha256=v9QgbxAONChZNqm-TVPQGj7AEjZdSA01zC7gImkJEkY,12989
294
294
  endoreg_db/management/commands/start_filewatcher.py,sha256=3jESBqRiYPa9f35--zd70qQaYnyT0tzRO_b_HJuyteQ,4093
295
295
  endoreg_db/management/commands/storage_management.py,sha256=NpToX59ndwTFNmnSoeppmiPdMvpjSHH7mAdIe4SvUoI,22396
296
296
  endoreg_db/management/commands/summarize_db_content.py,sha256=pOIz3qbY4Ktmh0zV_DKFx971VD0pPx027gCD7a47EL0,10766
297
+ endoreg_db/management/commands/validate_ai_models.py,sha256=Z7Ga-PndTFVG8GnkYbS58h8ofiyhnxZDcyP5Qqpl1c8,4684
297
298
  endoreg_db/management/commands/validate_video.py,sha256=cns_kNgztyp6XTeXuDeLEet8vAATkpxZwJuSWuQ5Olk,11302
298
299
  endoreg_db/management/commands/validate_video_files.py,sha256=0lvA0Z8BKiibjyqc4ueI646IIc5bKI3sIOxiiF5_bTk,6509
299
300
  endoreg_db/management/commands/video_validation.py,sha256=xnAoCPB44dmnRbn6FqUjqRXQ-ZhDPNX1T5kCpAU8sgc,771
@@ -464,7 +465,7 @@ endoreg_db/models/medical/risk/risk_type.py,sha256=kEugcaWSTEWH_Vxq4dcF80Iv1L4_K
464
465
  endoreg_db/models/metadata/__init__.py,sha256=8I6oLj3YTmeaPGJpL0AWG5gLwp38QzrEggxSkTisv7c,474
465
466
  endoreg_db/models/metadata/frame_ocr_result.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
466
467
  endoreg_db/models/metadata/model_meta.py,sha256=F_r-PTLeNi4J-4EaGCQkGIguhdl7Bwba7_i56ZAjc-4,7589
467
- endoreg_db/models/metadata/model_meta_logic.py,sha256=6w1YX8hVq40UXbVN1fvDO9OljwekBZaDVHEjVZecoV8,12252
468
+ endoreg_db/models/metadata/model_meta_logic.py,sha256=R2VqcmJb3LmMMM37RMBWpRmfD_GVP3FsmgpAXAoyQPs,15810
468
469
  endoreg_db/models/metadata/pdf_meta.py,sha256=BTmpSgqxmPKi0apcNjyrZAS4AFKCPXVdBd6VBeyyv6E,3174
469
470
  endoreg_db/models/metadata/sensitive_meta.py,sha256=ekLHrW-b5uYcjfkRd0EW5ncx5ef8Bu-K6msDkpWCAbk,13034
470
471
  endoreg_db/models/metadata/sensitive_meta_logic.py,sha256=by3eCW8CgglK1SHiDOepHhTOGaugswxJhkH0BZp7-gs,33909
@@ -602,7 +603,7 @@ endoreg_db/services/pseudonym_service.py,sha256=CJhbtRa6K6SPbphgCZgEMi8AFQtB18CU
602
603
  endoreg_db/services/requirements_object.py,sha256=290zf8AEbVtCoHhW4Jr7_ud-RvrqYmb1Nz9UBHtTnc0,6164
603
604
  endoreg_db/services/segment_sync.py,sha256=YgHvIHkbW4mqCu0ACf3zjRSZnNfxWwt4gh5syUVXuE0,6400
604
605
  endoreg_db/services/storage_aware_video_processor.py,sha256=kKFK64vXLeBSVkp1YJonU3gFDTeXZ8C4qb9QZZB99SE,13420
605
- endoreg_db/services/video_import.py,sha256=PNAHHZHzge2TYDaZP63CL-sslj01CxFky6sEi6Twavg,46045
606
+ endoreg_db/services/video_import.py,sha256=5a73s0Au0kgZFbrsD4WUqmDAqhQmuf9_wqs79SI-byE,47356
606
607
  endoreg_db/tasks/upload_tasks.py,sha256=OJq7DhNwcbWdXzHY8jz5c51BCVkPN5gSWOz-6Fx6W5M,7799
607
608
  endoreg_db/tasks/video_ingest.py,sha256=kxFuYkHijINV0VabQKCFVpJRv6eCAw07tviONurDgg8,5265
608
609
  endoreg_db/tasks/video_processing_tasks.py,sha256=rZ7Kr49bAR4Q-vALO2SURebrhcJ5hSFGwjF4aULrOao,14089
@@ -786,7 +787,7 @@ endoreg_db/views/video/video_meta.py,sha256=C1wBMTtQb_yzEUrhFGAy2UHEWMk_CbU75WXX
786
787
  endoreg_db/views/video/video_processing_history.py,sha256=mhFuS8RG5GV8E-lTtuD0qrq-bIpnUFp8vy9aERfC-J8,770
787
788
  endoreg_db/views/video/video_remove_frames.py,sha256=2FmvNrSPM0fUXiBxINN6vBUUDCqDlBkNcGR3WsLDgKo,1696
788
789
  endoreg_db/views/video/video_stream.py,sha256=kLyuf0ORTmsLeYUQkTQ6iRYqlIQozWhMMR3Lhfe_trk,12148
789
- endoreg_db-0.8.3.9.dist-info/METADATA,sha256=ByxNYCIC-wIFfuG-7mfsrJ6KJumFz0K17X3-ABUuhCs,14758
790
- endoreg_db-0.8.3.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
791
- endoreg_db-0.8.3.9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
792
- endoreg_db-0.8.3.9.dist-info/RECORD,,
790
+ endoreg_db-0.8.4.1.dist-info/METADATA,sha256=TmIf-CR3u-Mx2h06sKN1XHpfDx8vh5R3hbrsDZDgJPw,14758
791
+ endoreg_db-0.8.4.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
792
+ endoreg_db-0.8.4.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
793
+ endoreg_db-0.8.4.1.dist-info/RECORD,,