def put(self, request, *args, **kwargs): print("myinputs api method=PUT", kwargs) if request.user.username == "comp-api-user": data = request.data ser = InputsSerializer(data=request.data) if ser.is_valid(): data = ser.validated_data inputs = get_object_or_404(Inputs, job_id=data["job_id"]) print("data") print(data) if inputs.status == "PENDING": # successful run if data["status"] == "SUCCESS": inputs.errors_warnings = data["errors_warnings"] inputs.custom_adjustment = data.get( "custom_adjustment", None) inputs.status = "SUCCESS" if is_valid( inputs) else "INVALID" inputs.save() if inputs.status == "SUCCESS": submit_sim = SubmitSim(inputs, compute=Compute()) submit_sim.submit() # failed run, exception was caught else: inputs.status = "FAIL" inputs.traceback = data["traceback"] inputs.save() return Response(status=status.HTTP_200_OK) else: print("inputs put error", ser.errors) return Response(ser.errors, status=status.HTTP_400_BAD_REQUEST) else: return Response(status=status.HTTP_401_UNAUTHORIZED)
def test_write_access(db, get_inputs, meta_param_dict): modeler = User.objects.get(username="******").profile inputs = _submit_inputs("Used-for-testing", get_inputs, meta_param_dict, modeler) _, submit_sim = _submit_sim(inputs) sim = submit_sim.submit() sim.status = "SUCCESS" sim.save() factory = APIRequestFactory() req = factory.get("/") req.user = modeler.user data = SimulationSerializer(instance=sim).data assert data["role"] == None assert "pending_permissions" not in data assert "access" not in data data = SimulationSerializer(instance=sim, context={"request": req}).data assert data["role"] == "admin" assert "pending_permissions" in data assert "access" in data data = InputsSerializer(instance=sim.inputs).data assert data["role"] == None data = InputsSerializer(instance=sim.inputs, context={"request": req}).data assert data["role"] == "admin"
class SubmitInputs: webapp_version = WEBAPP_VERSION def __init__( self, request: HttpRequest, project: Project, ioutils: IOClasses, compute: Compute, ): self.request = request self.user = self.request.user self.project = project self.ioutils = ioutils self.compute = compute self.badpost = None self.meta_parameters = ioutils.displayer.parsed_meta_parameters() def submit(self): print(self.request.data) self.ser = InputsSerializer(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", {}) try: self.valid_meta_params = self.meta_parameters.validate( meta_parameters) errors = None except ValidationError as ve: errors = str(ve) if errors: raise BadPostException(errors) parser = self.ioutils.Parser( self.project, self.ioutils.displayer, 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"], project=self.project, owner=getattr(self.request.user, "profile", None), job_id=result["job_id"], status="PENDING", ) return self.inputs
def post(self, request, *args, **kwargs): print("inputs api method=POST", request.POST, kwargs) ser = InputsSerializer(data=request.data) if ser.is_valid(): data = ser.validated_data if "meta_parameters" in data: meta_parameters = data["meta_parameters"] else: meta_parameters = {} return self.get_inputs(kwargs, meta_parameters) else: return Response(ser.errors, status=status.HTTP_400_BAD_REQUEST)
def post(self, request, *args, **kwargs): compute = Compute() project = get_object_or_404( self.queryset, owner__user__username=kwargs["username"], title=kwargs["title"], ) ioutils = get_ioutils(project, Parser=APIParser) try: submit_inputs = SubmitInputs(request, project, ioutils, compute) result = submit_inputs.submit() except BadPostException as bpe: return Response(bpe.errors, status=status.HTTP_400_BAD_REQUEST) except AppError as ae: try: send_mail( f"Compute Studio AppError", (f"An error has occurred:\n {ae.parameters}\n causing: " f"{ae.traceback}\n user:{request.user.username}\n " f"project: {project.app_url}."), "*****@*****.**", ["*****@*****.**"], fail_silently=True, ) # Http 401 exception if mail credentials are not set up. except Exception: pass return Response(ae.traceback, status=status.HTTP_500_INTERNAL_SERVER_ERROR) inputs = InputsSerializer(result) return Response(inputs.data, status=status.HTTP_201_CREATED)
def submit(request, success_status, project, sim): compute = Compute() ioutils = get_ioutils(project, Parser=APIParser) try: submit_inputs = SubmitInputs(request, project, ioutils, compute, sim) result = submit_inputs.submit() except BadPostException as bpe: return Response(bpe.errors, status=status.HTTP_400_BAD_REQUEST) except AppError as ae: try: send_mail( f"Compute Studio AppError", (f"An error has occurred:\n {ae.parameters}\n causing: " f"{ae.traceback}\n user:{request.user.username}\n " f"project: {project.app_url}."), "*****@*****.**", ["*****@*****.**"], fail_silently=True, ) # Http 401 exception if mail credentials are not set up. except Exception: pass return Response(ae.traceback, status=success_status) inputs = InputsSerializer(result) return Response(inputs.data, status=status.HTTP_201_CREATED)
def test_authors_sorted_alphabetically(db, get_inputs, meta_param_dict): modeler = User.objects.get(username="******").profile inputs = _submit_inputs("Used-for-testing", get_inputs, meta_param_dict, modeler) _, submit_sim = _submit_sim(inputs) sim = submit_sim.submit() sim.status = "SUCCESS" sim.is_public = True sim.save() factory = APIRequestFactory() req = factory.get("/") req.user = modeler.user u = User.objects.create_user("aaaa", "*****@*****.**", "heyhey2222") create_profile_from_user(u) profile = Profile.objects.get(user__username="******") pp, created = PendingPermission.objects.get_or_create( sim=sim, profile=profile, permission_name="add_author") assert created pp.add_author() data = SimulationSerializer(instance=sim, context={"request": req}).data data2 = copy.deepcopy(data) assert sorted(data2["authors"]) == data["authors"] data = SimulationSerializer(instance=sim, context={"request": req}).data data2 = copy.deepcopy(data) assert sorted(data2["authors"]) == data["authors"] data = InputsSerializer(instance=sim.inputs, context={"request": req}).data data2 = copy.deepcopy(data) assert sorted(data2["sim"]["authors"]) == data["sim"]["authors"]
def put(self, request, *args, **kwargs): print("myinputs api method=PUT", kwargs) print("authenticator", request.user, request.successful_authenticator) ser = InputsSerializer(data=request.data) if ser.is_valid(): data = ser.validated_data inputs = get_object_or_404( Inputs.objects.prefetch_related("project"), job_id=data["job_id"]) if not inputs.project.has_write_access(request.user): return Response(status=status.HTTP_401_UNAUTHORIZED) if inputs.status in ("PENDING", "INVALID", "FAIL"): # successful run if data["status"] == "SUCCESS": inputs.errors_warnings = data["errors_warnings"] inputs.custom_adjustment = data.get( "custom_adjustment", None) inputs.status = "SUCCESS" if is_valid( inputs) else "INVALID" inputs.save() if inputs.status == "SUCCESS": submit_sim = SubmitSim(inputs.sim, compute=Compute()) submit_sim.submit() # failed run, exception was caught else: inputs.status = "FAIL" inputs.traceback = data["traceback"] inputs.save() if self.request.is_secure(): protocol = "https" else: protocol = "http" # local dev. base_url = f"{protocol}://{self.request.get_host()}" url = base_url + inputs.get_absolute_url() fail( project=inputs.project, model_pk=inputs.sim.model_pk, traceback=inputs.traceback, url=url, ) return Response(status=status.HTTP_200_OK) else: print("inputs put error", ser.errors) return Response(ser.errors, status=status.HTTP_400_BAD_REQUEST)
def get(self, request, *args, **kwargs): print("myinputs api method=GET", request.GET, kwargs) inputs = get_object_or_404( self.queryset, sim__model_pk=kwargs["model_pk"], project__title__iexact=kwargs["title"], project__owner__user__username__iexact=kwargs["username"], ) if not inputs.has_read_access(request.user): raise PermissionDenied() ser = InputsSerializer(inputs, context={"request": self.request}) return Response(ser.data)
def submit(self): print(self.request.data) self.ser = InputsSerializer(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", {}) try: self.valid_meta_params = self.meta_parameters.validate( meta_parameters) errors = None except ValidationError as ve: errors = str(ve) if errors: raise BadPostException(errors) parser = self.ioutils.Parser( self.project, self.ioutils.displayer, 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"], project=self.project, owner=getattr(self.request.user, "profile", None), job_id=result["job_id"], status="PENDING", ) return self.inputs
def get(self, request, *args, **kwargs): print("myinputs api method=GET", request.GET, kwargs) if "model_pk" in kwargs: inputs = get_object_or_404( self.queryset, outputs__model_pk=kwargs["model_pk"], project__title=kwargs["title"], project__owner__user__username=kwargs["username"], ) else: inputs = self.queryset.get_object_from_hashid_or_404( kwargs["hashid"]) return Response(InputsSerializer(inputs).data)
def post(self, request, *args, **kwargs): project = get_object_or_404( self.projects, owner__user__username__iexact=kwargs["username"], title__iexact=kwargs["title"], ) sim = Simulation.objects.new_sim(user=request.user, project=project) context = {"request": request} data = { "inputs": InputsSerializer(sim.inputs, context=context).data, "sim": SimulationSerializer(sim, context=context).data, } return Response(data, status=status.HTTP_201_CREATED)
def test_write_access(db, get_inputs, meta_param_dict): modeler = User.objects.get(username="******").profile inputs = _submit_inputs("Used-for-testing", get_inputs, meta_param_dict, modeler) _, submit_sim = _submit_sim(inputs) sim = submit_sim.submit() sim.status = "SUCCESS" sim.save() factory = APIRequestFactory() req = factory.get("/") req.user = modeler.user data = SimulationSerializer(instance=sim).data assert data["has_write_access"] == False data = SimulationSerializer(instance=sim, context={"request": req}).data assert data["has_write_access"] == True data = InputsSerializer(instance=sim).data assert data["has_write_access"] == False data = InputsSerializer(instance=sim, context={"request": req}).data assert data["has_write_access"] == True
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.valid_meta_params = self.meta_parameters.validate( meta_parameters) errors = None except ValidationError as ve: errors = str(ve) if errors: raise BadPostException(errors) parser = self.ioutils.Parser( self.project, self.ioutils.displayer, 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, ) # 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 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) is_public = validated_data.pop("is_public", 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 if is_public is not None: self.sim.is_public = is_public self.sim.save() elif notify_on_completion is not None: self.sim.notify_on_completion = notify_on_completion self.sim.save() return self.inputs