October 15, 2010 1

ShipItSquirrel on Twitter

By in python, twitter

We’ve been busy working towards a deadline over at Collective Labs, and around the office, Ship It Squirrel has become our unofficial mascot. It’s not uncommon to hear someone mutter “Ship It” as they’re dealing with some nasty issue, only to hear the rest of the office chime in “Ship It” in support.

Because of that, we thought it would be funny to have a Twitter bot ShipItSquirrel that would reply back to keywords in your tweets with “Ship It!”. Well, the wait is over. You can now find ShipItSquirrel on Twitter. Follow him and he’ll follow you back. Then, whenever certain ship-related terms are tweeted by you, ShipItSquirrel will snap back “Ship It!” in support.

Yeah, okay, so it was also an excuse to play with Tweepy, a Python Twitter library and see how the new OAuth authentication worked. If you’re curious, you can check out the skeleton ShipItSquirrel app on GitHub. Oh, but you’ll need to get your own damn access tokens for Twitter if you intend to run the code on your Twitter account.

Tags: , , , ,

October 9, 2010 0

Logging file and line numbers in Python

By in python

If you’re like me, you abuse ‘print’ and┬áhave lots of little warning, or generic exceptions printing various levels of messages to the console of your Python applications. Sometimes the messages are informational, and other times they represent critical errors. You’d like to be able to categorize these levels of printed messages. Sometimes you also have messages printed that come from another software library. In those cases, because the message is dynamically generated, you aren’t sure where in the code, exactly, the error message occurred. In those cases you’d like to have the file and line numbers where the message was printed.

Well, you’re in luck. There’s been a handy little library in Python for a number of years called logging and it does all of this. You can categorize the various levels of messages as: debug, info, warning, error, and ´╗┐critical. Alternatively, you can then set the level of messages that you want to be logged, or printed, so that you would only see messages for level of ‘warning’ or above. Additionally, the messages you log/print can automatically have the time prepended, as well as the file and line number. Here’s a short example.

#!/usr/bin/env python
import logging

    format='%(asctime)s %(levelname)-8s %(filename)s:%(lineno)-4d: %(message)s',
    datefmt='%m-%d %H:%M',
logging.debug('A debug message')
logging.info('Some information')
logging.warning('A shot across the bow')

# Should print the following (with current date/time of course)
#10-19 19:57 INFO     test.py:9   : Some information
#10-19 19:57 WARNING  test.py:10  : A shot across the bow

To give you an idea of what logging is doing for you, you could write your own logging function that did roughly (and I mean roughly), the same thing. Here’s a logging function that prints the file, line, and a prefix (which could be info, warning, error, etc.). There is no concept of filtering the level of messages with this example, however.

#!/usr/bin/env python
import inspect

def logfileline(msg, prefix=''):
    ''' Utility function to log a message and automatically print the file 
        and line number the log function was called from. '''
    frame, module = None, None
    if prefix != '' and not prefix.endswith(' '):
        prefix = prefix + ' '

        frame = inspect.stack()[1][0]
        module = inspect.getmodule(frame)
        print '{0}{1}::{2}:\n\t{3}'.format(prefix, frame.f_lineno, 
                                        frame.f_code.co_filename, msg)
        if frame is not None:
            del frame
        if module is not None:
            del module

So there you have it. Two little examples of logging/printing messages at different levels with the option for file and line numbers.

Tags: ,