-1

I have 3 endpoints in my flask.

  1. /candies with GET methods
  2. /chocolates with GET methods
  3. /gifts with post methods and request body (candy(int), chocolate(int))

The code is worked when I do a post with 2 parameters (chocolate and candy), but when I just do one (chocolate or candy), the output is KeyError. Here is my code:

from flask import Flask, current_app, request
    def create_app():
        app = Flask(__name__)
        app.config["candies"] = 0
        app.config["chocolates"] = 0 

        return app
app = create_app()

app.route("/candies", methods=["GET"])
def get_candies():
    candies = current_app.config["candies"]
    if candies == 1:
        return {"message" : f"I have {candies} candy"}, 200
    else:
        return {"message" : f"I have {candies} candies"}, 200

@app.route("/chocolates", methods=["GET"])
def get_chocolate():
    chocolates = current_app.config["chocolates"]
    if chocolates == 1:
        return {"message" : f"I have {chocolates} chocolate"}, 200
    else :
        return {"message" : f"I have {chocolates} chocolates"}, 200

@app.route("/gifts", methods=["POST"])
def gift():
    body = request.json
    cands = body["candy"]
    chocs = body["chocolate"]
    cur_chocs = current_app.config["chocolates"]
    cur_cands = current_app.config["candies"]
    
    if cands == None or chocs == None:
        return {"error": "No gifts for today :("}, 400
    elif cands <=0 or chocs <=0 :
        return {"error": "We need real candies and chocolates"}, 400
    
    fnl_chocs = cur_chocs + chocs 
    fnl_cands = cur_cands + cands
    current_app.config["chocolates"] = fnl_chocs
    current_app.config["candies"] = fnl_cands
    return {"message": "Gifts are well received!"}, 201

HERE IS MY TESTING CODE:

if __name__ == "__main__":
    app.config.update({"TESTING": True})
    c = app.test_client()

    initial_candies_response = c.get("/candies")
    print(initial_candies_response.json)
    assert initial_candies_response.json == {"message": "I have 0 candies"}
    assert initial_candies_response.status_code == 200

    initial_chocs_response = c.get("/chocolates")
    print(initial_chocs_response.json)
    assert initial_chocs_response.json == {"message": "I have 0 chocolates"}
    assert initial_chocs_response.status_code == 200

    gift_response = c.post("/gifts", json={"candy": 5, "chocolate": 3})
    print(gift_response.json)
    assert gift_response.json == {"message": "Gifts are well received!"}
    assert gift_response.status_code == 201

    post_gift_candies_response = c.get("/candies")
    print(post_gift_candies_response.json)
    assert post_gift_candies_response.json == {"message": "I have 5 candies"}
    assert post_gift_candies_response.status_code == 200


    post_gift_chocolates_response = c.get("/chocolates")
    print(post_gift_chocolates_response.json)
    assert post_gift_chocolates_response.json == {"message": "I have 3 chocolates"}
    assert post_gift_chocolates_response.status_code == 200
    
    gift_response = c.post("/gifts", json={"chocolate": 3})
    print(gift_response.json)
    assert gift_response.json == {"message": "Gifts are well received!"}
    assert gift_response.status_code == 201
    

    post_gift_chocolates_response = c.get("/chocolates")
    print(post_gift_chocolates_response.json)
    assert post_gift_chocolates_response.json == {"message": "I have 6 chocolates"}
    assert post_gift_chocolates_response.status_code == 200
    
    print("Testing p2.py DONE!")

And here is the output:

{'message': 'I have 0 candies'}
{'message': 'I have 0 chocolates'}
{'message': 'Gifts are well received!'}
{'message': 'I have 5 candies'}
{'message': 'I have 3 chocolates'}
Traceback (most recent call last):
  File "/home/ray/SC/startup-campus-backend/Assignments/Assignment4/p2.py", line 146, in <module>
    gift_response = c.post("/gifts", json={"chocolate": 3})

    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
  File "/home/ray/SC/startup-campus-backend/Assignments/Assignment4/p2.py", line 99, in gift
    cands = body["candy"]
KeyError: 'candy'
maanijou
  • 1,067
  • 1
  • 14
  • 23
Alex
  • 1
  • 1

1 Answers1

0

when i just do one (chocolate or candy) the output is KeyError

Use json.get("key"), which will default to None if the key doesn't exist

For example

    cands = body.get("candy")
    chocs = body.get("chocolate")
    
    if cands == None or chocs == None:
        return {"error": "No gifts for today :("}, 400
    elif cands <= 0 or chocs <= 0:
        return {"error": "We need real candies and chocolates"}, 400

    cur_chocs = current_app.config["chocolates"]
    cur_cands = current_app.config["candies"]

Then you'll need to update your tests since cands == None will be True, so the response will not be 201

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • if i put body.get in candy and chocolate, the output will be like this : line 99, in gift cands = body.get["candy"] TypeError: 'builtin_function_or_method' object is not subscriptable – Alex Oct 03 '22 at 21:28
  • 1
    Look again. `.get()` is a function. Parenthesis, not square brackets – OneCricketeer Oct 03 '22 at 21:30