Wednesday, June 16, 2010

Images from web in python gui

I have an application that I use to monitor data produced by a webservice. This webservice produces a new image ( a .png graph to be precise ) every 15 seconds. Basically I have four cron jobs that execute every minute. Three of these are configured to sleep for 15s, 30s and 45s respectivley. So that's one way to make cron do stuff more often than once a minute.

Anyway, I have been using a web browser and some fancy ajax type functions to continuously display this graph and some other JSON data from the webserver every 15 seconds forever. We have a group of people who have the job of watching my graphs and data among a whole bunch of other stuff in case they might provide some alert to a problem.

Anyway, I have been wondering, of late, about the reliablility of using a web browser for monitoring. The web browser is not refreshing itself and so I am a little worried that it just kind of get's stuck at times. I think it looses the AJAXIAN plot so to speak. This is why I started making a python gui using the following python modules:
  • httplib
  • json
  • urrlib
  • wx
  • logging
I will only show three classes here for reference purposes.

There is also a threading module required. This bit of handy code is at the bottom and I must apologies to the author of this code as I failed to take a note of his name / URL and so can not reference the source.

This is the Web client class that I use to retrieve the http / JSON content and the image content from my webserver.

#!/usr/bin/env python

import httplib
import urllib

class HTTP_Client(httplib.HTTPConnection):

def __init__(self, url):
httplib.HTTPConnection.__init__(self, url)


def getPage(self, page):
self.request("GET", "/%s" % page)
r = self.getresponse()
data = r.read()
if r.status == 200 and r.reason == "OK":
return urllib.base64(data)
else:
return "E Fetching %s: %s %s" % (page, r.status, r.reason)

if __name__ == "__main__":
hc = HttpClient("www.python.org")
print hc.getPage("parrot.spam")
print hc.getPage("index.html")


This is an example of how to display an image on a panel using the wx gui toolkit. I think this is a mostly coding by google but it's not a big leap to make it useful. I believe my real program uses the _Image.SetBitmap(_Bitmap) method to update the bitmap.


#!/usr/bin/env python

import urllib
import wx
import cStringIO

class Panel1(wx.Panel):
""" class Panel1 creates a panel with an image on it, inherits wx.Panel"""
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
try:
url = "http://www.photoshopsupport.com/photoshop-blog/07/2008/photoshop-blog/istockphoto-free-photo-credits.jpg"
data = urllib.urlopen(url).read()
stream = cStringIO.StringIO(data)
bmp = wx.BitmapFromImage( wx.ImageFromStream( stream ) )
wx.StaticBitmap(self, -1, bmp, (5,5))
except IOError:
print "Image file %s is not found" % url
raise SystemExit

app = wx.PySimpleApp()
frame1 = wx.Frame(None, -1, "An image on a panel", size=(400,300))
Panel1(frame1, -1)
frame1.Show(1)
app.MainLoop()


This is the logger object. It sets up a logger and a formatter as well as a few actual logging methods. These just expose the internal methods of the logging module provided in default python.


#!/usr/bin/env python
import logging
import logging.handlers

class CDLogger(object):

def __init__(self):
self.log = logging.getLogger('cdBurner')
self.log.setLevel(logging.INFO)

hand = logging.FileHandler("cdburner.log", 'a')
form = logging.Formatter("%(asctime)s %(levelname)-10s %(message)s")

hand.setFormatter(form)
self.log.addHandler(hand)

def info(self, message):
self.log.info(message)

def debug(self, message):
self.log.debug(message)

def warning(self, message):
self.log.warning(message)

def error(self, message):
self.log.error(message)



Here is the threading module that is used to execute the timer.


Code on my laptop so I need to get it from the laptop. Will do this later.