Get data from an API with Flask - python

I have a simple flask app, which is intended to make a request to an api and return data. Unfortunately, I can't share the details, so you can reproduce the error. The app looks like that:
from flask import Flask
import requests
import json
from requests.auth import HTTPBasicAuth
app = Flask(__name__)
#app.route("/")
def getData():
# define variables
username = "<username>"
password = "<password>"
headers = {"Authorization": "Basic"}
reqHeaders = {"Content-Type": "application/json"}
payload = json.dumps(
{
"jobType": "<jobType>",
"jobName": "<jobName>",
"startPeriod": "<startPeriod>",
"endPeriod": "<endPeriod>",
"importMode": "<importMode>",
"exportMode": "<exportMode>"
}
)
jobId = 7044
req = requests.get("<url>", auth=HTTPBasicAuth(username, password), headers=reqHeaders, data=payload)
return req.content
if __name__ == "__main__":
app.run()
However, when executed this returns error 500: Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
The same script but outside a flask app (just the function as it is defined here) runs with no problems at all.
What am I doing wrong?

flask app return format json. If you return req.content, it will break function. You must parse response request to json before return it.
from flask import jsonify
return jsonify(req.json())
It's better with safe load response when the request fail
req = requests.get()
if req.status_code !=200:
return {}
else:
return jsonify(req.json())

Related

Trying to send an audio file and text to flask api but getting 400 bad request error

So, i am trying to send an audiofile and text as arguments to a flask api, it works fine when i send them through postman but i get a bad request error when i post it through python code.
Here is my python code:
import requests
import json
url= 'http://192.168.100.14:8000/v1/translate'
with open('/home/faizi/ai-chatbot-with-voice-driven-facial-animation/01_smalltalk_bot/game.wav', 'rb') as file:
files = {'input_file': file}
d = {"text":"hello, my name is faizan"}
req = requests.post(url, files=files, json=d)
print(req.status_code)
print(req.text)
And here is my flask api:
from flask import Flask
from flask_cors import cross_origin
from flask import Blueprint, request, Response
import json
from Voice_Cloning_Module import demo_cli
from flask import send_file
app = Flask("foo")
#app.route('/v1/translate', methods=['POST', 'OPTIONS'])
#cross_origin()
def translate_mbart():
data = request.get_json()
audio_file = request.files['input_file']
audio_file.save("./bufferaudiofile/"+audio_file.filename)
text = request.form['text']
returnedfile = demo_cli.clone(text,"./bufferaudiofile/"+audio_file.filename)
path_to_clonefile = returnedfile
return send_file(
path_to_clonefile,
mimetype="audio/wav",
as_attachment=True,
attachment_filename="test.wav")
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
I am getting 400 bad request error and i dont understand what could be the issue, it works fine in postman
I was able to successfully send a wav file using the following code. I suggest stripping it back to bare bones and focussing on receiving the file to make sure nothing else is causing the issue.
For the API:
from flask import Flask
from flask import request
import json
app = Flask(__name__)
#app.route('/main', methods=['POST', 'OPTIONS'])
def main():
file = request.files['file']
print(file)
return { "ok": True }
if __name__ == '__main__':
app.run(host = 'localhost', port = 8000)
And for the request:
import requests
import json
url = 'http://localhost:8000/main'
with open('test_file.wav', 'rb') as wav:
files = { "file": wav }
d = { "body" : "Foo Bar" }
req = requests.post(url, files=files, json=d)
print(req.status_code)
print(req.text)

How to make rest API that responds to post(data=data,header=header) with python and flask

I am trying to make a rest API in python.flask and I want it to be responsive to python.requests.post(data=data,header=header). But every tutorial and website only shows me Postman and
An API that responds to python.requests.post(PARAMS=data,header=header) but "PARAMS" does not work for my case. I've tried using python.flask.request.get_json(), I've tried using python.flask.Resource, I've tried using another one here:-
from flask import Flask
from flask_restful import Resource, Api, reqparse
from json import loads as dictionary
from flask import request as req
app = Flask(__name__)
api = Api(app)
#app.route('/test', methods=['POST'])
def post(username,token,url):
# gotit=dictionary(gotit)
k = '{"name":'+username+',"password":'+token+',"link":'+url+'}'
print(k)
return k
if __name__ == '__main__':
app.run()#debug=True)
But all in vain. Please help me make an API that responds to this:- python.requests.post(data=data,header=header). And also help with the header thing.
Python.v3.8
Here's your code but with some modification:
Server Code:
from flask import Flask, jsonify, request
import requests
import json
app = Flask(__name__)
#app.route('/test', methods=['POST'])
def post():
# you will get that data in request.data you can simplify/jsonfiy
text = str(request.data)
t = request.data
return t
if __name__ == "__main__":
app.run(debug=True)
python.requests Code:
import requests
header = {
"Content-Type":"text/plain"
}
data = {
"username":"myName",
"password":"myPass",
"url":"myWeb"
}
d = requests.post(url='http://127.0.0.1:5000/test', data=data, headers=header)
#
print(d.content)
Response from server something like this:
response Screenshot
I'm Using Python 3.9.1
Hope it will help You:)

How can I return API objects in application using flask

