<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xml:lang="en"><title type="text">Corey Goldberg</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/search/label/python" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/goldblog/python" /><subtitle type="html">Blog - Technology, Programming</subtitle><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-05-25T19:34:38+00:00</updated><generator uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">106</openSearch:totalResults><openSearch:startIndex xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">1</openSearch:startIndex><openSearch:itemsPerPage xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">25</openSearch:itemsPerPage><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="goldblog/python" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><id>tag:blogger.com,1999:blog-5236867476487043111</id><geo:lat>42.349622</geo:lat><geo:long>-71.073722</geo:long><entry><title type="text">SST 0.2.1 Release Announcement (selenium-simple-test)</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2012/04/sst-021-release-announcement-selenium.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-04-23T11:02:26-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-5754354347068900419</id><content type="html">&lt;p&gt;
&lt;strong&gt;SST version 0.2.1 has been released.&lt;/strong&gt;
&lt;/p&gt;

&lt;img src="http://testutils.org/sst/_static/sst-logo_small.png" /&gt;

&lt;p&gt;
&lt;a href="http://testutils.org/sst"&gt;SST&lt;/a&gt; (selenium-simple-test) is a web test framework that uses Python to generate functional browser-based tests.
&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;
SST version 0.2.1 is on PyPI: &lt;a href="http://pypi.python.org/pypi/sst"&gt;http://pypi.python.org/pypi/sst&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
install or upgrade with:
&lt;/p&gt;
&lt;pre style="font-size:15px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:8px;"&gt;
pip install -U sst
&lt;/pre&gt;

&lt;p&gt;
Changelog: &lt;a href="http://testutils.org/sst/changelog.html"&gt;http://testutils.org/sst/changelog.html&lt;/a&gt;&lt;br /&gt;
SST Docs: &lt;a href="http://testutils.org/sst"&gt;http://testutils.org/sst&lt;/a&gt;&lt;br /&gt;
SST on Launchpad: &lt;a href="https://launchpad.net/selenium-simple-test"&gt;https://launchpad.net/selenium-simple-test&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;
SST downloads | (Jan 1 2012 - April 23 2012)
&lt;/p&gt;

&lt;div class="separator" style="clear: both;"&gt;
&lt;a href="http://2.bp.blogspot.com/-NfGlXi6Cfoo/T5WYhY7BTDI/AAAAAAAADPU/N6CsEVFjaGM/s1600/SST_downloads_pypi_2012-04-23.png" imageanchor="1" style=""&gt;&lt;img border="0" height="276" width="400" src="http://2.bp.blogspot.com/-NfGlXi6Cfoo/T5WYhY7BTDI/AAAAAAAADPU/N6CsEVFjaGM/s400/SST_downloads_pypi_2012-04-23.png" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;
1600+ downloads from PyPI since initial release.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-5754354347068900419?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-NfGlXi6Cfoo/T5WYhY7BTDI/AAAAAAAADPU/N6CsEVFjaGM/s72-c/SST_downloads_pypi_2012-04-23.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><title type="text">Python - Getting Data Into Graphite - Code Examples</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2012/04/python-getting-data-into-graphite-code.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-04-09T09:16:49-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-3479065951823805010</id><content type="html">&lt;p&gt;
This post shows code examples in Python (2.7) for sending data to &lt;a href="http://coreygoldberg.blogspot.com/2012/04/python-graphite-storage-and.html"&gt;Graphite&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Once you have a &lt;a href="http://coreygoldberg.blogspot.com/2012/04/installing-graphite-099-on-ubuntu-1204.html"&gt;Graphite server setup&lt;/a&gt;, with Carbon running/collecting, you need to send it data for graphing.
&lt;/p&gt;

&lt;p&gt;
Basically, you write a program to collect numeric values and send them to Graphite's backend aggregator (Carbon).
&lt;/p&gt;

&lt;p&gt;
To send data, you create a &lt;a href="http://docs.python.org/library/socket.html"&gt;socket&lt;/a&gt; connection to the graphite/carbon server and send a message (string) in the format:
&lt;/p&gt;

&lt;pre style="font-size:13px;border:0.5px #999999 solid;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:4px;"&gt;
"metric_path value timestamp\n"
&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;`metric_path`&lt;/b&gt;: arbitrary namespace containing substrings delimited by dots. The most general name is at the left and the most specific is at the right.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;`value`&lt;/b&gt;: numeric value to store.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;`timestamp`&lt;/b&gt;: epoch time.&lt;/li&gt;
  &lt;li&gt;messages must end with a trailing newline.&lt;/li&gt;
  &lt;li&gt;multiple messages maybe be batched and sent in a single socket operation. each message is delimited by a newline, with a trailing newline at the end of the message batch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Example message:
&lt;/p&gt;

&lt;pre style="font-size:13px;border:0.5px #999999 solid;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:4px;"&gt;
"foo.bar.baz 42 74857843\n" 
&lt;/pre&gt;

&lt;p&gt;
Let's look at some (Python 2.7) code for sending data to graphite...
&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;
Here is a simple client that sends a single message to graphite.
&lt;/p&gt;

&lt;p&gt;
Code:
&lt;/p&gt;

&lt;pre style="font-size:12px;border:0.5px #999999 solid;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:4px;"&gt;
#!/usr/bin/env python

import socket
import time


CARBON_SERVER = '0.0.0.0'
CARBON_PORT = 2003

message = 'foo.bar.baz 42 %d\n' % int(time.time())

print 'sending message:\n%s' % message
sock = socket.socket()
sock.connect((CARBON_SERVER, CARBON_PORT))
sock.sendall(message)
sock.close()

&lt;/pre&gt;

&lt;hr /&gt;

&lt;p&gt;
Here is a command line client that sends a single message to graphite:
&lt;/p&gt;

&lt;p&gt;
Usage: 
&lt;/p&gt;

&lt;pre style="font-size:12px;border:0.5px #999999 solid;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:4px;"&gt;
$ python client-cli.py metric_path value
&lt;/pre&gt;

&lt;p&gt;
Code:
&lt;/p&gt;

&lt;pre style="font-size:12px;border:0.5px #999999 solid;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:4px;"&gt;
#!/usr/bin/env python

import argparse
import socket
import time


CARBON_SERVER = '0.0.0.0'
CARBON_PORT = 2003


parser = argparse.ArgumentParser()
parser.add_argument('metric_path')
parser.add_argument('value')
args = parser.parse_args()


if __name__ == '__main__':
    timestamp = int(time.time())
    message = '%s %s %d\n' % (args.metric_path, args.value, timestamp)
    
    print 'sending message:\n%s' % message
    sock = socket.socket()
    sock.connect((CARBON_SERVER, CARBON_PORT))
    sock.sendall(message)
    sock.close()

&lt;/pre&gt;   

&lt;hr /&gt;

&lt;p&gt;
Here is a client that collects &lt;a href="http://en.wikipedia.org/wiki/Load_(computing)"&gt;load average&lt;/a&gt; (Linux-only) and sends a batch of 3 messages (1min/5min/15min loadavg) to graphite.  It will run continuously in a loop until killed.  (adjust the delay for faster/slower collection interval):
&lt;/p&gt;

&lt;pre style="font-size:12px;border:0.5px #999999 solid;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:4px;"&gt;
#!/usr/bin/env python
 
import platform
import socket
import time


CARBON_SERVER = '0.0.0.0'
CARBON_PORT = 2003
DELAY = 15  # secs


def get_loadavgs():
    with open('/proc/loadavg') as f:
        return f.read().strip().split()[:3]


