parsing json formatted requests in appengine - python

Been working on an appengine app lately. I would like to parse json data contained in requests to the app. How do I use the request object of the requesthandler class to achieve this?
Below is a snippet of the code to show what I want to achieve:
import cgi
import webapp2
import datamethods
from google.appengine.ext.webapp.util import run_wsgi_app
class adduser(webapp2.RequestHandler):
def get(self):
# Get the phone number from json data in request.
userphone = self.request.get("phone")
# Get the name from json data in request.
name = self.request.get("name")
app = webapp2.WSGIApplication([
('/adduser', adduser),
('/sign', updatestatus),
('/login',login)
], debug=True)
def main():
run_wsgi_app(app)
if __name__ == "__main__":
main()

You have to parse the incoming json string in an object. After this you can access the attributes.
import json # Now you can import json instead of simplejson
....
jsonstring = self.request.body
jsonobject = json.loads(jsonstring)

import cgi
import webapp2
import datamethods
from google.appengine.ext.webapp.util import run_wsgi_app
class adduser(webapp2.RequestHandler):
def get(self):
items = []
response = { }
userphone = self.request.get("phone")
name = self.request.get("name")
items.append({'userphone': userphone , 'name':name})
response['userInformation'] = items
return response #return json data
app = webapp2.WSGIApplication([
('/adduser', adduser),
('/sign', updatestatus),
('/login',login)
], debug=True)
def main():
run_wsgi_app(app)
if __name__ == "__main__":
main()

Related

Flask issue with python: The browser (or proxy) sent a request that this server could not understand

New to Flask and API development, but I'm trying to figure out what's wrong here.
This is my code in my koho-flask.py
from flask import Flask
from flask_restful import reqparse, abort, Api, Resource
import new_model_zero_shot as model
app = Flask(__name__)
api = Api(app)
#create new user_palette object
user = model.user_palette(model.cold_start(), 1)
dish_list = model.dish_list
#user.recommend_meal(['chicken', 'rice'], query_type = ['our_dbs', dish_list], name_csv = None)
# argument parsing
parser = reqparse.RequestParser()
parser.add_argument('query')
# we already have a way to package the output to user
class GetRecipes(Resource):
def get(self):
# use parser and find the user's query
args = parser.parse_args()
user_query = args['query']
recs = (user.recommend_meal(user_query,
query_type = ['our_dbs', dish_list], name_csv = None))
return recs
class Hello(Resource):
def get(self):
return {'data': "Hello wassup!"}
#recipe search endpoint
api.add_resource(GetRecipes, '/')
api.add_resource(Hello, '/')
#%%
if __name__ == '__main__':
app.run(debug=False)
When I run app.run(debug=False), the server starts.
After, I open a test.py file in the same directory and run this.
import requests
url = 'http://127.0.0.1:5000/'
params ={'query': 'chicken'}
response = requests.get(url, params)
a = response.json()
My "a" variable returns a dictionary with the value "The browser (or proxy) sent a request that this server could not understand". This happens whether I test out my dummy "Hello" endpoint or my real "GetRecipes" endpoint.
What am I doing incorrectly?

Using Flask to reproduce an audio using json

i'm trying to make an app in flask-python that using a json post send an audio using the gtts google library as the answer, but my method doesn't work. My code is the following.
from gtts import gTTS
from flask import Flask, send_file, request
app = Flask(__name__)
#app.route("/")
def t2s():
text = request.get_json()
obj = gTTS(text = text, slow = False, lang = 'en')
obj.save('audio.wav')
return send_file('audio.wav')
if __name__ == "__main__":
app.run(port=3000 , debug=True, use_reloader=True, host='0.0.0.0')
any suggestions?, i'm using postman.
Thanks a lot for the possible help
Flask as default doesn't get POST requests and you have to use methods=['POST', 'GET']
from gtts import gTTS
from flask import Flask, send_file, request
app = Flask(__name__)
#app.route("/", methods=['POST', 'GET'])
def t2s():
text = request.get_json()
print(text)
obj = gTTS(text = text, slow = False, lang = 'en')
obj.save('audio.wav')
return send_file('audio.wav')
if __name__ == "__main__":
app.run(host='0.0.0.0', port=3000)
And test (using mplayer on Linux):
import requests
import os
data = 'Hello World'
r = requests.post('http://127.0.0.1:3000/', json=data)
open('output.wav', 'wb').write(r.content)
os.system('mplayer output.wav')

Flask Client does not retreive response