from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
#app.route('/address_search', methods=['GET'])
def sample():
zipcode = request.args.get('zipcode', None)
url = f'https://zipcloud.ibsnet.co.jp/api/search?zipcode={zipcode}'
response = requests.get(url)
# results = response.json()
# results = jsonify(response) ?????
return response
if __name__ == '__main__':
app.run(debug=True)
I'm trying to create an Application which return the Address.
I succeeded to return url but about response, I can't and Internal Server Error appears
So I thought in flask, requests.get(url) cannot be used but I didn't came up an another way.
I heard that jsonify() is used but I don't known how.
I searched it in Google for two days but I still cannot find it's answer.
Someone please give me advice.
So, you want to return the response of that API in your web application, i guess this is what you're looking for?
#app.route('/address_search', methods=['GET'])
def sample():
zipcode = request.args.get('zipcode', None)
url = f'https://zipcloud.ibsnet.co.jp/api/search?zipcode={zipcode}'
response = requests.get(url)
response_json = response.json()
return jsonify(response_json)
EDIT, response to your comment:
You can't do jsonify(response_json)['results'][0] because jsonify turns the JSON data to Flask Response object, instead try this:
#app.route('/address_search', methods=['GET'])
def sample():
zipcode = request.args.get('zipcode', None)
url = f'https://zipcloud.ibsnet.co.jp/api/search?zipcode={zipcode}'
response = requests.get(url)
response_json = response.json()
results = response_json['results'][0]
return jsonify(results)

How can i build a proper restful response API by python flask for parameters

I'm studing about RESFful API with python.
I want to build a my restful api server,
but i have a problem,
i don't know how my api server returns proper data by reqeust each parameters
(request code sample)
the request code wants to get the information about 'item' : 'sword'
import requests
import json
url = "https://theURL"
querystring={"item":"sword"}
response = requests.request("GET", url, params=querystring)
print (response.json())
(API server response code sample, by flask python)
from flask import Flask, url_for
from flask_restful import Resource, Api, abort, reqparse
app = Flask(__name__)
api = Api(app)
TODOS = {
"version":"2.0",
"resultCode":"OK",
"output":{
{
"item" :"sword"
"price": 300,
"damage": 20,
},
{
"item" :"gun"
"price": 500,
"damage": 30,
},
},
}
class Todo(Resource):
def post(self):
return TODOS
api.add_resource(Todo, '/item.price')
if __name__ == "__main__":
app.run(debug=True, host ="192.168.0.8", port = 8080)
So i want to know how i use a code in response api server for returning 'item price' data by reqeusted parameters 'item : sword'
I just want to get the selected parameter's item price and damage information.
I thought it might be very easy, i'm tried to search the example but i couldn't find proper sample code.
I'm not a Flask-expert, but this helps setting up and running a minimalistic Flask-server. Then, this explains how to return json-formatted data from your server, and finally how to request and interpret the json-response can be found here. Summarized below:
Server returning a json-formatted data:
from flask import Flask
from flask import jsonify
app = Flask(__name__)
#app.route('/')
#app.route('/index')
def hello():
return "Hello, World!"
#app.route('/request_sword')
def grant_sword():
return jsonify({"sword": {"name":"Excalibur","price":"stack overflow"}})
Client requesting json-formatted data:
import json
import urllib.request
url = "http://127.0.0.1:5000/request_sword" ## My local host flask server
data = urllib.request.urlopen(url)
response = json.loads(data.read())
print(response)
That's all really. You may also just enter the url in your browser, which will correctly read the json-data:

Is it possible to make POST request in Flask?

There is a need to make POST request from server side in Flask.
Let's imagine that we have:
#app.route("/test", methods=["POST"])
def test():
test = request.form["test"]
return "TEST: %s" % test
#app.route("/index")
def index():
# Is there something_like_this method in Flask to perform the POST request?
return something_like_this("/test", { "test" : "My Test Data" })
I haven't found anything specific in Flask documentation. Some say urllib2.urlopen is the issue but I failed to combine Flask and urlopen. Is it really possible?
For the record, here's general code to make a POST request from Python:
#make a POST request
import requests
dictToSend = {'question':'what is the answer?'}
res = requests.post('http://localhost:5000/tests/endpoint', json=dictToSend)
print 'response from server:',res.text
dictFromServer = res.json()
Notice that we are passing in a Python dict using the json= option. This conveniently tells the requests library to do two things:
serialize the dict to JSON
write the correct MIME type ('application/json') in the HTTP header
And here's a Flask application that will receive and respond to that POST request:
#handle a POST request
from flask import Flask, render_template, request, url_for, jsonify
app = Flask(__name__)
#app.route('/tests/endpoint', methods=['POST'])
def my_test_endpoint():
input_json = request.get_json(force=True)
# force=True, above, is necessary if another developer
# forgot to set the MIME type to 'application/json'
print 'data from client:', input_json
dictToReturn = {'answer':42}
return jsonify(dictToReturn)
if __name__ == '__main__':
app.run(debug=True)
Yes, to make a POST request you can use urllib, see the documentation.
I would however recommend to use the requests module instead.
EDIT:
I suggest you refactor your code to extract the common functionality:
#app.route("/test", methods=["POST"])
def test():
return _test(request.form["test"])
#app.route("/index")
def index():
return _test("My Test Data")
def _test(argument):
return "TEST: %s" % argument

Categories