Search code examples
pythonflaskflask-restful

Flask-restful: Request returns wrong value


For a small project at home I have tried to set a simple RESTful server up. I'm struggling with a problem, that the server returns values I would not expect.

Here is an abstract example describing my problem:

# coding: utf-8
import platform as p

from flask import Flask, request
from flask_restful import Resource, Api
from flask_cors import CORS

app = Flask(__name__)
CORS(app)
api = Api(app)

hosts = {"keyA": ["Altair", "Deneb"], "keyB": ["RB3"]}

def in_host_list(hostname, key="keyA"):
    t_hosts = hosts["keyA"]
    if (key == "keyB"):
        t_hosts += hosts["keyB"]
    return hostname in t_hosts

class MainHosts(Resource):
    def get(self):
        return {p.node(): in_host_list(p.node(), "keyA")}

class AllHosts(Resource):
    def get(self):
        return {p.node(): in_host_list(p.node(), "keyB")}

api.add_resource(MainHosts, '/mainhosts')
api.add_resource(AllHosts, '/allhosts')

if __name__ == "__main__":
    app.run(host='0.0.0.0', port='5002', threaded=True)

My problem is the following one. Let's say I've started the python script and there has been no request yet. My first request looks like this

curl http://rb3:5002/mainhosts
{"RB3": false}

The response is what I would expect. The next request is the following one.

curl http://rb3:5002/allhosts
{"RB3": true}

This is also as expected. But when I try to the following, I get a weird response.

curl http://rb3:5002/mainhosts
{"RB3": true}

I would expect the same response as in my first call ({"RB3": false}). And even if I switch the computer and do a fresh request, I get the same result. So I'm asuming, that flask stores somehow a certain state? This behavior only changes, when I restart my python script. Then, the first call is correct but all following requests will give me another response than I would expect.

What am I doing wrong? First I thought that I'm accessing a cookie or a session. But when I switch to another computer and try to access the API, I also get the wrong data displayed. I've read over the documentation of flask and flask-restful. I've also read about Application Context and Request Context, but I'm missing something. Maybe someone of you can give me a helpful hint.


Solution

  • You altered the KeyA list, appending the KeyB list to it:

    t_hosts = hosts["keyA"]
    if (key == "keyB"):
        t_hosts += hosts["keyB"]
    

    This altered the list in place; += augmented assignment is not just a simple concatenation creating a new list object. You can either first create a copy of the list, or create a new list from concatenation.

    To create a copy, call list() on hosts["keyA"]:

    t_hosts = list(hosts["keyA"])
    if key == "keyB":
        t_hosts += hosts["keyB"]
    

    or creating a new list by concatenating, use:

    t_hosts = hosts["keyA"]
    if key == "keyB":
        t_hosts = t_hosts + hosts["keyB"]