def send_msg(message):
    print 'sending message:\n%s' % message
    sock = socket.socket()
    sock.connect((CARBON_SERVER, CARBON_PORT))
    sock.sendall(message)
    sock.close()


if __name__ == '__main__':
    node = platform.node().replace('.', '-')
    while True:
        timestamp = int(time.time())
        loadavgs = get_loadavgs()
        lines = [
            'system.%s.loadavg_1min %s %d' % (node, loadavgs[0], timestamp),
            'system.%s.loadavg_5min %s %d' % (node, loadavgs[1], timestamp),
            'system.%s.loadavg_15min %s %d' % (node, loadavgs[2], timestamp)
        ]
        message = '\n'.join(lines) + '\n'
        send_msg(message)
        time.sleep(DELAY)

&lt;/pre&gt;

&lt;hr /&gt;

&lt;p&gt;
Resources:
&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://graphite.wikidot.com"&gt;Graphite Docs&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://graphite.wikidot.com/getting-your-data-into-graphite"&gt;Graphite Docs - Getting Your Data Into Graphite&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://coreygoldberg.blogspot.com/2012/04/installing-graphite-099-on-ubuntu-1204.html"&gt;Installing Graphite 0.9.9 on Ubuntu 12.04 LTS&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://agiletesting.blogspot.com/2011/04/installing-and-configuring-graphite.html"&gt;Installing and configuring Graphite&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-3479065951823805010?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry><title type="text">Installing Graphite 0.9.9 on Ubuntu 12.04 LTS</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2012/04/installing-graphite-099-on-ubuntu-1204.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-04-07T10:26:30-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-2575951543578343606</id><content type="html">&lt;p&gt;
I just setup a &lt;a href="http://coreygoldberg.blogspot.com/2012/04/python-graphite-storage-and.html"&gt;Graphite server&lt;/a&gt; on Ubuntu 12.04 (Precise).
&lt;/p&gt;

&lt;p&gt;
Here are some instructions for getting it all working (using Apache as web server).
&lt;/p&gt;

&lt;p&gt;
It follows these steps:
&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;install system dependencies (apache, django, dev libs, etc)&lt;/li&gt;
    &lt;li&gt;install Whisper (db lib)&lt;/li&gt;
    &lt;li&gt;install and configure Carbon (data aggregator)&lt;/li&gt;
    &lt;li&gt;install Graphite (django webapp)&lt;/li&gt;
    &lt;li&gt;configure Apache (http server)&lt;/li&gt;
    &lt;li&gt;create initial database&lt;/li&gt;
    &lt;li&gt;start Carbon (data aggregator)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Once that is done, you should be able to visit the host in your web browser and see the Graphite UI.
&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Setup Instructions:&lt;/p&gt;

&lt;pre style="font-size:10px;border:0.5px #999999 solid;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:2px;"&gt;
#############################
# INSTALL SYSTEM DEPENDENCIES
#############################

$ sudo apt-get install apache2 libapache2 libapache2-mod-wsgi /
    libapache2-mod-python memcached python-dev python-cairo-dev /
    python-django python-ldap python-memcache python-pysqlite2 /
    python-pip sqlite3 erlang-os-mon erlang-snmp rabbitmq-server
    
$ sudo pip install django-tagging

#################
# INSTALL WHISPER
#################

$ sudo pip install http://launchpad.net/graphite/0.9/0.9.9/+download/whisper-0.9.9.tar.gz

################################################
# INSTALL AND CONFIGURE CARBON (data aggregator)
################################################

$ sudo pip install http://launchpad.net/graphite/0.9/0.9.9/+download/carbon-0.9.9.tar.gz
$ cd /opt/graphite/conf/
$ sudo cp carbon.conf.example carbon.conf
$ sudo cp storage-schemas.conf.example storage-schemas.conf

###########################
# INSTALL GRAPHITE (webapp)
###########################

$ sudo pip install http://launchpad.net/graphite/0.9/0.9.9/+download/graphite-web-0.9.9.tar.gz

or

$ wget http://launchpad.net/graphite/0.9/0.9.9/+download/graphite-web-0.9.9.tar.gz
$ tar -zxvf graphite-web-0.9.9.tar.gz
$ mv graphite-web-0.9.9 graphite
$ cd graphite
$ sudo python check-dependencies.py
$ sudo python setup.py install

##################
# CONFIGURE APACHE
##################

$ cd graphite/examples
$ sudo cp example-graphite-vhost.conf /etc/apache2/sites-available/default
$ sudo cp /opt/graphite/conf/graphite.wsgi.example /opt/graphite/conf/graphite.wsgi
$ sudo mkdir /etc/httpd
$ sudo mkdir /etc/httpd/wsgi
$ sudo /etc/init.d/apache2 reload

#########################
# CREATE INITIAL DATABASE 
#########################

$ cd /opt/graphite/webapp/graphite/
$ sudo python manage.py syncdb
$ sudo chown -R www-data:www-data /opt/graphite/storage/
$ sudo /etc/init.d/apache2 restart
$ sudo cp local_settings.py.example local_settings.py

################################
# START CARBON (data aggregator)
################################

$ cd /opt/graphite/
$ sudo ./bin/carbon-cache.py start

&lt;/pre&gt;

&lt;p&gt;
Resources:
&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://graphite.readthedocs.org/en/latest/install.html"&gt;http://graphite.readthedocs.org/en/latest/install.html&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://graphite.wikidot.com/installation"&gt;http://graphite.wikidot.com/installation&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://geek.michaelgrace.org/2011/09/how-to-install-graphite-on-ubuntu/"&gt;http://geek.michaelgrace.org/2011/09/how-to-install-graphite-on-ubuntu/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;
* works on my machine, Ubuntu 12.04
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-2575951543578343606?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><title type="text">Python - Graphite: Storage and Visualization of Time-series Data</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2012/04/python-graphite-storage-and.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-04-07T04:45:28-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-4866018540846996112</id><content type="html">&lt;p&gt;
I'm doing some work with &lt;strong&gt;Graphite&lt;/strong&gt; in Python.  Here is a quick overview of what Graphite is...
&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;
&lt;strong&gt;Graphite&lt;/strong&gt; provides real-time visualization and storage of numeric time-series data.
&lt;/p&gt;

&lt;p&gt;
Links:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project: &lt;a href="https://launchpad.net/graphite"&gt;https://launchpad.net/graphite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="http://graphite.readthedocs.org"&gt;http://graphite.readthedocs.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Graphite does two things:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store numeric time-series data&lt;/li&gt;
&lt;li&gt;Render graphs of this data on demand&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Graphite consists of a storage backend and a web-based visualization frontend.  Client applications send streams of numeric time-series data to the Graphite backend (called carbon), where it gets stored in fixed-size database files similar in design to RRD. The web frontend provides 2 distinct user interfaces for visualizing this data in graphs as well as a simple URL-based API for direct graph generation.
&lt;/p&gt;

