As @TimRoberts said in comment you would have to use io.BytesIO to create file-like object in memory, write in this file and later read from this file.
r = requests.get("https://placekitten.com/640/360")
file_like_object = io.BytesIO()
file_like_object.write(r.content)
file_like_object.seek(0) # move to the beginning of file
return send_file(file_like_object, mimetype='image/png')
or shorter
r = requests.get("https://placekitten.com/640/360")
file_like_object = io.BytesIO(r.content)
return send_file(file_like_object, mimetype='image/png')
And this can be usefull if you want to generate files instead of getting from server - ie. plot with matplotlib, image with pillow, audio from some TextToSpeech API, etc.
You could find many examples on Stackoverflow.
But if you don't want to edit file then there is even simpler method.
Using requests.get(..., stream=True) you may get r.raw which is file-like object.
r = requests.get("https://placekitten.com/640/360", stream=True)
file_like_object = r.raw
return send_file(file_like_object, mimetype='image/png')
Minimal working code with both versions, and with real URL so everyone can copy and run it:
EDIT: I added example which resize image without saving on disk.
from flask import Flask, render_template_string, send_file
import requests
import io
from PIL import Image
app = Flask(__name__)
@app.route('/')
def index():
return render_template_string('''
<img src="/get_image">get_image<br/>
<img src="/get_image_bytesio">get_image_bytesio<br/>
<img src="/get_image_bytesio_smaller">get_image_bytesio_smaller<br/>
''')
@app.route('/get_image')
def get_image():
r = requests.get("https://placekitten.com/640/360", stream=True) # it needs `stream=True`
file_like_object = r.raw
return send_file(file_like_object, mimetype='image/png')
@app.route('/get_image_bytesio')
def get_image_bytesio():
r = requests.get("https://placebear.com/640/360")
#file_like_object = io.BytesIO()
#file_like_object.write(r.content)
#file_like_object.seek(0) # move to the beginning of file after writing
file_like_object = io.BytesIO(r.content)
return send_file(file_like_object, mimetype='image/png')
@app.route('/get_image_bytesio_smaller')
def get_image_bytesio_smaller():
r = requests.get("https://placebear.com/640/360")
file_like_object = io.BytesIO(r.content)
# edit image without saving on disk
img = Image.open(file_like_object)
img = img.resize((320, 180))
# `seek()` has to be after `resize()` because it may use `lazy loading`
file_like_object.seek(0) # move to the beginning of file after reading
img.save(file_like_object, 'PNG')
file_like_object.seek(0) # move to the beginning of file after writing
return send_file(file_like_object, mimetype='image/png')
if __name__ == '__main__':
#app.debug = True
app.run()