Consume rest endpoint removing payload's unwanted properties and falsy values
Clash 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?
python python-3.x dictionary rest
add a comment |Â
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?
python python-3.x dictionary rest
add a comment |Â
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?
python python-3.x dictionary rest
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?
python python-3.x dictionary rest
asked Apr 6 at 4:19
slackmart
1163
1163
add a comment |Â
add a comment |Â
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
.)
what happens if the API sends the fields in a different order
â PirateApp
Jun 26 at 0:58
add a comment |Â
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
.)
what happens if the API sends the fields in a different order
â PirateApp
Jun 26 at 0:58
add a comment |Â
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
.)
what happens if the API sends the fields in a different order
â PirateApp
Jun 26 at 0:58
add a comment |Â
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
.)
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
.)
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
add a comment |Â
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
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password