/
asyncsubmit.py
executable file
·149 lines (123 loc) · 4.83 KB
/
asyncsubmit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import datetime
from collections import namedtuple
from django.utils import timezone
from django.contrib.auth import get_user_model
from django.http import HttpResponse, HttpRequest
from django.shortcuts import get_object_or_404
from rest_framework import status
from rest_framework.response import Response
import paramtools as pt
from webapp.apps.users.models import Project
from webapp.apps.comp import actions
from webapp.apps.comp.constants import OUT_OF_RANGE_ERROR_MSG, WEBAPP_VERSION
from webapp.apps.comp.compute import Compute
from webapp.apps.comp.exceptions import ValidationError, BadPostException
from webapp.apps.comp.ioutils import IOClasses
from webapp.apps.comp.models import Inputs, Simulation
from webapp.apps.comp.serializers import InputsSerializer
User = get_user_model()
class SubmitInputs:
webapp_version = WEBAPP_VERSION
def __init__(
self,
request: HttpRequest,
project: Project,
ioutils: IOClasses,
compute: Compute,
sim: Simulation,
):
self.request = request
self.user = self.request.user
self.project = project
self.ioutils = ioutils
self.compute = compute
self.badpost = None
self.meta_parameters = ioutils.model_parameters.meta_parameters_parser()
self.sim = sim
def submit(self):
self.ser = InputsSerializer(instance=self.sim.inputs, data=self.request.data)
is_valid = self.ser.is_valid()
if not is_valid:
raise BadPostException(self.ser.errors)
validated_data = self.ser.validated_data
meta_parameters = validated_data.get("meta_parameters", {})
adjustment = validated_data.get("adjustment", {})
parent_model_pk = validated_data.pop("parent_model_pk", None)
notify_on_completion = validated_data.pop("notify_on_completion", None)
if parent_model_pk is not None and self.sim.parent_sim is None:
parent_sim = get_object_or_404(
Simulation, project=self.project, model_pk=parent_model_pk
)
else:
parent_sim = None
try:
self.meta_parameters.adjust(meta_parameters)
self.valid_meta_params = self.meta_parameters.specification(
meta_data=False, serializable=True
)
errors = None
except pt.ValidationError as ve:
errors = str(ve)
if errors:
raise BadPostException(errors)
parser = self.ioutils.Parser(
self.project,
self.ioutils.model_parameters,
adjustment,
compute=self.compute,
**self.valid_meta_params,
)
result = parser.parse_parameters()
self.inputs = self.ser.save(
meta_parameters=self.valid_meta_params,
adjustment=result["adjustment"],
errors_warnings=result["errors_warnings"],
custom_adjustment=result["custom_adjustment"],
job_id=result["job_id"],
status="PENDING",
parent_sim=self.sim.parent_sim or parent_sim,
model_config=self.ioutils.model_parameters.config,
)
# case where parent sim exists and has not yet been assigned
if not self.sim.parent_sim and parent_sim:
self.sim.parent_sim = parent_sim
self.sim.title = parent_sim.title
self.sim.readme = parent_sim.readme
if notify_on_completion is not None:
self.sim.notify_on_completion = notify_on_completion
self.sim.save()
elif notify_on_completion is not None:
self.sim.notify_on_completion = notify_on_completion
self.sim.save()
return self.inputs
class SubmitSim:
def __init__(self, sim: Simulation, compute: Compute):
self.compute = compute
self.sim = sim
def submit(self):
inputs = self.sim.inputs
data = {
"meta_param_dict": inputs.meta_parameters,
"adjustment": inputs.deserialized_inputs,
}
print("submit", data)
self.submitted_id, self.max_q_length = self.compute.submit_job(
data, inputs.project.worker_ext(action=actions.SIM)
)
print(f"job id: {self.submitted_id}")
print(f"q lenghth: {self.max_q_length}")
self.sim = self.save()
return self.sim
def save(self):
sim = self.sim
sim.status = "PENDING"
sim.job_id = self.submitted_id
sim.sponsor = sim.project.sponsor
cur_dt = timezone.now()
future_offset_seconds = (self.max_q_length) * sim.project.exp_task_time
future_offset = datetime.timedelta(seconds=future_offset_seconds)
expected_completion = cur_dt + future_offset
sim.exp_comp_datetime = expected_completion
sim.creation_date = cur_dt
sim.save()
return sim