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/] >