A while ago, I took Udacity’s CS253 “Web Development” class.
I’m still a newb when it comes to programming and python, but have been practicing and trying out new things since finishing the class.
When I came up with a new idea for using Python, I would Google what I was trying to do and usually came across a python module related to my idea. It was pretty awesome that someone out there had already programmed a script to make my idea easier, but it was not awesome that Google App Engine only allows specific modules to be imported into their environment.
So I decided to break away from Google App Engine and try to get a server / application up and running on my own. I found the webapp2 module, installed it for Python 2.7 and found it to work great. It works just like it does in all the CS253 examples. The template looks something like this:
class Handler(webapp2.RequestHandler):
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def render_str(self, template, **params):
params['user'] = self.user
return render_str(template, **params)
def render(self, template, **kw):
self.write(self.render_str(template, **kw))
class Main(Handler):
def get(self):
self.render('index.html')
class WhateverHandler(Handler)
def get(self):
self.render('index.html')
app = webapp2.WSGIApplication([
('/', Main),
('/whatever', WhateverHandler),
],
debug=True)
def main():
from paste import httpserver
httpserver.serve(app, host='0.0.0.0', port='8083')
if __name__ == '__main__':
main()
And that’s awesome and it works great and etc etc; but what happens when you want to put an image on your site? Good luck. I ran into a lot of problems, with the image not being found on the server and python interpreting jpgs and pngs as text and was trying to write that out to the browser.
Here is a quick solution for you beginner programmers like me. Lets just assume for now you are using JPGs only.
1) Create framework for image requests:
Create a new def in your ‘Class Handler(webapp2.RequestHandler): called “def image:”.
The problems I encountered were the browser seeing whatever JPG I was trying to send to it as a text file. We need to tell the browser that this is a JPG, and we do this with the line “ self.response.headers['Content-Type'] = ’image/jpeg’ ” which changes the ‘header’ of the message that the server is sending the browser.
Then we need to tell python to spit out the image, and we do this with the line “self.response.out.write(open(images_dir + filename + extension,”rb”).read())”
This breaks it out so we can tell python the directory the file is located in, the filename and the extension.
The final product looks like this:
class Handler(webapp2.RequestHandler):
def image(self, images_dir, filename, extension):
self.response.headers['Content-Type'] = 'image/jpeg'
self.response.out.write(open(images_dir + filename + extension,"rb").read())
2) Add a new Handler just for image requests that uses image framework: images_dir is a predefined variable where the images are stored on your server
images_dir = 'img'
class ImageHandler(Handler):
def get(self, filename, extension):
self.image(templates_dir + '/' + images_dir, filename, extension)
3) Add a configuration line to route requests for images to the ImageHandler: FILE_RE is a ‘regular expression’ built to break files up into their name and extension
import re
FILE_RE = r'(.+?)(\.[^.]*$|$)'
app = webapp2.WSGIApplication([
('/', Main),
('/img' + FILE_RE , ImageHandler),
('/whatever', WhateverHandler),
],
debug=True)
def main():
from paste import httpserver
httpserver.serve(app, host='0.0.0.0', port='8083')
if __name__ == '__main__':
main()
4) Finally, we have
import re
import webapp2
FILE_RE = r'(.+?)(\.[^.]*$|$)'
class Handler(webapp2.RequestHandler):
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def render_str(self, template, **params):
params['user'] = self.user
return render_str(template, **params)
def render(self, template, **kw):
self.write(self.render_str(template, **kw))
def image(self, images_dir, filename, extension):
self.response.headers['Content-Type'] = 'image/jpeg'
self.response.out.write(open(images_dir + filename + extension,"rb").read())
class Main(Handler):
def get(self):
self.render('index.html')
class WhateverHandler(Handler)
def get(self):
self.render('index.html')
class ImageHandler(Handler):
def get(self, filename, extension):
self.image(templates_dir + '/' + images_dir, filename, extension)
app = webapp2.WSGIApplication([
('/', Main),
('/img' + FILE_RE , ImageHandler),
('/whatever', WhateverHandler),
],
debug=True)
def main():
from paste import httpserver
httpserver.serve(app, host='0.0.0.0', port='8083')
if __name__ == '__main__':
main()
Let me know what you think.