&lt;p&gt;
Graphite consists of 3 software components:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;carbon&lt;/strong&gt; - a Twisted daemon that listens for time-series data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;whisper&lt;/strong&gt; - a simple database library for storing time-series data (similar in design to RRD)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;graphite webapp&lt;/strong&gt; - A Django webapp that renders graphs on-demand using Cairo&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-td4PhqtoLmE/T4AoEmg3krI/AAAAAAAADAs/RboE-QdM2PE/s1600/graphite_web-graph.png" imageanchor="1" style=""&gt;&lt;img border="0" height="298" width="400" src="http://4.bp.blogspot.com/-td4PhqtoLmE/T4AoEmg3krI/AAAAAAAADAs/RboE-QdM2PE/s400/graphite_web-graph.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-4866018540846996112?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-td4PhqtoLmE/T4AoEmg3krI/AAAAAAAADAs/RboE-QdM2PE/s72-c/graphite_web-graph.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></entry><entry><title type="text">Python Book Giveaway - Boston Python User Group - April 12, 2012</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2012/04/python-book-giveaway-boston-python-user.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-04-05T06:17:52-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-3974517846451529992</id><content type="html">&lt;p&gt;
I am bringing some of my [lightly read] Python books to give away at the next &lt;a href="http://meetup.bostonpython.com"&gt;Boston Python User Group&lt;/a&gt; meetup.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;&lt;a href="http://meetup.bostonpython.com/events/51175882/"&gt;Boston Python User Group - April Project Night&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;i&gt;When&lt;/i&gt;: Thursday, April 12, 2012, 6:30 PM&lt;br /&gt;
&lt;i&gt;Where&lt;/i&gt;: Microsoft NERD, Cambridge&lt;br /&gt;
&lt;/p&gt;


&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;a href="http://2.bp.blogspot.com/-zTGQdzWdbzI/T32a4EiCHBI/AAAAAAAADAc/s_Z_e77KSgA/s1600/bostonpython-book-giveaway.jpg" imageanchor="1" style=""&gt;&lt;img border="0" height="300" width="400" src="http://2.bp.blogspot.com/-zTGQdzWdbzI/T32a4EiCHBI/AAAAAAAADAc/s_Z_e77KSgA/s400/bostonpython-book-giveaway.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;
Books:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pro Python (Alchin)&lt;/li&gt;
&lt;li&gt;Head First Python (Barry)&lt;/li&gt;
&lt;li&gt;Programming in Python 3 (Summerfield)&lt;/li&gt;
&lt;li&gt;Python Programming Patterns (Christopher)&lt;/li&gt;
&lt;li&gt;Hello World! (Sande)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
If you are interested in getting a free book, come to #bostonpython Project Night on April 12!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-3974517846451529992?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-zTGQdzWdbzI/T32a4EiCHBI/AAAAAAAADAc/s_Z_e77KSgA/s72-c/bostonpython-book-giveaway.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><title type="text">Python Screencast: Install/Setup "SST Web Test Framework" on Ubuntu 12.04</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2012/03/python-screencast-installsetup-sst-web.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-03-24T09:59:24-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-3183044741162023684</id><content type="html">&lt;p&gt;
I uploaded a 5 minute video/screencast showing how to install and setup &lt;a href="http://testutils.org/sst/"&gt;SST Web Test Framework&lt;/a&gt; on &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt; (Precise Pangolin 12.04).
&lt;/p&gt;

&lt;p&gt;
I step through: creating a virtualenv, installing &lt;a href="http://testutils.org/sst/"&gt;SST&lt;/a&gt; from &lt;a href="http://pypi.python.org/pypi/sst"&gt;PyPI&lt;/a&gt;, and creating a basic automated web test:
&lt;/p&gt;

&lt;a href="http://www.youtube.com/watch?v=LpSvGmglZPI"&gt;http://www.youtube.com/watch?v=LpSvGmglZPI&lt;/a&gt;
&lt;br /&gt;

&lt;iframe width="480" height="360" src="http://www.youtube.com/embed/LpSvGmglZPI?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;
the following steps are essentially a transcript of what I did...
&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;
install system package dependencies:
&lt;/p&gt;

&lt;pre style="font-size:14px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:6px;"&gt;
$ sudo apt-get install python-virtualenv xvfb
&lt;/pre&gt;

&lt;p&gt;
create a "&lt;a href="http://www.virtualenv.org"&gt;virtualenv&lt;/a&gt;":
&lt;/p&gt;

&lt;pre style="font-size:14px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:6px;"&gt;
$ virtualenv ENV
&lt;/pre&gt;

&lt;p&gt;
active the virtualenv:
&lt;/p&gt;

&lt;pre style="font-size:14px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:6px;"&gt;
$ cd ENV
$ source bin/activate
(ENV)$
&lt;/pre&gt;

&lt;p&gt;
&lt;i&gt;* notice your prompt changed, signifying the virtualenv is active&lt;/i&gt;
&lt;/p&gt;

&lt;p&gt;
install SST using `&lt;a href="http://www.pip-installer.org"&gt;pip&lt;/a&gt;`:
&lt;/p&gt;

&lt;pre style="font-size:14px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:6px;"&gt;
(ENV)$ pip install sst
&lt;/pre&gt;

&lt;p&gt;
Now SST is installed.  You can check the version of SST:
&lt;/p&gt;

&lt;pre style="font-size:14px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:6px;"&gt;
$ sst-run -V
&lt;/pre&gt;

&lt;hr /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-3183044741162023684?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/LpSvGmglZPI/default.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><title type="text">Codeswarm - Python Core Development Visualization</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2012/03/codeswarm-python-core-development.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-03-08T09:14:52-08:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-5729428969472644513</id><content type="html">&lt;p&gt;
particle visualization of Python core development commits: Jan 1, 2010 - Mar 06, 2012
&lt;/p&gt;

&lt;a href="http://www.youtube.com/watch?v=IQPuU_YtN8Q"&gt;http://www.youtube.com/watch?v=IQPuU_YtN8Q&lt;/a&gt;&lt;br /&gt;

&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/IQPuU_YtN8Q" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;

&lt;p&gt;
data source is the commit log from cpython mercurial trunk:
&lt;/p&gt;

&lt;pre style="font-size:14px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:6px;"&gt;
$ hg clone http://hg.python.org/cpython
&lt;/pre&gt;

&lt;p&gt;
... trimmed to show development activity since Jan 1, 2010.
&lt;/p&gt;

&lt;p&gt;
(images making up this video were rendered with: &lt;a href="http://www.michaelogawa.com/code_swarm/"&gt;Codeswarm&lt;/a&gt;)
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-5729428969472644513?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/IQPuU_YtN8Q/default.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><title type="text">SST - Automated Web Page Profiling (Python)</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2012/03/sst-automated-web-page-profiling-python.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-03-05T06:04:10-08:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-8749377410492757625</id><content type="html">&lt;p&gt;
SST - Web Test Framework: &lt;a href="http://testutils.org/sst"&gt;http://testutils.org/sst&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
The latest release of SST (0.2.0) adds the ability to capture &lt;a href="http://www.softwareishard.com/blog/har-12-spec/"&gt;HAR (HTTP Archive format)&lt;/a&gt; output for pageload performance tracing/profiling.
&lt;/p&gt;

&lt;p&gt;
New SST doc section: &lt;a href="http://testutils.org/sst/#performance-tracing-with-browsermob-proxy-har"&gt;Performance tracing with Browsermob Proxy (HAR)&lt;/a&gt;
&lt;/p&gt;
    
&lt;p&gt;
The HAR format is based on JSON, and is used by tools that consume/produce data collected by monitoring HTTP communication.  These files contain a log of HTTP client/server conversation and can be used for additional analysis of page load performance.
&lt;/p&gt;

&lt;p&gt;
The capture is achieved by routing browser requests through &lt;a href="http://opensource.webmetrics.com/browsermob-proxy/"&gt;BrowserMob Proxy&lt;/a&gt;, which records web page loads while your tests run. SST will launch the proxy and save output to .har files if you enable the `--browsermob` command line option. 
HAR files are saved in the results directory for each page load.
&lt;/p&gt;

