diff --git a/beat/web/experiments/api.py b/beat/web/experiments/api.py index b21eb32c6111cb6e00a9d15a50d019c34d203cf7..e82b7c1f77c83ef2edaf82a72ae51208d2360450 100755 --- a/beat/web/experiments/api.py +++ b/beat/web/experiments/api.py @@ -25,9 +25,6 @@ # # ############################################################################### -import re -import uuid - import simplejson import functools @@ -49,7 +46,11 @@ import beat.core.algorithm import beat.core.toolchain from .models import Experiment -from .serializers import ExperimentSerializer, ExperimentResultsSerializer +from .serializers import ( + ExperimentSerializer, + ExperimentResultsSerializer, + ExperimentCreationSerializer, +) from .permissions import IsDatabaseAccessible from ..common.responses import BadRequestResponse, ForbiddenResponse @@ -102,10 +103,8 @@ class ListCreateExperimentsView(ListCreateContributionView): model = Experiment serializer_class = ExperimentSerializer - - # TODO: no serializer is used by the POST method, but the rest-framework isn't - # happy if we don't declare one - writing_serializer_class = ExperimentSerializer + writing_serializer_class = ExperimentCreationSerializer + namespace = "api_experiments" def get(self, request, author_name): def _getStatusLabel(status): @@ -174,134 +173,6 @@ class ListCreateExperimentsView(ListCreateContributionView): # Returns the results return Response(processed_result) - def post(self, request, author_name): - data = request.data - - if "name" in data: - if not (isinstance(data["name"], six.string_types)): - return BadRequestResponse("Invalid name") - - max_length = self.model._meta.get_field("name").max_length - current_length = len(data["name"]) - if current_length > max_length: - return BadRequestResponse( - "name too long, max is {}, current is {}".format( - max_length, current_length - ) - ) - - name = re.sub(r"[\W]", "-", data["name"]) - else: - name = None - - if "short_description" in data: - if not (isinstance(data["short_description"], six.string_types)): - return BadRequestResponse("Invalid short_description") - - max_length = self.model._meta.get_field("short_description").max_length - current_length = len(data["short_description"]) - if current_length > max_length: - return BadRequestResponse( - "Short description too long, max is {}, current is {}".format( - max_length, current_length - ) - ) - - short_description = data["short_description"] - else: - short_description = "" - - if "description" in data: - if not (isinstance(data["description"], six.string_types)): - raise serializers.ValidationError( - {"description": "Invalid description data"} - ) - description = data["description"] - try: - validate_restructuredtext(description) - except ValidationError as errors: - raise serializers.ValidationError( - {"description": [error for error in errors]} - ) - else: - description = None - - if "toolchain" not in data: - return BadRequestResponse("Must indicate a toolchain name") - - if not (isinstance(data["toolchain"], six.string_types)): - return BadRequestResponse("Invalid toolchain name") - - if "declaration" not in data: - return BadRequestResponse("Must indicate a declaration") - - if not (isinstance(data["declaration"], dict)) and not ( - isinstance(data["declaration"], six.string_types) - ): - return BadRequestResponse("Invalid declaration") - - if isinstance(data["declaration"], dict): - declaration = data["declaration"] - else: - declaration_string = data["declaration"] - try: - declaration = simplejson.loads(declaration_string) - except simplejson.errors.JSONDecodeError: - return BadRequestResponse("Invalid declaration data") - - # Retrieve the toolchain - core_toolchain = beat.core.toolchain.Storage(settings.PREFIX, data["toolchain"]) - - if core_toolchain.version == "unknown": - return BadRequestResponse("Unknown toolchain version") - - if core_toolchain.username is None: - core_toolchain.username = request.user.username - - try: - db_toolchain = Toolchain.objects.for_user(request.user, True).get( - author__username=core_toolchain.username, - name=core_toolchain.name, - version=core_toolchain.version, - ) - except Toolchain.DoesNotExist: - return Response("Toolchain %s not found" % data["toolchain"], status=404) - - # Create the experiment object in the database - existing_names = map( - lambda x: x.name, - Experiment.objects.filter(author=request.user, toolchain=db_toolchain), - ) - if name is None: - name = str(uuid.uuid4()) - while name in existing_names: - name = str(uuid.uuid4()) - - elif name in existing_names: - return BadRequestResponse("The name '" + name + "' is already used") - - experiment, toolchain, errors = Experiment.objects.create_experiment( - author=request.user, - toolchain=db_toolchain, - name=name, - short_description=short_description, - description=description, - declaration=declaration, - ) - - if not experiment: - return BadRequestResponse(errors) - - # Send the result - result = { - "name": experiment.fullname(), - "url": reverse("api_experiments:all") + experiment.fullname() + "/", - } - - response = Response(result, status=201) - response["Location"] = result["url"] - return response - # ----------------------------------------------------------