Home > Back-end >  Flask: The browser (or proxy) sent a request that this server could not understand
Flask: The browser (or proxy) sent a request that this server could not understand

Time:04-19

I created a small Flask service. However each time I tried to use the say-hi endpoint, I get the following message:

{
    "message": "The browser (or proxy) sent a request that this server could not understand."
}

My Flask service looks like this:

from flask import Flask, request
from flask_restful import Resource, Api, abort, reqparse

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

class HelloResource(Resource):
    def get(self):
        return { 'message': 'Hello' }

class SayHiResource(Resource):
    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('name', required=True, help='Name cannot be blank')
        args = parser.parse_args()

        return { 'message': 'Hello '   args['name'] }

api.add_resource(HelloResource, '/hello')
api.add_resource(SayHiResource, '/say-hi')

if __name__ == '__main__':
    app.run(debug=True, load_dotenv=True)

However, there is not much information about why is failing.

The way I'm running is by using gunicorn and the serviceEntrypoint.py file, which only has this content:

from src.api.service import app

if __name__ == '__main__':
    app.run()

Here is my folder structure

.
├── requirements.txt
├── serviceEntrypoint.py
└── src
    ├── __init__.py
    └── api
        ├── __init__.py
        └── service.py

Why the /hello ending works, but the say-hi doesn't when I call to http://localhost:8000/say-hi?name=John?

CodePudding user response:

if you run the flask debug server and issue your HTTP request http://localhost:8000/say-hi?name=John, you will see that the actual error is:

message "Did not attempt to load JSON data because the request Content-Type was not 'application/json'."

There is documentation and examples here, but it boils down to choosing if the request should be a GET or a POST. The way you structured your request - you are passing 1 field only, the username - it looks like a GET, in this case you should have:

api.add_resource(SayHiResource, '/say-hi/<username>')

and class:

class SayHiResource(Resource):
    def get(self, username):
        return { 'message': 'Hello '   username }

if you want to implement a POST request, please trace in the documentation the example that is triggered by the call: curl http://localhost:5000/todos -d "task=something new" -X POST -v

Update:

for using query parameters, you can use the request.args:

api.add_resource(SayHiResource, '/say-hi')

class:

class SayHiResource(Resource):
    def get(self):
        username = request.args.get("username")
        status = request.args.get("status")
        # print(query_args)
        return { 'message': 'Hello {}, your status is: {}'.format(username, status) }

example:

[http_offline@greenhat-35 /tmp/] > curl 'http://localhost:8000/say-hi?username=lala&status=enabled'
{
    "message": "Hello lala, your status is: enabled"
}
[http_offline@greenhat-35 /tmp/] > 
  • Related