Coverage for backend/django/core/auxiliary/models/UploadSession.py: 68%
51 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
1from django.conf import settings
2from django.db import models
4from core.managers import IdentityAccessControlManager
5from flowsheetInternals.unitops.models import SimulationObject
8class UploadSessionPurpose(models.TextChoices):
9 ML_TRAINING_CSV = "ml_training_csv"
10 SCENARIO_CSV = "scenario_csv"
11 PINCH_UTILITY_CSV = "pinch_utility_csv"
14class UploadSessionStatus(models.TextChoices):
15 INITIATED = "initiated"
16 UPLOADING = "uploading"
17 COMPLETED = "completed"
18 ABORTED = "aborted"
19 FAILED = "failed"
20 EXPIRED = "expired"
23class UploadSession(models.Model):
24 created_by = models.ForeignKey(
25 settings.AUTH_USER_MODEL,
26 on_delete=models.CASCADE,
27 related_name="upload_sessions",
28 )
29 flowsheet = models.ForeignKey(
30 "Flowsheet",
31 on_delete=models.CASCADE,
32 related_name="upload_sessions",
33 )
34 flowsheet_state = models.ForeignKey(
35 "FlowsheetState",
36 on_delete=models.SET_NULL,
37 related_name="upload_sessions",
38 null=True,
39 blank=True,
40 )
41 scenario = models.ForeignKey(
42 "Scenario",
43 on_delete=models.SET_NULL,
44 related_name="upload_sessions",
45 null=True,
46 blank=True,
47 )
48 simulationObject = models.ForeignKey(
49 SimulationObject,
50 on_delete=models.SET_NULL,
51 related_name="upload_sessions",
52 null=True,
53 blank=True,
54 )
55 purpose = models.CharField(max_length=32, choices=UploadSessionPurpose.choices)
56 bucket = models.CharField(max_length=255)
57 object_key = models.CharField(max_length=1024, unique=True)
58 s3_upload_id = models.CharField(max_length=512)
59 original_filename = models.CharField(max_length=255)
60 content_type = models.CharField(max_length=255, blank=True, default="")
61 size_bytes = models.BigIntegerField()
62 status = models.CharField(
63 max_length=16,
64 choices=UploadSessionStatus.choices,
65 default=UploadSessionStatus.INITIATED,
66 )
67 csv_headers = models.JSONField(default=list, blank=True)
68 csv_delimiter = models.CharField(max_length=1, blank=True, default="")
69 csv_warnings = models.JSONField(default=list, blank=True)
70 csv_inspected_at = models.DateTimeField(null=True, blank=True)
71 created_at = models.DateTimeField(auto_now_add=True)
72 completed_at = models.DateTimeField(null=True, blank=True)
73 expires_at = models.DateTimeField(null=True, blank=True)
75 objects = IdentityAccessControlManager()
77 def clean(self):
78 """Require operational provenance to resolve within one stable flowsheet."""
80 super().clean()
81 if self.flowsheet_state_id is None:
82 return
83 if self.flowsheet_state.flowsheet_id != self.flowsheet_id:
84 from django.core.exceptions import ValidationError
86 raise ValidationError(
87 {"flowsheet_state": "Upload state must belong to the upload flowsheet."}
88 )
89 for field_name in ("scenario", "simulationObject"):
90 related = getattr(self, field_name, None)
91 if related is not None and related.flowsheet_state_id != self.flowsheet_state_id:
92 from django.core.exceptions import ValidationError
94 raise ValidationError(
95 {field_name: "Upload source must belong to the upload state."}
96 )
98 class Meta:
99 indexes = [
100 models.Index(fields=["purpose", "status"]),
101 models.Index(fields=["expires_at"]),
102 ]