views:

297

answers:

4

Hello there fellow SOers,

I would like to send dynamically created images to my users, such as charts, graphs etc. These images are "throw-away" images, they will be only sent to one user and then destroyed, hence the "no files involved".

I would like to send the image directly to the user, without saving it on the file system first. With PHP this could be achieved by linking an image in your HTML files to a PHP script such as:

edit: SO swallowed my image tag:

<img src="someScript.php?param1=xyz">

The script then sent the correct headers (filetype=>jpeg etc) to the browser and directly wrote the image back to the client, without temporarily saving it to the file system.

How could I do something like this with a WSGI application. Currently I am using Python's internal SimpleWSGI Server. I am aware that this server was mainly meant for demonstration purposes and not for actual use, as it lacks multi threading capabilities, so please don't point this out to me, I am aware of that, and for now it fulfills my requirements :)

Is it really as simple as putting the URL into the image tags and handling the request with WSGI, or is there a better practise?

Has anyone had any experience with this and could give me a few pointers (no 32Bit ones please)

Thanks,

Tom

+2  A: 

YES. It is as simple as putting the url in the page.

<img src="url_to_my_application">

And your application just have to return it with the correct mimetype, just like on PHP or anything else. Simplest example possible:

def application(environ, start_response):
    data = open('test.jpg', 'rb').read() # simulate entire image on memory
    start_response('200 OK', [('content-type': 'image/jpeg'), 
                              ('content-length', str(len(data)))])
    return [data]

Of course, if you use a framework/helper library, it might have helper functions that will make it easier for you.

I'd like to add as a side comment that multi-threading capabilities are not quintessential on a web server. If correctly done, you don't need threads to have a good performance.

If you have a well-developed event loop that switches between different requests, and write your request-handling code in a threadless-friendly manner (by returning control to the server as often as possible), you can get even better performance than using threads, since they don't make anything run faster and add overhead.

See twisted.web for a good python web server implementation that doesn't use threads.

nosklo
thanks a lot for your great answer, also for the good info about the threading thing. I set the first answer as the correct one simply because he was a little bit faster than you, and the actual answers to the problem are almost equal. But consider your answer also as the correct one, if I could set two right ones, yours would also be one of them :)
Tom
@Tom: Actually I was faster (my answer says right now "answered 44 mins ago" and his one says "answered 42 mins ago") but since I edited my answer afterwards, I think it got down on the list. Also, I seem to have more info in a smaller, clearer answer. But whatever, it's your call.
nosklo
+5  A: 

It is not related to WSGI or php or any other specific web technology. consider

<img src="someScript.php?param1=xyz">

in general for url "someScript.php?param1=xyz" server should return data of image type and it would work

so consider this example

from wsgiref.simple_server import make_server

def serveImage(environ, start_response):
    status = '200 OK'
    headers = [('Content-type', 'image/png')]
    start_response(status, headers)

    return open("about.png", "rb").read()

httpd = make_server('', 8000, serveImage)
httpd.serve_forever()

so any url pointing to serveImage will return a valid image and you can use it in img tag now Image data can be generated on the fly using many third party libraries e.g. PIL etc

edit: see examples of generating images dynamically using python imaging library http://lost-theory.org/python/dynamicimg.html

Anurag Uniyal
A: 

For a fancy example that uses this technique, please see the BNF railroad diagram WHIFF mini-demo. You can get the source from the WHIFF wsgi toolkit download.

Aaron Watters
A: 

You should consider using and paying attention to ETag headers. It's a CGI script, not WSGI, but the ideas are translatable: sparklines source -- it happens to always return the same image for the same parameters, so it practices extreme caching.

ianb