Send an image with flask by using urllib2 - python

I'm new to Flask and I want to send an image to a client that was previously received from a external server with urllib2. Here is my example code for sending the google logo to the client:
import urllib2
from flask import Flask, send_file
app = Flask(__name__)
#app.route('/getTestImage')
def getTestImage():
url = "https://www.google.de/images/srpr/logo11w.png"
response = urllib2.urlopen(url)
img = response.read()
response.close()
return img
if __name__ == '__main__':
app.run()
When I open 127.0.0.1:5000/getTestImage with a browser ( e.g. Firefox) I just get binary code. How do I send the png file so that the browser display the image? I found send_file from Flask but I don't realy know how to use the function with the received image data from urllib2.
Edit: I figured it out. Simply return Response(img, mimetype="image/png").

You see binary data because you're returning the image data directly. Flask wraps text returned from a view in its default Response object, which sets the mimetype to text/plain. Since you're not returning plain text data, you need to create a response that describes the correct mimetype.
return app.response_class(img, mimetype='image/png')

Related

Post Request as Media in MMS

I wrote a python program that gets a photo from a webserver. The photo is obtained by sending a POST request to my URL (the returned photo depends on data of POST request):
myobj = {'x': [1,2,3,4], 'y': [1,2,3,6]}
x = requests.post('http://cainevisualizer.azurewebsites.net/plot.png', data=myobj)
x is a requests.Response object with methods giving its content, status code, the response url, the text (in unicode) etc (see all methods here. However, it appears that, in order to send a text message of an image in Twilio, Message().media requires the URL of the image.
message = Message()
message.media(myURL)
Again, the webserver (in Flask) returns an image after a post request rather than returning a unique url to the image. Is there an API or some other way to convert a MIME image into a unique url? Any advice appreciated.
I think I found a solution to my own question. So, I changed the webserver that hosts the photo to now accept GET requests. I then pass my parameters to and send a GET request to the webserver. See the GET request as follows:
import requests
data = {'x[]': [1,2,3,4], 'y[]': [4,5,6,7]}
response = requests.get('http://cainevisualizer.azurewebsites.net/plot.png', params=data)
url = response.url
This request passes the parameters in the data dictionary as a single URL to the webserver. In this case, the GET request is encoded as a url and passes [1,2,3,4] and [4,5,6,7] as query parameters. This is instead of sending the information in the GET request as part of the body of the request (or as part of anything BUT the url itself)
I now use the request.args.getlist('x[]') and request.args.getlist('y[]') function in the webserver to to get the information from this GET request... it looks something like this
from flask import Flask, request, make_response
app = Flask(__name__)
#app.route('/plot.png', methods=['GET', 'POST'])
def plot():
xs = request.args.getlist('x[]')
ys = request.args.getlist('y[]')

how to again post a file that is received in a post request in python

When I am trying to post the file that I have received from a post request, it is giving me an error as:
expected str, bytes or os.PathLike object, not FileStorage
How am I suppose to post the file?
A proper syntax is what I am looking for.
However without posting file, that is only posting data is working fine.
from PIL import Image
from flask_restful import Resource, request, Api
import requests
class fileSendingApi(Resource):
def post(self):
images=open(request.files['my_image_1'],'rb')
URL = 'http://127.0.0.1:5000/final_img_api'
file={"my_image_2": images}
values={"auth_key": "some_auth_key"}
response = requests.post(URL, files=file, data=values)
output = response.json()
You have a mistake in your code:
images=open(request.files['my_image_1'],'rb')
When using open you are actually transforming the file from web-uploaded file to FileStorage.
What you want to do is use the file that was uploaded:
images=request.files['my_image_1']
and it should work.
By the way, if you want to save the image use: images.save(FILE_PATH) instead of open()

Serve an ical feed with Flask

I've got a small flask website, and I want to serve an ical feed from it.
I've already created an ics-file, which gets frequently updated, however I can't figure out how to serve it from the website.
I've tried doing it through Response and serve_file, but they just display the text in the file.
You need to set the the correct content disposition header of the response. In your case the header would be something like the following:
Content-Disposition: attachment; filename=calender.ics;
In your Flask route your code should look something like the following:
from flask import make_response
app = Flask(__name__)
# ...
#app.route('/calendar/')
def calendar():
# Get the calendar data
_calendar = make_calendar()
# turn calendar data into a response
response = make_response(_calendar)
response.headers["Content-Disposition"] = "attachment; filename=calendar.ics"
return response

How to get json data from another website in Flask?

I want to make a website with Flask to show some data posted from another website such as this one.In short,I want to list the data from that website.
Should I use this method: flask.Request.get_json()?
I do not know how to get a Request object. Could you show me some demos about that?
I am using Python 3 and Flask.
import requests
def get(url):
try:
res = requests.get(url)
return res.json()
except:
return False
data = get('http://example.com')
print(data)
In short,I want to list the data from that website.
The accepted answer seem not use flask, so I'll add some:
from flask import jsonify, Flask
import requests
app = Flask(__name__)
#app.route('/')
def index():
r = requests.get('https://api.github.com/users/runnable')
return jsonify(r.json())
Should I use this method: flask.Request.get_json()
No, it is for parsing the incoming json request data. No one is sending requests to you.

Uploading an image from python client to a flask server

I am using requests and requests_toolbelt to send an image to the cloud and so far I have something like this
import requests
import json
from requests_toolbelt import MultipartEncoder
m = MultipartEncoder(
fields={"user_name":"tom", "password":"tom", "method":"login",
"location":"landing", "cam_id":"c00001", "datetime":"hammaTime!"
,'image': ('filename', open('image.jpg', 'rb'))}
)
r = requests.post(url, data=m)
print r.text
After it gets to the server, how to I get back a dictionary of something usable? The toolbelt docs show only how to post, not how to handle it on the other end. Any advice?
You can see a working example of Flask server which accepts POSTS like the on you're trying to make on HTTPbin. If you do something like:
m = MultipartEncoder(fields=your_fields)
r = requests.post('https://httpbin.org/post', data=m, headers={'Content-Type': m.content_type})
print(r.json()['form'])
You'll see that everything in your post should be in that dictionary.
Using HTTPBin's source, you can then see that the form section is generated from request.form. You can use that to retrieve the rest of your data. Then you can use request.files to access the image you wish to upload.
The example Flask route handler would look like:
#app.route('/upload', methods=['POST'])
def upload_files():
resp = flask.make_response()
if authenticate_user(request.form):
request.files['image'].save('path/to/file.jpg')
resp.status_code = 204
else:
resp.status_code = 411
return resp
You should read into Uploading Files documentation though. It is really invaluable when using common patterns like this in Flask.
requests-toolbelt can only send the file to the server but it is up to you to save that on the server side and then return meaningful result. You can create a flask endpoint to handle the file upload, return the desired result dictionary as a JSON and then convert the JSON back to dict on the client side with json.loads.
#app.route('/upload', methods=['POST'])
def upload_file():
if request.method == 'POST':
f = request.files['image']
f.save('uploads/uploaded_file')
# do other stuff with values in request.form
# and return desired output in JSON format
return jsonify({'success': True})
See flask documentation for more info on file uploading.
Also, you need to specify the mime-type while including the image in MultipartEncoder and content-type in the header while making the request. (I'm not sure you if you can even upload images with MultipartEncoder. I was successful with only the text files.)
m = MultipartEncoder(
fields={"user_name":"tom", "password":"tom", "method":"login",
"location":"landing", "cam_id":"c00001", "datetime":"hammaTime!"
,'image': ('filename', open('file.txt', 'rb'), 'text/plain')} # added mime-type here
)
r = requests.post(url, data=m, headers={'Content-Type': m.content_type}) # added content-type header here

Categories

Resources