&lt;p&gt;
HAR files can be viewed/analyzed with various tools, such as `harviewer`:
  &lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.softwareishard.com/har/viewer/"&gt;http://www.softwareishard.com/har/viewer/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://pcapperf.appspot.com/"&gt;http://pcapperf.appspot.com/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://code.google.com/p/harviewer/"&gt;http://code.google.com/p/harviewer/&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
I created a screencast demo showing it all together:  
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;&lt;a href="http://www.youtube.com/watch?v=eJxxP9tZfAo"&gt;Automated Web Page Profiling : SST + BrowserMob&lt;/a&gt;&lt;/b&gt;
&lt;/p&gt;

&lt;iframe width="420" height="315" src="http://www.youtube.com/embed/eJxxP9tZfAo" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-8749377410492757625?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/eJxxP9tZfAo/default.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><title type="text">SST 0.2.0 Release Announcement (and codebase visualization)</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2012/02/sst-020-release-announcement-and.html" /><category term="python" /><category term="Canonical" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-02-27T09:47:52-08:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-3059175347800814451</id><content type="html">&lt;p&gt;
&lt;a href="http://testutils.org/sst"&gt;SST&lt;/a&gt; (selenium-simple-test) is a web test framework that uses Python to generate functional browser-based tests.
&lt;/p&gt;

&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;a href="http://testutils.org/sst/_static/sst-logo_small.png" imageanchor="1" style=""&gt;&lt;img border="0" height="80" width="202" src="http://testutils.org/sst/_static/sst-logo_small.png" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;h3&gt;Version 0.2.0 Released!&lt;/h3&gt;

&lt;p&gt;
SST version 0.2.0 is on PyPI: &lt;a href="http://pypi.python.org/pypi/sst"&gt;http://pypi.python.org/pypi/sst&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
install or upgrade with:
&lt;/p&gt;
&lt;pre style="font-size:15px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:8px;"&gt;
pip install -U sst
&lt;/pre&gt;

&lt;p&gt;
Changelog: &lt;a href="http://testutils.org/sst/changelog.html"&gt;http://testutils.org/sst/changelog.html&lt;/a&gt;&lt;br /&gt;
SST Docs: &lt;a href="http://testutils.org/sst"&gt;http://testutils.org/sst&lt;/a&gt;&lt;br /&gt;
SST on Launchpad: &lt;a href="https://launchpad.net/selenium-simple-test"&gt;https://launchpad.net/selenium-simple-test&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;hr /&gt;

&lt;h3&gt;Development Update&lt;/h3&gt;

&lt;p&gt;
So... what's up with SST development?  is it active?
&lt;/p&gt;

&lt;p&gt;
I ran &lt;a href="http://code.google.com/p/gource/"&gt;Gource&lt;/a&gt; against the trunk branch and created an awesome visualization (with soundtrack!) to show off development activity:
&lt;/p&gt;

&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/5EEicYCRqjY?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;
video: &lt;a href="http://www.youtube.com/watch?v=5EEicYCRqjY"&gt;link (with soundtrack)&lt;/a&gt;&lt;br /&gt;
video: &lt;a href="http://www.youtube.com/watch?v=jB9uWpxJg2I"&gt;link (no soundtrack)&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
The magic incantation of `gource` to produce the video:
&lt;/p&gt;

&lt;pre style="font-size:14px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding:8px;"&gt;
$ gource \
    -s .3 \
    -1280x720 \
    --auto-skip-seconds .3 \
    --multi-sampling \
    --stop-at-end \
    --hide mouse,progress \
    --file-idle-time 0 \
    --max-files 0  \
    --background-colour 222222 \
    --font-size 20 \
    --logo docs/assets/sst-logo_small.png \
    --title "SST Development - lp:selenium-simple-test" \
    --output-ppm-stream - \
    --output-framerate 30 \
    | ffmpeg -y -r 30 -f image2pipe -vcodec ppm -i - -b 2048K movie.mp4
&lt;/pre&gt;

&lt;p&gt;
(rendered on Ubuntu 11.10, audio mixed with Pitivi)
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-3059175347800814451?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/5EEicYCRqjY/default.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><georss:featurename xmlns:georss="http://www.georss.org/georss">Boston, MA, USA</georss:featurename><georss:point xmlns:georss="http://www.georss.org/georss">42.3584308 -71.0597732</georss:point><georss:box xmlns:georss="http://www.georss.org/georss">42.2645643 -71.21770169999999 42.4522973 -70.9018447</georss:box></entry><entry><title type="text">Python - Matplotlib and Numpy on Debian/Ubuntu</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2012/01/python-matplotlib-and-numpy-on.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-01-29T12:38:01-08:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-8891938644331440152</id><content type="html">&lt;p&gt;
There are `&lt;strong&gt;python-matplotlib&lt;/strong&gt;` and `&lt;strong&gt;python-numpy&lt;/strong&gt;` packages in the Debian/Ubuntu repos.
&lt;/p&gt;

&lt;p&gt;
However, if you want to run in a virtualenv (with no-site-packages), and pip install these packages from PyPI, you need some system dependencies installed first to build with:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
$ sudo apt-get install build-essential python-dev libfreetype6-dev libpng-dev python-virtualenv
&lt;/pre&gt;

&lt;p&gt;
Then, you can create a virtualenv, and the installers for Numpy and Matplotlib will work:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
$ virtualenv env
$ cd env
$ source bin/activate
(env)$ pip install numpy matplotlib

...
...
Successfully installed numpy matplotlib
Cleaning up...
&lt;/pre&gt;

&lt;p&gt;
(tested on Ubuntu Oneiric 11.10 and Ubuntu Precise 12.04 alpha)
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-8891938644331440152?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></entry><entry><title type="text">Officially Introducing "SST" (Python Web Test Framework)</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2012/01/officially-introducing-sst-python-web.html" /><category term="python" /><category term="Canonical" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-01-03T06:52:24-08:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-7385818577698113821</id><content type="html">&lt;p&gt;&lt;strong&gt;"SST (selenium-simple-test) is a framework built on Selenium WebDriver, using Python to make writing functional web tests easier with code."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;
Since early 2011, I have been working for &lt;a href="http://www.canonical.com/"&gt;Canonical&lt;/a&gt; on the &lt;a href="https://launchpad.net/~canonical-isd-team/+mugshots"&gt;Infrastructure Systems Development team&lt;/a&gt; (Core Dev Ops).
&lt;/p&gt;

&lt;p&gt;
[&lt;a href="http://dl.dropbox.com/u/216762/Canonical_ISD_hackers_UDS-P_11-03-2011.jpg"&gt;pic of canonical-isd-hackers at UDS-P-Orlando&lt;/a&gt;]
&lt;/p&gt;

&lt;p&gt;
A by-product of our recent development efforts is a web testing framework.  It has been available on &lt;a href="https://launchpad.net/selenium-simple-test"&gt;Launchpad&lt;/a&gt; for a while, but I've never really announced it in public.  We are using SST internally, and I want to expose it to a wider audience.
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Selenium WebDriver?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Selenium (WebDriver) is a popular open-source library for automating browsers.  It can be used to create functional/acceptance tests of a web application.  The Selenium client bindings provide API's that allow you to programatically drive a browser and access web content/elements.  The bindings are available and supported for many languages and platforms.&lt;/p&gt;

&lt;p&gt;While working directly with Selenium API's from code is fine for ad-hoc browser interaction, it is rather low-level and lacks things necessary for creating suites of automated web tests.  For larger-scale testing, you will soon want to use a framework to help organize, execute, and report.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introducing SST...&lt;/strong&gt;&lt;/p&gt;

&lt;img src="http://testutils.org/sst/_static/sst-logo_small.png" alt="SST Logo"&gt;&lt;/img&gt;

