I have an endpoint which is receiving a text file from a request, which the flask server processes and now need to send a response which should be a json file. I have read and performed the operations of received txt file, and now when I send the dict by jsonify I get this in terminal.
Response 444 bytes [200 OK]
How do I get the json file or is there any other way of sending the JSON file in response? Since I won't be in control of the server that will send the request I need a way to send JSON file.
Code Handling the response
#app.route('/automated_testing', methods=['GET','POST'])
def getfile():
if request.method == 'POST':
for file in request.files:
links = request.files[file].read()
#Since a byte sized object is returned
links = [links.decode('utf8').strip()]
links = links[0].split("\n")
res = dict()
for i in links:
f = FlarePredictor(i)
res[i] = f[0]
print(jsonify(res), file=sys.stderr)
return jsonify(res)
else:
return "GET REQ"
return "Hi"
Code used to send the request
import requests
with open('test.txt', 'rb') as f:
r = requests.post('http://127.0.0.1:5000/automated_testing', files={'test.txt': f})
requests supports JSON out-of-the-box:
json = r.json()
Now json will be a regular Python dictionary containing the data.
Related
I'm trying to write the output of an API 'get' request to a file. I know the function works as the output of the request is returned successfully and in full in shell.
The function creates the file, but the file only includes the status code for the get request - can anyone help me understand why? Still pretty new to Python and very new to calling APIs...
def user_info(token):
heads = {"Authorization": "bearer " + token, "Content-type": "application/json"}
url = "xxxxx"
request = req.get(url, headers=heads)
with open('userdata.txt', 'w') as f:
f.write(str(request))
if request.status_code == 200:
return request.json()
else:
return "User Info FAILED! Failure code: {}, error: {}".format(request.status_code,request.json()['error'])
The file just contains:
<Response [200]>
Thanks!
A Response object in the requests module when called as a string will return its status code as detailed in the Response python code
def __repr__(self):
return '<Response [%s]>' % (self.status_code)
If you want to write the json from the response as a string then you can use the built in json module and use its dumps method to dump it as a string not a dict.
import requests
import json
with open("myfile.txt", "w") as output:
resp = requests.get("https://jsonplaceholder.typicode.com/todos/1")
output.write(json.dumps(resp.json()))
I am trying to create an endpoint called /automated_testing. This endpoint will
receive an automated POST request which will be a .txt file which contains some strings. I want to read those strings and perform some operations on it.
I am getting error :
raise exceptions.BadRequestKeyError(key)
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'files'
I am using the below code to send a request which I trigger from separate script.
import requests
with open('test.txt', 'rb') as f:
r = requests.post('http://127.0.0.1:5000/automated_testing', files={'test.txt': f})
Code for the flask server
#app.route('/automated_testing', methods=['GET','POST'])
def getfile():
if request.method == 'POST':
file = request.files['files']
a = ""
with open(file,'r') as f:
file_content = f.read()
a+=file_content
return a
else:
return "GET REQ"
return "Hi"
Content of test.txt
Hi
hello
I get that the error indicates ['files'] but I am not able to resolve the problem. Is the way I am sending the post request wrong or the flask server?
Try
file = request.files['text.txt']
or iterate over all sent files:
for file in request.files:
#do_stuff
While implementing a rest API in python flask, I have used several options to return a file (any type) , read it and save it to local repository of request but encountered with multiple errors as below:
Case 1:
def download_file():
return send_file('any_file.pdf')
r = requests.get(url = 'http://localhost:5000/download').read()
has responded with a error Response object has no attribute read/text/content
Case 2:
def download_file():
file = open('any_file.pdf','r').read()
return file
r = requests.get(url = 'http://localhost:5000/download')
has responded with a error Return doesn't accept this
So How can I do this as flask is not allowing to return a file without response object and response object is not readable and doesn't support to save that file directly.
The Flask server code in Case 1 is correct. A more complete example:
#app.route('/download')
def download_file():
# Some logic here
send_file('any_file.pdf')
However the Response object returned by requests.get doesn't have a read method. The correct way is to use:
Response.content: Content of the response, in bytes.
So, the client code should be:
r = requests.get('http://localhost:5000/download')
bytes = r.content
# Now do something with bytes, for example save it:
with open('downloaded_file.ext', 'wb') as f:
f.write(bytes)
Hi I am trying to return multipart from data from a get request. However I am unable to return a MultipartEncoder object as a response. I have attempted the solution at
Can I serve a multipart http response in Flask?
The below code only returns the 'toPersonEmail' field. How does one return m as a response in Flask?
#app.route("/multipart", methods=['GET'])
def send_multipart():
m = MultipartEncoder(fields={ 'markdown': "> Block quotes are written like so in markdown.",
'toPersonEmail':'d#d.com',
'files': ("pnggrad16rgb.png", open("pnggrad16rgb.png", 'rb'),
'image.png')})
return Response(m.fields, mimetype=m.content_type)
Flask has no specific provision for multipart mime responses; multipart/form is a mimetype normally only used in a POST request to the server, not in a response from a HTTP server.
If you must return valid multipart mime data, render the body to bytes and set the right headers on a response object; the `(
m = MultipartEncoder(fields={ 'markdown': "> Block quotes are written like so in markdown.",
'toPersonEmail':'d#d.com',
'files': ("pnggrad16rgb.png", open("pnggrad16rgb.png", 'rb'),
'image.png')})
return (m.to_string(), {'Content-Type': m.content_type})
If you wanted to stream the response, you'd have to supply your own generator function that reads from the multipart encoder in chunks:
def chunked_reader(f, chunksize=2 ** 20): # 1Mb chunks
while True:
chunk = f.read(chunksize)
if not chunk:
return
yield chunk
and use that to wrap your MultipartEncoder() instance when streaming response data:
# include the Content-Length header, even though we are streaming
return Response(
chunked_reader(m), content_type=m.content_type,
headers={'Content-Length': m.len})
The MultipartEncoder() object supports a .read() method just like files do.
Currently I'm trying to send a byte-array to a webservice, but i get the error message, that a bytearray is not serializeable:
TypeError: bytearray(b'') is not JSON serializable
I'm using the following code
Sending the requests
# Set blob
with open('demo-file.txt') as file:
f = file.read()
b = bytearray(f)
print a.set_data('5cb9bc4d-c0fd-40ab-8b74-4e62b50d8966', b)
Set_Data method:
def set_data(self, path, data):
"""
Save data in
Parameter
--------
path (str): Path as string
data (bytearray): Data as bytearray
"""
result = requests.post(self.url + '/set', json = { 'path': path, 'data': data})
# Check status and token
if result.status_code == 200:
return result.text
What am I doing wrong, do I have to use some other methods for sending bytearrays?
Thank you all a lot!
If you really need json, you have to encode your binary data. See: Base64 encoding in Python 3
An alternative: How to send binary post data via HTTP?