9
from flask import Flask, redirect, url_for

app = Flask(__name__)
@app.route('/')
def index():
        generate_img("test.jpg");
        return '<img src=' + url_for(filename='test.jpg') + '>'

generate_img() will output a random image to the current directory (same folder as this script).

I am getting 404, I navigate to mydomain.com/test.jpg but it's not there.

KJW
  • 15,035
  • 47
  • 137
  • 243

2 Answers2

8

Reason of a 404 error is that there is no such view to handle this. To serve images from flask, save the image inside static folder and then you can access image at this url

mydomain.com/static/test.jpg

     from flask import Flask, redirect, url_for

     app = Flask(__name__)
     @app.route('/')
     def index():
          generate_img("test.jpg"); #save inside static folder
          return '<img src=' + url_for('static',filename='test.jpg') + '>' 

Static folder is there to serve all the media, be it css, javascript,video or image files with everything accessible at mydomai.com/static/filename. Remember you should not use flask serving from static folder in production. This feature is only for development.

codecool
  • 5,886
  • 4
  • 29
  • 40
  • so for production, don't use static folder? do you mean to use a different folder name? – KJW Aug 20 '12 at 18:55
  • You may use static folder then too but you have to setup Apache or any server you use to load media from that folder. Otherwise if flask continues to serve those itself you would have performance issues. Check out last lines of this blogpost to know how to set Apache for this http://manavgoel.net/blog/post/2012/7/Deploying-flask-website-on-webfaction – codecool Aug 20 '12 at 21:09
7

Assuming the image is actually generated (that is, that index() is called), the reason for the 404 is that there is no route that points to the image, so Flask will tell you there is no mydomain.com/test.jpg. A static webserver like Apache or Nginx will by default map paths from a root to URLs, but an ordinary Flask/Werkzeug/WSGI setup will not do that.

Perhaps you want to create a resource that directly returns the image instead?

EDIT: Something similar should be able to serve images.

@app.route("/imgs/<path:path>")
def images(path):
    generate_img(path)
    fullpath = "./imgs/" + path
    resp = flask.make_response(open(fullpath).read())
    resp.content_type = "image/jpeg"
    return resp

EDIT2: Of course, generate_img could probably be rewritten so it never write to disk but instead return image data directly.

Bittrance
  • 2,202
  • 2
  • 20
  • 29
  • 1
    how to create resource that directly returns the image? so is this not possible to do in Flask at all? I want basically images, and files to be accessible from Flask server. – KJW Aug 20 '12 at 09:27
  • Be careful of file traversal attacks with this answer. – ViolinFour Apr 10 '23 at 03:21