&lt;p&gt;SST aims to keep things simple.&lt;/p&gt;

&lt;p&gt;Tests are made up of scripts, created by composing actions that drive a browser and assert conditions. You have the flexibility of the full Python language, along with a convenient set of functions to simplify web testing.&lt;/p&gt;

&lt;p&gt;SST framework consists of:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;user actions and assertions (API) in Python&lt;/li&gt;
    &lt;li&gt;test case loader (generates/compiles scripts to unittest cases)&lt;/li&gt;
    &lt;li&gt;console test runner&lt;/li&gt;
    &lt;li&gt;data parameterization/injection&lt;/li&gt;
    &lt;li&gt;selectable output reports&lt;/li&gt;
    &lt;li&gt;selectable browsers&lt;/li&gt;
    &lt;li&gt;headless (xvfb) mode&lt;/li&gt;
    &lt;li&gt;screenshots on errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Test output can be displayed to the console, saved as an HTML report, or JUnit-compatible XML for compatibility with CI systems.&lt;/p&gt;

&lt;p&gt;SST is free open source software (Apache Licensed).  SST is primarily being developed on Linux, specifically Ubuntu. It should work fine on other platforms, but any issues (or even better - patches) should be reported on the Launchpad project:&lt;/p&gt;
 
&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://launchpad.net/selenium-simple-test"&gt;https://launchpad.net/selenium-simple-test&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I just uploaded SST 0.1.0 to PyPI:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://pypi.python.org/pypi/sst"&gt;http://pypi.python.org/pypi/sst&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;go ahead, give it a try:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;`$ [sudo] pip install sst`&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;documentation and more info:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://testutils.org/sst"&gt;http://testutils.org/sst&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;a sample test script in SST:&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
from sst.actions import *

go_to('http://www.ubuntu.com/')
assert_title_contains('Ubuntu homepage')
&lt;/pre&gt;

&lt;p&gt;Here is the development progress of SST (shown as a code_swarm visualization) over the past 8 months:&lt;p&gt;

&lt;p&gt;&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/PR8Wf05z9CU" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;Special thanks to all the SST code committers so far:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Danny Tamez&lt;/li&gt;
    &lt;li&gt;Julien Funk&lt;/li&gt;
    &lt;li&gt;Kenneth Koontz&lt;/li&gt;
    &lt;li&gt;Leo Arias&lt;/li&gt;
    &lt;li&gt;Lukasz Czyzykowkski&lt;/li&gt;
    &lt;li&gt;Rick McBride&lt;/li&gt;
    &lt;li&gt;Sidnei da Silva&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Extra special thanks to SST's initial creator:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Michael Foord&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy New Year!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-Corey Goldberg&lt;/strong&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-7385818577698113821?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/PR8Wf05z9CU/default.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total></entry><entry><title type="text">"Web Performance Testing night" in Boston/Cambridge - Python Meetup Dec. 19</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2011/12/web-performance-testing-night-in.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2011-12-21T08:46:12-08:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-1694448256836382037</id><content type="html">&lt;p&gt;
I will be speaking at: &lt;strong&gt;"Web Performance Testing, lightning talks, and beers"&lt;/strong&gt; at the &lt;a href="http://meetup.bostonpython.com"&gt;Boston Python User Group&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;Event Info:&lt;/strong&gt; &lt;a href="http://meetup.bostonpython.com/events/36664122/"&gt;http://meetup.bostonpython.com/events/36664122/&lt;/a&gt; &lt;br /&gt;
&lt;strong&gt;Date:&lt;/strong&gt; Monday, December 19, 2011, 7:00 PM &lt;br /&gt;
&lt;strong&gt;Location:&lt;/strong&gt; Microsoft NERD, Cambridge, MA &lt;br /&gt;
&lt;/p&gt;

&lt;p&gt;
&lt;blockquote&gt;&lt;em&gt;"Corey Goldberg of Canonical and Dan Kuebrich of Tracelytics will tag-team to 
tell us about web performance testing, and a few interesting tools they've built."&lt;/em&gt;&lt;/blockquote&gt;
&lt;/p&gt;

&lt;p&gt;
Free pizza and beer! &lt;br /&gt;
Come Join!
&lt;/p&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-s_87-XNniM4/TuYM2QM3puI/AAAAAAAACXQ/hwQO1DoxAQ8/s1600/python-icon.jpg" imageanchor="1" style=""&gt;&lt;img border="0" height="228" width="230" src="http://1.bp.blogspot.com/-s_87-XNniM4/TuYM2QM3puI/AAAAAAAACXQ/hwQO1DoxAQ8/s400/python-icon.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;p&gt;
Edit/Update:&lt;br /&gt;
Thanks to all who attended!  The night was a big success.&lt;br /&gt;
&lt;br /&gt;
The slides from my portion of the presentation are posted here:&lt;br /&gt;
&lt;a href="http://goldb.org/talks/2011/boston-python_webperf/webperf.html"&gt;webperf.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-1694448256836382037?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-s_87-XNniM4/TuYM2QM3puI/AAAAAAAACXQ/hwQO1DoxAQ8/s72-c/python-icon.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total></entry><entry><title type="text">Python - Stock Quotes From Google Finance</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2011/09/python-stock-quotes-from-google-finance.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2011-09-27T05:46:17-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-2408922334076933866</id><content type="html">&lt;p&gt;Quick example of retrieving stock quotes from Google Finance in Python:&lt;/p&gt;&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;#!/usr/bin/env python

import json
import pprint
import urllib2


def get_stock_quote(ticker_symbol):   
    url = 'http://finance.google.com/finance/info?q=%s' % ticker_symbol
    lines = urllib2.urlopen(url).read().splitlines()
    return json.loads(''.join([x for x in lines if x not in ('// [', ']')]))


if __name__ == '__main__':
    quote = get_stock_quote('IBM')
    print 'ticker: %s' % quote['t']
    print 'current price: %s' % quote['l_cur']
    print 'last trade: %s' % quote['lt']
    print 'full quote:'
    pprint.pprint(quote)
&lt;/pre&gt;&lt;p&gt;* note: all values in the returned dict object are Unicode strings.&lt;/p&gt;&lt;p&gt;Output:&lt;/p&gt;&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;ticker: IBM
current price: 174.51
last trade: Sep 26, 4:00PM EDT
full quote:
{u'c': u'+5.17',
 u'ccol': u'chg',
 u'cp': u'3.05',
 u'div': u'0.75',
 u'e': u'NYSE',
 u'ec': u'0.00',
 u'eccol': u'chb',
 u'ecp': u'0.00',
 u'el': u'174.51',
 u'el_cur': u'174.51',
 u'elt': u'Sep 26, 6:07PM EDT',
 u'id': u'18241',
 u'l': u'174.51',
 u'l_cur': u'174.51',
 u'lt': u'Sep 26, 4:00PM EDT',
 u'ltt': u'4:00PM EDT',
 u's': u'2',
 u't': u'IBM',
 u'yld': u'1.72'}
 &lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-2408922334076933866?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry><title type="text">Python - Getting Started With Selenium WebDriver on Ubuntu/Debian</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2011/07/python-getting-started-with-selenium.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2011-07-11T09:48:33-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-8268137651028115633</id><content type="html">&lt;p&gt;
This is a quick introduction to &lt;a href="http://seleniumhq.org/"&gt;Selenium&lt;/a&gt; &lt;a href="http://www.aosabook.org/en/selenium.html"&gt;WebDriver&lt;/a&gt; in Python on Ubuntu/Debian systems.
&lt;/p&gt;

