Consume rest endpoint removing payload's unwanted properties and falsy values

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite












Let's suppose that there's a third part web service and I want to make a GET
request to it and use the response to feed my project's service.



Next code will allow me to create a dict object only with non-falsy keys' values:



import requests
from abc import ABC, abstractmethod


class AbstractPayload(dict, ABC):
def __new__(cls, *args, **kwargs):
"""Validate: values are not empty and that each key in kwargs exists
in cls.fields iterable, then it creates and returns the final dict
instance using the field and the value as key-value pairs."""
return
field: v for field, v in kwargs.items() if v and field in cls.fields


@property
@abstractmethod
def fields(cls):
"""Valid fields' iterable. Override this as you need."""
pass


class UpdatePayload(AbstractPayload):
fields = ('location', 'capacity', 'maxlatency', 'tags')


# Usage example:
response = requests.get('/thirdpart/device/189')
if response.ok:
requests.patch('/mydevices/33', json=UpdatePayload(**response.json()))


Summary:



  • Avoiding unwanted fields being added to the endpoint patch payload.

  • Having a unique block of code (__new__ method) where the properties are
    gonna be evaluated to discard falsy values.

  • Making it easily adaptable to all the api resources (just inheriting from
    a class and defining a fields iterable)

Questions:



  • What do you think about this approach?

  • Do you have any suggestions to improve it?

  • Or even better, Do you have another cleaner approach?