I am trying to retrieve data from server through a client using requests.post
task id id a random id
here is the server
from json import dumps
from werkzeug.exceptions import BadRequest
from flask import (
Flask,
Response,
request
)
from utils import get_random_id
app = Flask(__name__)
tasks = {
get_random_id(): {
"task": "write server mock",
"completed": True
}
#print(get_random_id())
}
#app.route(
'/tasks',
methods=['GET']
)
def list_tasks():
li = [
{
"id": task_id,
"task": values["task"],
"completed": values["completed"]
} for task_id, values in tasks.iteritems()
]
#print(li)
return Response(
dumps(li),
mimetype='application/json'
)
if __name__ == "__main__":
pass
Here is the client:
from flask import Flask,request
#importing server file that i made
import server
app = Flask(__name__)
app.testing = True
#app.route('/')
def index():
return request.url
response = app.test_client(server)
print(response)
I want to retrieve the posts in my python file all I manage to generate is response of the client
How do I get the table?
Do I use API Endpoints?
Please help me fix this error
You need to use some HTTP library for making a request.
Try http://docs.python-requests.org/en/master/
Example:
import requests
r = requests.get('{your server url}/tasks')
test_client method will create a client for you. And then you should use that client to query your server (either POST or GET or whatever). So you could use something like the following:
with server.test_client() as c:
resp = c.get('/tasks')
data = json.loads(resp.data)
print(data)

How to get Python dictionary via Flask request files attribute [duplicate]

This question already has answers here:
Read file data without saving it in Flask
(8 answers)
Opening a file that has been uploaded in Flask
(2 answers)
Closed 4 years ago.
With server.py running:
from flask import Flask, request, Response
app = Flask(__name__)
#app.route('/test', methods=['GET','POST'])
def route():
print('got files: %s' % request.files)
return Response()
if __name__ == '__main__':
app.run('0.0.0.0', 5000)
send a request using client.py:
import json, requests
dictionary_1 = {"file": {"url": "https://bootstrap.pypa.io/get-pip.py"}}
files = [('dictionary_1', ('get-pip.py', json.dumps(dictionary_1), 'application/json'))]
response = requests.post('http://127.0.0.1:5000/test', files=files)
Server logs that it received a request:
got files: ImmutableMultiDict([('dictionary_1', <FileStorage: u'get-pip.py' ('application/json')>)])
Apparently, the dictionary_1 was received as FileStorage object.
How to turn the received FileStorage into the Python dictionary?
edited later
The possible duplicate post does not clarify how to send and unpack the Python dictionary object sent via requests(files=list())
This is happening because you're posting files instead of data. This should work:
import flask
app = flask.Flask(__name__)
#app.route('/test', methods=['GET','POST'])
def route():
print('got data: {}'.format(flask.request.json))
return Response()
if __name__ == '__main__':
app.run('0.0.0.0', 5000)
and then send data to your app by
import requests
dictionary_1 = {"file": {"url": "https://bootstrap.pypa.io/get-pip.py"}}
response = requests.post('http://127.0.0.1:5000/test', json=dictionary_1)
In your example there's no need to post the file unless I'm misunderstanding something
Solution # 1:
from flask import Flask, request, Response
import StringIO, json
app = Flask(__name__)
#app.route('/test', methods=['GET','POST'])
def route():
print('got files: %s' % request.files)
for key, file_storage in request.files.items():
string_io = StringIO.StringIO()
file_storage.save(string_io)
data = json.loads(string_io.getvalue())
print('data: %s type: %s' % (data, type(data)) )
return Response()
if __name__ == '__main__':
app.run('0.0.0.0', 5000)
Solution # 2:
from flask import Flask, request, Response
import tempfile, json, os, time
app = Flask(__name__)
#app.route('/test', methods=['GET','POST'])
def route():
print('got files: %s' % request.files)
for key, _file in request.files.items():
tmp_filepath = os.path.join(tempfile.mktemp(), str(time.time()))
if not os.path.exists(os.path.dirname(tmp_filepath)):
os.makedirs(os.path.dirname(tmp_filepath))
_file.save(tmp_filepath)
with open(tmp_filepath) as f:
json_data = json.loads(f.read())
print type(json_data), json_data
return Response(json_data)
if __name__ == '__main__':
app.run('0.0.0.0', 5000)

Google App Engine HTTP information being printed somehow

I'm just wanting to return a JSON object, but HTTP information is being printed below it. I'm using Google App Engine and https://github.com/simplegeo/python-oauth2
#!/usr/bin/env python
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from django.utils import simplejson as json
import oauth2 as oauth
import cgi
class MainHandler(webapp.RequestHandler):
def get(self):
consumer = oauth.Consumer(key="xxx",
secret="xxx")
request_token_url = "xxx"
client = oauth.Client(consumer)
resp, content = client.request(request_token_url, "POST")
if resp['status'] != '200':
raise Exception("Invalid response %s." % resp['status'])
request_token = dict(cgi.parse_qsl(content))
print
print json.dumps({"oauth_token": request_token['oauth_token'], "oauth_token_secret": request_token['oauth_token_secret']})
def main():
application = webapp.WSGIApplication([('/', MainHandler)],
debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
Add the proper Content-Type and switch to self.response.out.write
self.response.headers['Content-Type'] = 'application/json'
self.response.out.write(data)
Instead of print use self.response:
self.response.out.write("Some Text")
I suppose that the RequestHandler automatically prints a default HTTP header and sends it if nothing is written to the response.out stream.
If you only want to send JSON data you can set the "Content-Type" header information to "application/json".

Categories

Resources