&lt;p&gt;
WebDriver (part of Selenium 2) is a library for automating browsers, and can be used from a variety of language bindings.  It allows you to programmatically drive a browser and interact with web elements.  It is most often used for test automation, but can be adapted to a variety of web scraping or automation tasks.
&lt;/p&gt;

&lt;p&gt;
To use the WebDriver API in Python, you must first install the Selenium Python bindings.  This will give you access to your browser from Python code.  The easiest way to install the bindings is via &lt;a href="http://www.pip-installer.org/"&gt;pip&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
On Ubuntu/Debian systems, this will install pip (and dependencies) and then install the Selenium Python bindings from &lt;a href="http://pypi.python.org/pypi/selenium"&gt;PyPI&lt;/a&gt;:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
$ sudo apt-get install python-pip
$ sudo pip install selenium

&lt;/pre&gt;

&lt;p&gt;
After the installation, the following code should work:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
#!/usr/bin/env python

from selenium import webdriver

browser = webdriver.Firefox()
browser.get('http://www.ubuntu.com/')

&lt;/pre&gt;

&lt;p&gt;
This should open a Firefox browser sessions and navigate to http://www.ubuntu.com/
&lt;/p&gt;

&lt;p&gt;
Here is a simple functional test in Python, using Selenium WebDriver and the &lt;a href="http://docs.python.org/library/unittest.html"&gt;unittest&lt;/a&gt; framework:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
#!/usr/bin/env python

import unittest
from selenium import webdriver


class TestUbuntuHomepage(unittest.TestCase):
    
    def setUp(self):
        self.browser = webdriver.Firefox()
        
    def testTitle(self):
        self.browser.get('http://www.ubuntu.com/')
        self.assertIn('Ubuntu', self.browser.title)
        
    def tearDown(self):
        self.browser.quit()


if __name__ == '__main__':
    unittest.main(verbosity=2)

&lt;/pre&gt;    


&lt;p&gt;Output:&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
testTitle (__main__.TestUbuntuHomepage) ... ok

----------------------------------------------------------------------
Ran 1 test in 5.931s

OK

&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-8268137651028115633?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total></entry><entry><title type="text">Python - Reading MP3 Meta Information with 'mpeg1audio'</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2011/07/python-reading-mp3-meta-information.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2011-07-09T10:25:26-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-1725099691722768667</id><content type="html">&lt;p&gt;
'&lt;a href="https://github.com/Ciantic/mpeg1audio/"&gt;mpeg1audio&lt;/a&gt;' is a Pure Python MPEG Audio Layer 1, 2 and 3 meta information retrieval package.  It is capable of retrieving duration, bitrate, average bitrate, sample count, etc.
&lt;/p&gt;

&lt;p&gt;
Here is an example of using mpeg1audio for getting meta data from a directory of MP3 files.
&lt;/p&gt;

Code:

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
#!/usr/bin/env python

import glob
import mpeg1audio  # (https://github.com/Ciantic/mpeg1audio/)

for f in sorted(glob.glob('*.mp3')):
    mp3 = mpeg1audio.MPEGAudio(f)
    mb = '%.2f' % (mp3.size / 1048576.0)
    fn = f.replace('.mp3', '')
    print '%s (%s) [%dk] %s MB' % (fn, mp3.duration, mp3.bitrate, mb)

&lt;/pre&gt;    

Output:

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
Eminem - Buffalo Bill (0:03:56) [253k] 7.15 MB
Minor Threat - Betray (0:03:02) [180k] 3.92 MB
Social Distortion - Bakersfield (0:06:24) [320k] 14.68 MB
Social Distortion - Diamond In The Rough (0:04:34) [320k] 10.49 MB
Social Distortion - Prison Bound (0:05:24) [227k] 8.81 MB
Social Distortion - When She Begins (0:05:02) [320k] 11.54 MB

&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-1725099691722768667?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry><title type="text">Python - processing GMail IMAP email</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2011/07/python-processing-gmail-imap-email.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2011-07-07T14:34:40-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-6264901944732774336</id><content type="html">&lt;p&gt;
Here is an example of processing your GMail IMAP email in Python.
&lt;/p&gt;

&lt;p&gt;
The script below will:
&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;login to GMail account using IMAP&lt;/li&gt;
    &lt;li&gt;open your Inbox&lt;/li&gt;
    &lt;li&gt;retrieve and print all messages&lt;/li&gt;
    &lt;li&gt;close mailbox&lt;/li&gt;
    &lt;li&gt;logout&lt;/li&gt;
&lt;/ul&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
#!/usr/bin/env python

import imaplib

USER = 'username@gmail.com'
PASSWORD = 'xxx'

mail = imaplib.IMAP4_SSL('imap.gmail.com', 993)
mail.login(USER, PASSWORD)
mail.select('Inbox')

status, data = mail.search(None, 'ALL')
for num in data[0].split():
    status, data = mail.fetch(num, '(RFC822)')
    print 'Message %s\n%s\n' % (num, data[0][1])
   
mail.close()
mail.logout()
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-6264901944732774336?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry><title type="text">Python - Taking Browser Screenshots With No Display (Selenium/Xvfb)</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2011/07/python-taking-browser-screenshots-with.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2011-07-04T10:41:18-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-4263810995486916552</id><content type="html">&lt;p&gt;
In my last two blog posts, I showed examples of using Selenium WebDriver to &lt;a href="http://coreygoldberg.blogspot.com/2011/06/python-selenium-webdriver-capture.html"&gt;capture screenshots&lt;/a&gt;, and &lt;a href="http://coreygoldberg.blogspot.com/2011/06/python-headless-selenium-webdriver.html"&gt;running in a headless (no X-server) mode&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
This example combines the two solutions to capture screenshots inside a virtual display.
&lt;/p&gt;

&lt;p&gt;
To achieve this, I use a combination of Selenium WebDriver and pyvirtualdisplay (which uses xvfb) to run a browser in a virtual display and capture screenshots.
&lt;/p&gt;

&lt;p&gt;
the setup you need is:
&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Selenium 2 Python bindings:  &lt;a href="http://pypi.python.org/pypi/selenium"&gt;PyPI&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;pyvirtualdisplay Python package (depends on &lt;a href="http://en.wikipedia.org/wiki/Xvfb"&gt;xvfb&lt;/a&gt;):  &lt;a href="http://pypi.python.org/pypi/PyVirtualDisplay"&gt;PyPI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
On Debian/Ubuntu Linux systems, you can install everything with:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
$ sudo apt-get install python-pip xvfb xserver-xephyr
$ sudo pip install selenium
&lt;/pre&gt;

&lt;p&gt;
once you have it setup, the following code example should work:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
#!/usr/bin/env python

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=0, size=(800, 600))
display.start()

browser = webdriver.Firefox()
browser.get('http://www.google.com')
browser.save_screenshot('screenie.png')
browser.quit()

display.stop()
&lt;/pre&gt;

&lt;p&gt;
this will:
&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;launch a virtual display&lt;/li&gt;
  &lt;li&gt;launch Firefox browser inside the virtual display&lt;/li&gt;
  &lt;li&gt;navigate to google.com&lt;/li&gt;
  &lt;li&gt;capture and save a screenshot&lt;/li&gt;
  &lt;li&gt;close the browser&lt;/li&gt;
  &lt;li&gt;stop the virtual display&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-4263810995486916552?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total></entry><entry><title type="text">Python - Headless Selenium WebDriver Tests using PyVirtualDisplay</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2011/06/python-headless-selenium-webdriver.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2012-01-02T07:25:19-08:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-1095251415954187012</id><content type="html">&lt;p&gt;
