-2

I have the following Python3 code to check if a attribute is in a JSON (or has a value different than null)

def has_attribute(data, attribute):
    return (attribute in data) and (data[attribute] is not None)

This is the function which checks that the attribute is in the JSON and has a value different than null.

if has_attribute(json_request,"offer_id"):
        print("IT IS")
else:
        print("NO")

The thing is that when I pass a JSON, it doesn't print anything. Why?

This code is in a flask app.

I tested this code sending a json object (which is a simple json object like {"a":"a","b":"b"}) through Postman.
When the query is done it is received because I see the json that flask received but none of the prints from the if..else is printed.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Marc
  • 19
  • 5
  • `json_request` is what type of object? This works fine with a dictionary – OneCricketeer Jan 21 '18 at 19:46
  • @cricket_007, it's just a simple object with some attributes which are strings – Marc Jan 21 '18 at 19:47
  • Please show a [mcve] of the problem – OneCricketeer Jan 21 '18 at 19:47
  • There is a difference between "a simple object" without a defined `__getattr__` and a dictionary – OneCricketeer Jan 21 '18 at 19:51
  • @cricket_007 I have updated the question with more details. It is the minimal, complete and verifiable example. I mean, it cannot be more simplified. – Marc Jan 21 '18 at 19:53
  • 2
    It is *not* a minimal, complete, and verifiable example. But regardless, I am confused. JSON is a *text-based serialization format*. Are you working with text? Or, are you working with some Python object you *deserialized* from the JSON text? In which case, this question doesn't really have anything to do with JSON... As an aside, if `data` is in fact a `dict`, then your function could simply be `return data.get(attribute) is not None` – juanpa.arrivillaga Jan 21 '18 at 19:59
  • It may be minimal, but not verifiable until you show the Flask code and tell us what `type(json_request)` returns – OneCricketeer Jan 21 '18 at 20:07
  • @cricket_007, Thank you for the advises. The type of the json is – Marc Jan 21 '18 at 20:11
  • 2
    @MarcBenedí *then it is **not** JSON*. – juanpa.arrivillaga Jan 21 '18 at 20:16

2 Answers2

0

JSON isn't a type in Python. It is either a string, or a dictionary.

For example, your code works fine when testing a dictionary

def has_attribute(data, attribute):
    return (attribute in data) and (data[attribute] is not None)

json_request = {'foo' : None, 'hello' : 'world'}

print("IT IS" if has_attribute(json_request, "foo") else "NO")  # NO
print("IT IS" if has_attribute(json_request, "bar") else "NO")  # NO
print("IT IS" if has_attribute(json_request, "hello") else "NO")  # IT IS

Likewise, it would also work if you did import json; json_request = json.loads(some_json_string) because that returns you a dictionary.

If you were testing a class, you would need to rewrite this using getattr() built-in function

class A:
  def __init__(self):
    self.x = None
    self.y = 'a'

  def has_attribute(self, attribute):
    return getattr(self, attribute, None) is not None

a = A()
print("IT IS" if a.has_attribute("foo") else "NO")  # NO
print("IT IS" if a.has_attribute("x") else "NO")  # NO
print("IT IS" if a.has_attribute("y") else "NO")  # IT IS

This code is in a flask app.

  1. Print statements end up in the console / server logs, not the web page or in PostMan. You need to return a string or response object in Flask.
  2. See How to get POSTed json in Flask?

Here's a sample Flask app that works.

from flask import Flask, request
app = Flask(__name__)

def has_attribute(data, attribute):
    return attribute in data and data[attribute] is not None

@app.route("/postit", methods=["POST"])
def postit():
    json_request = request.get_json()
    print(has_attribute(json_request, 'offer_id'))
    return str(has_attribute(json_request, 'offer_id'))

Logs

 $ FLASK_APP=app.py python -m flask run
 * Serving Flask app "app"
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
False
127.0.0.1 - - [21/Jan/2018 14:19:10] "POST /postit HTTP/1.1" 200 -
True
127.0.0.1 - - [21/Jan/2018 14:19:25] "POST /postit HTTP/1.1" 200 -

Request & Response

$ curl -XPOST -H 'Content-Type:application/json' -d'{"offer_id":null}' http://localhost:5000/postit
False
$ curl -XPOST -H 'Content-Type:application/json' -d'{"offer_id":"data"}' http://localhost:5000/postit
True
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • I'm getting the Json with `request.get_json()` from Flask. `@app.route('/aaaaa',methods=['POST']) def request_bed(): bed_request = request.get_json()` – Marc Jan 21 '18 at 20:08
  • I have updated my answer to include working Flask code – OneCricketeer Jan 21 '18 at 20:22
-1

The way you should read from a JSON object should be object[property_name].

For example object[a] will ideally return a based on your example.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Vijay
  • 1,030
  • 11
  • 34