share|improve this question

























    up vote
    3
    down vote

    favorite












    Let's suppose that there's a third part web service and I want to make a GET
    request to it and use the response to feed my project's service.



    Next code will allow me to create a dict object only with non-falsy keys' values:



    import requests
    from abc import ABC, abstractmethod


    class AbstractPayload(dict, ABC):
    def __new__(cls, *args, **kwargs):
    """Validate: values are not empty and that each key in kwargs exists
    in cls.fields iterable, then it creates and returns the final dict
    instance using the field and the value as key-value pairs."""
    return
    field: v for field, v in kwargs.items() if v and field in cls.fields


    @property
    @abstractmethod
    def fields(cls):
    """Valid fields' iterable. Override this as you need."""
    pass


    class UpdatePayload(AbstractPayload):
    fields = ('location', 'capacity', 'maxlatency', 'tags')


    # Usage example:
    response = requests.get('/thirdpart/device/189')
    if response.ok:
    requests.patch('/mydevices/33', json=UpdatePayload(**response.json()))


    Summary:



    • Avoiding unwanted fields being added to the endpoint patch payload.

    • Having a unique block of code (__new__ method) where the properties are
      gonna be evaluated to discard falsy values.

    • Making it easily adaptable to all the api resources (just inheriting from
      a class and defining a fields iterable)

    Questions:



    • What do you think about this approach?

    • Do you have any suggestions to improve it?

    • Or even better, Do you have another cleaner approach?






    share|improve this question





















      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      Let's suppose that there's a third part web service and I want to make a GET
      request to it and use the response to feed my project's service.



      Next code will allow me to create a dict object only with non-falsy keys' values:



      import requests
      from abc import ABC, abstractmethod


      class AbstractPayload(dict, ABC):
      def __new__(cls, *args, **kwargs):
      """Validate: values are not empty and that each key in kwargs exists
      in cls.fields iterable, then it creates and returns the final dict
      instance using the field and the value as key-value pairs."""
      return
      field: v for field, v in kwargs.items() if v and field in cls.fields


      @property
      @abstractmethod
      def fields(cls):
      """Valid fields' iterable. Override this as you need."""
      pass


      class UpdatePayload(AbstractPayload):
      fields = ('location', 'capacity', 'maxlatency', 'tags')


      # Usage example:
      response = requests.get('/thirdpart/device/189')
      if response.ok:
      requests.patch('/mydevices/33', json=UpdatePayload(**response.json()))


      Summary:



      • Avoiding unwanted fields being added to the endpoint patch payload.

      • Having a unique block of code (__new__ method) where the properties are
        gonna be evaluated to discard falsy values.

      • Making it easily adaptable to all the api resources (just inheriting from
        a class and defining a fields iterable)

      Questions:



      • What do you think about this approach?

      • Do you have any suggestions to improve it?

      • Or even better, Do you have another cleaner approach?






      share|improve this question











      Let's suppose that there's a third part web service and I want to make a GET
      request to it and use the response to feed my project's service.



      Next code will allow me to create a dict object only with non-falsy keys' values:



      import requests
      from abc import ABC, abstractmethod


      class AbstractPayload(dict, ABC):
      def __new__(cls, *args, **kwargs):
      """Validate: values are not empty and that each key in kwargs exists
      in cls.fields iterable, then it creates and returns the final dict
      instance using the field and the value as key-value pairs."""
      return
      field: v for field, v in kwargs.items() if v and field in cls.fields


      @property
      @abstractmethod
      def fields(cls):
      """Valid fields' iterable. Override this as you need."""
      pass


      class UpdatePayload(AbstractPayload):
      fields = ('location', 'capacity', 'maxlatency', 'tags')


      # Usage example:
      response = requests.get('/thirdpart/device/189')
      if response.ok:
      requests.patch('/mydevices/33', json=UpdatePayload(**response.json()))


      Summary:



      • Avoiding unwanted fields being added to the endpoint patch payload.

      • Having a unique block of code (__new__ method) where the properties are
        gonna be evaluated to discard falsy values.

      • Making it easily adaptable to all the api resources (just inheriting from
        a class and defining a fields iterable)

      Questions:



      • What do you think about this approach?

      • Do you have any suggestions to improve it?

      • Or even better, Do you have another cleaner approach?








      share|improve this question










      share|improve this question




      share|improve this question









      asked Apr 6 at 4:19









      slackmart

      1163




      1163




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote













           field: v for field, v in kwargs.items() if v and field in cls.fields


          Feel free to break that into a multi-line comprehension.



          Note that the in has linear cost w.r.t. len(cls.fields).



           """Valid fields' iterable. Override this as you need."""
          pass


          Consider specifying that it shall be a set rather than just an iterable. (Also, I suppose return None would more clearly show that by default we don't return an iterable. Or consider doing an explicit raise.)






          share|improve this answer





















          • what happens if the API sends the fields in a different order
            – PirateApp
            Jun 26 at 0:58










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191375%2fconsume-rest-endpoint-removing-payloads-unwanted-properties-and-falsy-values%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          2
          down vote













           field: v for field, v in kwargs.items() if v and field in cls.fields


          Feel free to break that into a multi-line comprehension.



          Note that the in has linear cost w.r.t. len(cls.fields).



           """Valid fields' iterable. Override this as you need."""
          pass


          Consider specifying that it shall be a set rather than just an iterable. (Also, I suppose return None would more clearly show that by default we don't return an iterable. Or consider doing an explicit raise.)






          share|improve this answer





















          • what happens if the API sends the fields in a different order
            – PirateApp
            Jun 26 at 0:58














          up vote
          2
          down vote













           field: v for field, v in kwargs.items() if v and field in cls.fields


          Feel free to break that into a multi-line comprehension.



          Note that the in has linear cost w.r.t. len(cls.fields).



           """Valid fields' iterable. Override this as you need."""
          pass


          Consider specifying that it shall be a set rather than just an iterable. (Also, I suppose return None would more clearly show that by default we don't return an iterable. Or consider doing an explicit raise.)






          share|improve this answer





















          • what happens if the API sends the fields in a different order
            – PirateApp
            Jun 26 at 0:58












          up vote
          2
          down vote










          up vote
          2
          down vote









           field: v for field, v in kwargs.items() if v and field in cls.fields


          Feel free to break that into a multi-line comprehension.



          Note that the in has linear cost w.r.t. len(cls.fields).



           """Valid fields' iterable. Override this as you need."""
          pass


          Consider specifying that it shall be a set rather than just an iterable. (Also, I suppose return None would more clearly show that by default we don't return an iterable. Or consider doing an explicit raise.)






          share|improve this answer













           field: v for field, v in kwargs.items() if v and field in cls.fields


          Feel free to break that into a multi-line comprehension.



          Note that the in has linear cost w.r.t. len(cls.fields).



           """Valid fields' iterable. Override this as you need."""
          pass


          Consider specifying that it shall be a set rather than just an iterable. (Also, I suppose return None would more clearly show that by default we don't return an iterable. Or consider doing an explicit raise.)







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered May 15 at 4:39









          J_H

          4,317129




          4,317129











          • what happens if the API sends the fields in a different order
            – PirateApp
            Jun 26 at 0:58
















          • what happens if the API sends the fields in a different order
            – PirateApp
            Jun 26 at 0:58















          what happens if the API sends the fields in a different order
          – PirateApp
          Jun 26 at 0:58




          what happens if the API sends the fields in a different order
          – PirateApp
          Jun 26 at 0:58












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191375%2fconsume-rest-endpoint-removing-payloads-unwanted-properties-and-falsy-values%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Chat program with C++ and SFML

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          Will my employers contract hold up in court?