I need to integrate my functional UI tests (Selenium/WebDriver) with my Jenkins CI system.  The problem is that my Jenkins CI server has no display, so I must run my GUI tests in a headless X-server.
&lt;/p&gt;

&lt;p&gt;
A colleague pointed me to &lt;a href="http://pypi.python.org/pypi/PyVirtualDisplay"&gt;PyVirtualDisplay&lt;/a&gt;, a Python wrapper for &lt;a href="http://en.wikipedia.org/wiki/Xvfb"&gt;Xvfb&lt;/a&gt; and Xephyr.
&lt;/p&gt;

&lt;p&gt;
This makes running headless Python Selenium/WebDriver tests very easy.
&lt;/p&gt;

&lt;p&gt;
Here is some Python code showing WebDriver with a virtual display provided by Xvfb:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;    
#!/usr/bin/env python

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=0, size=(800, 600))
display.start()

# now Firefox will run in a virtual display. 
# you will not see the browser.
browser = webdriver.Firefox()
browser.get('http://www.google.com')
print browser.title
browser.quit()

display.stop()
&lt;/pre&gt;

&lt;p&gt;
install PyVirtualDisplay on Ubuntu/Debian:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
$ sudo apt-get install xvfb python-pip
$ sudo pip install pyvirtualdisplay
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-1095251415954187012?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">16</thr:total></entry><entry><title type="text">Python - Selenium WebDriver - Capture Screenshot</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2011/06/python-selenium-webdriver-capture.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2011-07-12T08:30:48-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-354942069393498892</id><content type="html">&lt;p&gt;
Example of capturing a screenshot from Selenium WebDriver in Python:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
#!/usr/bin/env python
from selenium import webdriver

browser = webdriver.Firefox()
browser.get('http://www.ubuntu.com/')
browser.save_screenshot('screenie.png')
browser.quit()
&lt;/pre&gt;

&lt;p&gt;
&lt;a href="http://code.google.com/p/selenium/"&gt;selenium/webdriver&lt;/a&gt; bindings for Python:  &lt;a href="http://pypi.python.org/pypi/selenium"&gt;http://pypi.python.org/pypi/selenium&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-354942069393498892?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><title type="text">Performance and Scalability Testing with Python and Multi-Mechanize</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2011/03/performance-and-scalability-testing.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2011-03-31T06:28:03-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-1063019783382648412</id><content type="html">&lt;p&gt;
I put together a slide-deck to help introduce &lt;a href="http://multimechanize.com"&gt;Multi-Mechanize&lt;/a&gt;.  I wanted something a little friendlier and easier to digest than "go read the project wiki".  (It is also the basis of a presentation/talk I might give someday).
&lt;/p&gt;

&lt;p&gt;
Hopefully, this will help people better understand what the project is all about. 
&lt;/p&gt;

&lt;div style="width:425px" id="__ss_7454050"&gt; &lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/coreygoldberg/performance-and-scalability-testing-with-python-and-multimechanize" title="Performance and Scalability Testing with Python and Multi-Mechanize"&gt;Performance and Scalability Testing with Python and Multi-Mechanize&lt;/a&gt;&lt;/strong&gt; &lt;object id="__sse7454050" width="425" height="355"&gt; &lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=perfscalepythonmulti-mechanize-110330174840-phpapp02&amp;stripped_title=performance-and-scalability-testing-with-python-and-multimechanize&amp;userName=coreygoldberg" /&gt; &lt;param name="allowFullScreen" value="true"/&gt; &lt;param name="allowScriptAccess" value="always"/&gt; &lt;embed name="__sse7454050" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=perfscalepythonmulti-mechanize-110330174840-phpapp02&amp;stripped_title=performance-and-scalability-testing-with-python-and-multimechanize&amp;userName=coreygoldberg" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt; &lt;/object&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-1063019783382648412?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><title type="text">linux-metrics - Python Package - System Metrics/Stats for Linux</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2011/03/linux-metrics-python-package-system.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2011-03-22T06:20:24-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-8128781021584333480</id><content type="html">&lt;p&gt;
I just released my Python package: 'linux-metrics'
&lt;/p&gt;

&lt;p&gt;
&lt;a href="http://linux-metrics.googlecode.com"&gt;linux-metrics&lt;/a&gt; contains Python modules for getting OS metrics on systems running the Linux (2.6) kernel.  It is a pure python library with no external dependencies.
&lt;/p&gt;

&lt;p&gt;
This project is under development, and nowhere near comprehensive. Only basic stats for major subsystems are provided (Processor/CPU, Disk, Memory, Network). Hopefully, more are coming.
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project Home: &lt;a href="http://linux-metrics.googlecode.com"&gt;http://linux-metrics.googlecode.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;PyPI Entry: &lt;a href="http://pypi.python.org/pypi/linux-metrics"&gt;http://pypi.python.org/pypi/linux-metrics&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-8128781021584333480?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><title type="text">Going to PyCon 2011!</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2011/01/going-to-pycon-2011.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2011-01-25T14:04:40-08:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-3975465223553773895</id><content type="html">&lt;p&gt;

This year I am attending my first &lt;b&gt;PyCon&lt;/b&gt; (the annual Python community conference).

&lt;/p&gt;




&lt;p&gt;

I will be in Atlanta: &lt;b&gt;March 10-13&lt;/b&gt;.

&lt;/p&gt;



&lt;p&gt;

If anyone is interested in meeting up or collaborating while I'm there, get in touch:

&lt;/p&gt;



&lt;ul&gt;

    &lt;li&gt;Twitter: &lt;a href="http://www.twitter.com/cgoldberg"&gt;@cgoldberg&lt;/a&gt;&lt;/li&gt;

    &lt;li&gt;Homepage/Info: &lt;a href="http://goldb.org"&gt;goldb.org&lt;/a&gt;&lt;/li&gt;

&lt;/ul&gt;


&lt;a href="http://us.pycon.org"&gt;

    &lt;img alt="PyCon 2011, Atlanta, March 9-17" src="http://us.pycon.org/2011/site_media/static/img/badges/pycon-badge-400x120.png" /&gt;

&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-3975465223553773895?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></entry><entry><title type="text">Python - Search a Local or Remote Splunk Server</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2010/12/python-search-local-or-remote-splunk.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2010-12-01T06:40:24-08:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-2880954091958444162</id><content type="html">&lt;p&gt;
Some basic instructions for searching &lt;a href="http://www.splunk.com/"&gt;Splunk&lt;/a&gt; from &lt;a href="http://python.org/"&gt;Python&lt;/a&gt;...
&lt;/p&gt;    

&lt;p&gt;
First, you must install Splunk on the machine you will run the Python script from.  Splunk installs its own Python interpreter that you can use to run your code.  I am using Splunk 4.14, which includes Python 2.6.
&lt;/p&gt;

&lt;p&gt;
(It looks like you can set some environment variables and install a few Python dependencies along with the Python SDK and get this going "outside" of Splunk.  But the easiest option is just to run on their interpreter).
&lt;/p&gt;

&lt;p&gt;
To run your own Python scripts on Splunk's interpreter:&lt;br /&gt;
- save script into Splunk's "bin" directory&lt;br /&gt; 
(usually "/opt/splunk/bin" or "C:\Program Files\Splunk\bin")&lt;br /&gt;
- go to the "bin" directory and run:&lt;br /&gt; 
splunk cmd python your_script.py
&lt;/p&gt;

&lt;p&gt;
So...&lt;br /&gt;
What goes in your Python code?
&lt;/p&gt;

