#1036 frontend: fix api_2 for marshmallow 3+
Closed 4 years ago by praiskup. Opened 4 years ago by dturecek.
copr/ dturecek/copr fix-marshmallow  into  master

@@ -36,8 +36,14 @@ 

  def render_build(build, self_params=None):

      if self_params is None:

          self_params = {}

+ 

+     build_data = BuildSchema().dump(build)

+     try:

+         build_data = build_data[0]

This hack is used on several places, I guess it could be done in the schema itself, we can call the method dump_compat() e.g. ... and we can document why we are doing this hack :-) it isn't obvious to me, tbh.

+     except KeyError:

+         pass

      return {

-         "build": BuildSchema().dump(build)[0],

+         "build": build_data,

          "_links": {

              "self": {"href": url_for(".buildr", build_id=build.id, **self_params)},

              "project": {"href": url_for(".projectr", project_id=build.copr_id)},

@@ -79,7 +79,9 @@ 

          """

          :return: if of the created build or raise Exception

          """

-         build_params = mm_deserialize(BuildCreateFromUrlSchema(), req.data.decode("utf-8")).data

+         build_params = mm_deserialize(BuildCreateFromUrlSchema(), req.data.decode("utf-8"))

+         build_params = getattr(build_params, "data", build_params)

+ 

          project = get_project_safe(build_params["project_id"])

  

          chroot_names = build_params.pop("chroots")
@@ -117,7 +119,9 @@ 

              raise MalformedRequest("Missing srpm file in the request")

          srpm_handle = req.files["srpm"]

  

-         build_params = mm_deserialize(BuildCreateSchema(), metadata).data

+         build_params = mm_deserialize(BuildCreateSchema(), metadata)

+         build_params = getattr(build_params, "data", build_params)

+ 

          project_id = build_params["project_id"]

  

          project = get_project_safe(project_id)
@@ -207,7 +211,8 @@ 

      @rest_api_auth_required

      def put(self, build_id):

          build = get_build_safe(build_id)

-         build_dict = mm_deserialize(BuildSchema(), flask.request.data.decode("utf-8")).data

+         build_dict = mm_deserialize(BuildSchema(), flask.request.data.decode("utf-8"))

+         build_dict = getattr(build_dict, "data", build_dict)

          try:

              if not build.canceled and build_dict["state"] == "canceled":

                  BuildsLogic.cancel_build(flask.g.user, build)

@@ -10,8 +10,13 @@ 

  

  

  def render_mock_chroot(chroot):

+     mock_chroot = MockChrootSchema().dump(chroot)

+     try:

+         mock_chroot = mock_chroot[0]

+     except KeyError:

+         pass

      return {

-         "chroot": MockChrootSchema().dump(chroot)[0],

+         "chroot": mock_chroot,

          "_links": {

              "self": {"href": url_for(".mockchrootr", name=chroot.name)},

          },

@@ -31,7 +31,7 @@ 

          user = flask.g.user

          result = mm_deserialize(ProjectCreateSchema(), flask.request.data.decode("utf-8"))

  

-         req = result.data

+         req = getattr(result, "data", result)

          name = req.pop("name")

  

          selected_chroots = req.pop("chroots", None)
@@ -158,7 +158,8 @@ 

          """

          project = get_project_safe(project_id)

  

-         project_dict = mm_deserialize(ProjectSchema(), flask.request.data.decode("utf-8")).data

+         project_dict = mm_deserialize(ProjectSchema(), flask.request.data.decode("utf-8"))

+         project_dict = getattr(project_dict, "data", project_dict)

          # pprint(project_dict)

  

          for k, v in project_dict.items():

@@ -45,7 +45,7 @@ 

          chroot_data = mm_deserialize(CoprChrootCreateSchema(),

                                       flask.request.data.decode("utf-8"))

  

-         req = chroot_data.data

+         req = getattr(chroot_data, "data", chroot_data)

          name = req.pop("name")

  

          try:
@@ -107,11 +107,12 @@ 

          chroot = self._get_chroot_safe(project, name)

  

          chroot_data = mm_deserialize(CoprChrootSchema(), flask.request.data.decode("utf-8"))

+         chroot_data = getattr(chroot_data, "data", chroot_data)

          try:

              updated_chroot = CoprChrootsLogic.update_chroot(

                  user=flask.g.user,

                  copr_chroot=chroot,

-                 **chroot_data.data

+                 **chroot_data

              )

          except InsufficientRightsException as err:

              raise AccessForbidden("Failed to update copr chroot: {}".format(err))

@@ -28,12 +28,12 @@ 

  

  

  class SpaceSeparatedList(fields.Field):

-     def _serialize(self, value, attr, obj):

+     def _serialize(self, value, attr, obj, **kwargs):

          if value is None:

              return []

          return value.split()

  

-     def _deserialize(self, value, attr=None, data=None):

+     def _deserialize(self, value, attr=None, data=None, **kwargs):

          if value is None:

              return ""

          elif not isinstance(value, Iterable) or isinstance(value, string_types):
@@ -50,7 +50,7 @@ 

      { name: "pkg", version: "pkg version" }

      we implement only the serialization, since field is read-only

      """

-     def _serialize(self, value, attr, obj):

+     def _serialize(self, value, attr, obj, **kwargs):

          if value is None:

              return []

          result = []

@@ -5,9 +5,17 @@ 

  

  from flask_restful.reqparse import Argument, RequestParser

  

+ from marshmallow.exceptions import ValidationError

  from .exceptions import ObjectNotFoundError, MalformedRequest

  from .schemas import AllowedMethodSchema

  

+ loads_kwargs = {}

+ try:

+     from marshmallow.utils import EXCLUDE

+     loads_kwargs = {"unknown": EXCLUDE}

+ except ImportError:

+     pass

+ 

  

  class AllowedMethod(object):

      def __init__(self, method, doc, require_auth=True, params=None):
@@ -44,14 +52,14 @@ 

  

  def mm_deserialize(schema, json_string):

      try:

-         result = schema.loads(json_string)

-     except ValueError as err:

+         result = schema.loads(json_string, **loads_kwargs)

+     except (ValueError, ValidationError) as err:

          raise MalformedRequest(

              msg="Failed to parse request: {}".format(err),

              data={"request_string": json_string}

          )

  

-     if result.errors:

+     if getattr(result, "errors", False):

          raise MalformedRequest(

              msg="Failed to parse request: Validation Error",

              data={
@@ -63,7 +71,12 @@ 

  

  

  def mm_serialize_one(schema, obj):

-     return schema().dump(obj)[0]

+     serialized_schema = schema().dump(obj)

+     try:

+         serialized_schema = serialized_schema[0]

+     except KeyError:

+         pass

+     return serialized_schema

  

  

  class MyArg(Argument):