&lt;p&gt;
First, import the modules you will need:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
import time
import splunk.auth
import splunk.search
&lt;/pre&gt;

&lt;p&gt;
Next, authenticate and get a session key.  
&lt;/p&gt;

&lt;p&gt;
For the local splunk host:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
key = splunk.auth.getSessionKey('user', 'password')
&lt;/pre&gt;

&lt;p&gt;
If you are going to search a remote splunk host, you must authenticate against it by adding the "hostPath" parameter:  
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
key = splunk.auth.getSessionKey('user', 'password', hostPath='https://mysplunk:8089')
&lt;/pre&gt;

&lt;p&gt;
Tips:&lt;br /&gt;
- use https, even if you are not using ssl in your splunk web interface&lt;br /&gt;
- 'admin' user doesn't seem to work.  user a normal user/password.
&lt;/p&gt;

&lt;p&gt;
Next, submit a search job.
&lt;/p&gt;

&lt;p&gt;
For a local search:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
job = splunk.search.dispatch('search index="os" *', earliest_time='-15m')
&lt;/pre&gt;

&lt;p&gt;
For a remote search, use the "hostPath" parameter again:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
job = splunk.search.dispatch('search index="os" *', earliest_time='-15m', hostPath='https://mysplunk:8089')
&lt;/pre&gt;

&lt;p&gt;
print the job details:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
print job
&lt;/pre&gt;

&lt;p&gt;
wait for the results:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
while not job.isDone:
    time.sleep(.25)    
&lt;/pre&gt;

&lt;p&gt;
print results
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
for result in job.results:
    print result
&lt;/pre&gt;        


&lt;hr /&gt;

&lt;p&gt;
Altogether in a Python script:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
#!/usr/bin/env python
# Corey Goldberg - 2010
# 
#  search a remote splunk server
#
#  instructions:
#   - save script into splunk's "bin" directory
#     (usually "/opt/splunk/bin" or "C:\Program Files\Splunk\bin")
#   - go to the "bin" directory and run: 
#     $ splunk cmd python my_script.py
#



import time
import splunk.auth
import splunk.search



SPLUNK_SERVER = '192.168.12.173'
USER_NAME = 'foo'
PASSWORD = 'secret'
SEARCH_STRING = 'search index="os"'
EARLIEST_TIME = '-15m'



def main():
    # authenticate
    key = splunk.auth.getSessionKey(USER_NAME, PASSWORD, hostPath='https://%s:8089' % SPLUNK_SERVER)
    print 'auth key:\n%s' % key
    
    # submit a search job
    job = splunk.search.dispatch(SEARCH_STRING, earliest_time=EARLIEST_TIME, hostPath='https://%s:8089' % SPLUNK_SERVER)
    print 'job details:\n%s' % job

    # wait for results
    while not job.isDone:
        time.sleep(.25)
    
    print 'results:'    
    for result in job.results:
        print result
          
          

if __name__== '__main__':
    main()
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-2880954091958444162?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry><title type="text">Python - Shorten a URL Using Google's Shortening Service (goo.gl)</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2010/10/python-shorten-url-using-googles.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2010-10-08T09:02:44-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-3361028988733434778</id><content type="html">&lt;p&gt;
Using Python to shorten a URL with Google's shortening service (goo.gl):
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt; 
#!/usr/bin/python 
#  Corey Goldberg - 2010

import json
import urllib
import urllib2


def shorten(url):
    gurl = 'http://goo.gl/api/url?url=%s' % urllib.quote(url)
    req = urllib2.Request(gurl, data='')
    req.add_header('User-Agent', 'toolbar')
    results = json.load(urllib2.urlopen(req))
    return results['short_url']


if __name__ == '__main__':
    print shorten('http://www.goldb.org/')
    print shorten('www.yahoo.com')

&lt;/pre&gt;

&lt;p&gt;
You give it a URL to shorten: shorten('http://www.goldb.org/long_url')
&lt;/p&gt;

&lt;p&gt;
... and it returns a shortened URL for you: 'http://goo.gl/jh4W'
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-3361028988733434778?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry><title type="text">Python - Linux: Parse Network Stats From ifconfig</title><link rel="alternate" type="text/html" href="http://coreygoldberg.blogspot.com/2010/09/python-linux-parse-network-stats-from.html" /><category term="python" /><author><name>Corey Goldberg</name><email>noreply@blogger.com</email><uri>https://profiles.google.com/114546378907380458640</uri></author><updated>2010-09-24T15:04:16-07:00</updated><id>tag:blogger.com,1999:blog-5236867476487043111.post-5805864631356358652</id><content type="html">&lt;p&gt;
I needed to get some Linux networking stats in my Python program today.  Specifically, I needed 'bytes sent' and 'bytes received' counts since last reboot from the local machine.
&lt;/p&gt;

&lt;p&gt;
&lt;a href="http://en.wikipedia.org/wiki/Ifconfig"&gt;ifconfig&lt;/a&gt; is a network configuration utility for Linux that you run from the command line:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
corey@studio17:~$ ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:22:19:e5:07:31  
          inet addr:10.0.0.5  Bcast:10.0.0.255  Mask:255.255.255.0
          inet6 addr: fe80::222:19ff:fee5:731/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3353822 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3052408 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:3476310326 (3.4 GB)  TX bytes:256706611 (256.7 MB)
          Interrupt:17 
&lt;/pre&gt;

&lt;p&gt;
The following function parses output from ifconfig to get the network stats I was after:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
import re
import subprocess

def get_network_bytes(interface):
    output = subprocess.Popen(['ifconfig', interface], stdout=subprocess.PIPE).communicate()[0]
    rx_bytes = re.findall('RX bytes:([0-9]*) ', output)[0]
    tx_bytes = re.findall('TX bytes:([0-9]*) ', output)[0]
    return (rx_bytes, tx_bytes)
&lt;/pre&gt;    
  
&lt;p&gt;  
Example usage:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
import re
import subprocess

def main():
    rx_bytes, tx_bytes = get_network_bytes('eth0')
    print '%s bytes received' % rx_bytes
    print '%s bytes sent' % tx_bytes
      
def get_network_bytes(interface):
    output = subprocess.Popen(['ifconfig', interface], stdout=subprocess.PIPE).communicate()[0]
    rx_bytes = re.findall('RX bytes:([0-9]*) ', output)[0]
    tx_bytes = re.findall('TX bytes:([0-9]*) ', output)[0]
    return (rx_bytes, tx_bytes)

if __name__ == '__main__':
    main()
&lt;/pre&gt;

&lt;p&gt;
&lt;b&gt;Update:&lt;/b&gt;  someone left an anonymous comment and mentioned you can just read from proc/net/dev rather than using ifconfig.  I modified his code sample and came up with this:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
def get_network_bytes(interface):
    for line in open('/proc/net/dev', 'r'):
        if interface in line:
            data = line.split('%s:' % interface)[1].split()
            rx_bytes, tx_bytes = (data[0], data[8])
            return (rx_bytes, tx_bytes)
&lt;/pre&gt;

&lt;p&gt;
Example Usage:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
def main():
    rx_bytes, tx_bytes = get_network_bytes('eth0')
    print '%s bytes received' % rx_bytes
    print '%s bytes sent' % tx_bytes
      
def get_network_bytes(interface):
    for line in open('/proc/net/dev', 'r'):
        if interface in line:
            data = line.split('%s:' % interface)[1].split()
            rx_bytes, tx_bytes = (data[0], data[8])
            return (rx_bytes, tx_bytes)

if __name__ == '__main__':
    main()
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-5805864631356358652?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></entry></feed>

