Benjamin W. Smith

Benjamin W. Smith

Benjamin W. Smith  //  Sysadmin by trade, Pythonista by passion. Dad to two boys and a girl. Guitarist. I like my coffee black, just like my metal.

Aug 29 / 8:36am

from python.podcast import awesome

If you don’t know, Chris Miller, Dave Stanek and Mike Crute started a podcast some months ago, aptly named from python import podcast. If you do know, great! Keep listening and supporting!

What you might not know is that I crashed the party to babble with the fellas about all things python. Hope they like me, cause I’m sticking around!

In all seriousness, on the most recent episode we talk about PyOhio, the conference process, the various awesome ideas and projects that spawned off of it and lots of other stuff. Definitely worth noting that Mike C. sits down to chat with Greg Malcom about the Python Koans project, which you need to check out.

So why are you still reading this? Why are you not listening to from python import podcast while playing with Python Koans??

Nothing left to see here..

Filed under  //  devops   from python import podcast   podcast   pyohio   python   python koans  
Aug 11 / 9:01pm

PyOhio 2010 Presentations

Looks like the presentations from PyOhio 2010 are published over at blip.tv.  That's awesome, now I can catch up on the ones I missed.

Below is my presentation, chopped and hacked to make me look like less of an idiot ;)

Also, you can find my slides here: Splunking With Python and the source code for the talk with examples here: pyohio_talk @ bitbucket

Overall I had a great experience at PyOhio and can't wait for next year!

Filed under  //  api   columbus   fabric   ohio   pyohio   python   splunk  
Aug 5 / 6:50pm

Obligatory PyOhio 2010 follow-up.

So, yeah, PyOhio was all kinds of awesome. So awesome, in fact, that it was tool damn cool for 2010. What you say? I mean to say that according to the handout, we were actually in 2011. You had to be there to believe it. Sucka.

This is only the second PyOhio I have been able to attend, although I’ve managed to be involved in the most minuscule way since it’s inception. First of all, I love the venue, The Ohio Union. I found it to be accessible, convenient, and appropriate for our needs. The Round Room seating situation could be improved, but I think that’s already on the agenda for next year.

The first talk I caught on Saturday was one that really piqued my interest. Scott McCarty talked about log analysis and demod a tool named petit, a pretty awesome log analysis tool written in Python. It basically gives some really practical ways to help your logs get you the info you need in less time, with less pain.

To entertain her, I sat in on Sarah’s talk, which is a really nice introduction to Python for .Net developers. Pretty sure that’s at least the second time I’ve seen that talk ;).

The evening after was great. Columbus has a decent night life! The wife and I strolled around the Arena District and the Short North on High St. We had dinner at The Black Olive and then The Burgundy Room for a drink and Tapas.

Also hung out with a crowd of folks from the conference for a few drinks at the Surly Girl.

Conclusion? Both of the districts are very cool, I’d go back any time for a night on the town.

On Sunday I presented my talk. Initially I had planned to speak on how to use the Splunk Python API/SDK. Sadly, that didn’t work out so well. I started out writing my own interface to the RESTful API that they provide/publish. Then, I discovered that Spunk had done all that already. The problem is that the code doesn’t feel Pythonic to me, and the documentation is just aweful (see this).

While I’m on the subject, I’ll take a moment to rant. One of my peeves in software design is that programmers don’t make clean interfaces. There’s nothing overly hard or complicated about talking to a RESTful service, but they have abstracted it in such a way that it takes digging to figure out WTF is going on under the hood. I would have tried to write the code with an interface that was abstracted, but didn’t leave you wondering what kind of magic Unimacorn dust was thrown in to make it all work. Am I wrong to think that way?? No.

Here is what I have to do for a basic search with Splunk

from splunk import auth, search

if __name__ == '__main__':
    # First of all; MOTHER FUCKING CAMEL CASE
    # Lastly, you call getSessionKey BUT it caches
    # the key, so you don't need to call it again.
    # Therefore, this method name feels like a lie.
    auth.getSessionKey('username', 'password')

    # Because the kw argument list is fucking huge.
    args = {'search': 'search sourcetype="syslog"',
            'latest_time': 'rt',
            'earliest_time': 'rt'}

    # Monolithic method to "dispatch" things.
    # I am not a fucking trucker, or police officer.
    search_job = search.dispatch(**args)

    # Pandas are now crying bloody tears
    if search_job.isDone:
        for index, event in enumerate(search_job.events):
            print event

Were I the developer responsible for the Splunk interface, I would have designed it something like this:

from splunk import Auth, Search

if __name__ == '__main__':

    auth = Auth()
    auth.authenticate('username', 'password')
    restful_search = Search()
    search_job = restful_search.basic_search(realtime=True,
                     sourcetype='syslog')

    # I like generators..
    while True:
        try:
            print search_job.events.raw.next()
        except StopIteration:
            break

Anyway, I’m over that now, moving on.

So, my talk went pretty OK. Like I started to say earlier, the Splunk part didn’t pan out. I still touched on the basics of the Splunk API and what I didn’t like. Most of the slides I wrote, however, were before I started seeing things I didn’t like about the code, so people were likely confused.

I also talked briefly about a suite of tools we use internally at AGI for managing ~1k servers. It’s called cf and is loosely based on cfengine, but built in Python with a bias toward flexibility and decoupling from the build process. Parts of the system are open source, but the goal is to open it completely and release a stable version.

In contrast, I also spoke about Fabric to basically show how simple application deployment can be.

After my talk, I stuck around for calvinhp’s talk about Supervisord, one of my favorite Pythonic unix tools. One I’ve even contributed back to!

You can find my slides here: Splunking With Python and my code here: pyohio_talk on bitbucket

So in a nutshell, PyOhio is awesome, and you should go every year.

Filed under  //  api   fabric   linux   petit   pyohio   python   splunk  
Jul 5 / 6:44pm

Android Scripting Environment.

Holy crap, why didn't I see this before?!  

I just recently started the task of writing an android application for shits and giggles.  Being that I'm not as versed in Java, it's been a slow process.  Now that I can use ASE, I should be able to prototype the app completely in the time it has taken me to write as much as I have in Java.

Any of my developer friends have experience with it?  Are there things to look out for?  Is it a waste of time?

ASE FTMFW SON!

Filed under  //  ASE   android   java   python  
Apr 7 / 8:31pm

PyOhio 2010 Call for Proposals

PyOhio 2010 Call For Proposals

Better late than never, right??

PyOhio 2010, the third annual Python programming conference for Ohio and the surrounding region, will take place Saturday-Sunday, July 31-Aug 1, 2010 at the Ohio State University in Columbus, Ohio. A variety of activities are planned, including tutorials, scheduled talks, Lightning Talks, Open Spaces and Sprints.

PyOhio invites all interested people to submit proposals for scheduled talks, tutorials, and panels. All topics of interest to Python programmers will be considered. Standard presentation slots will be 40 minutes plus a 10 minute question-and-answer period.

PyOhio is especially interested in hosting a Beginner’s Track for those new to Python or new to programming in general. If your proposal would be suitable for inclusion in a Beginner’s Track, please indicate so. Organizers will work with speakers and instructors in the Beginner’s Track to help them coordinate their talks/tutorials into a smooth, coherent learning curve for new Python users.

To ensure that you provide all necessary information, please use the submission template provided below. If organizing a panel, please confirm all panelists’ intention to participate before submitting your proposal.

PyOhio may record presentations for later release over the web. Presenters will need to sign a release of recording rights to PyOhio; see http://wiki.python.org/moin/PyOhio/RecordingRelease

All proposals should be emailed to cfp@pyohio.org for review. Please submit proposals by May 10, 2010. Accepted speakers will be notified by May 24.

You can read more about the conference at http://pyohio.org. If you have questions about proposals, please email cfp@pyohio.org. You can also contact the PyOhio organizers at pyohio-organizers@python.org.

Filed under  //  awesome   pyohio   python  
Jan 6 / 1:06am

My opinion on the explicit/implicit self argument.

Don’t remember how, but I ran across the “explicit vs implicit self” argument again while lurking on the internet. I realize this is an old argument, but it sparked up my thought machine and I wanted to share my opinion for the hell of it, dead horse be damned.

To me it’s like a noise your car makes that you never notice because it’s made it for so long. However, when other people ride in your car with you, they point it out. You quickly brush it off with “oh, it’s always done that, doesn’t really bother me.”. Like a crotchety old man, I like things the way they are and aint a damn thing you’re gonna do to change my mind!

Every single language has one(or more!) of those “car noises”. Suck it up and be practical, hippies, and get off my lawn!

Ok, I’m done :)

Filed under  //  explicit   implicit   python   self  
Dec 28 / 8:31am

New Year's Python Meme

From Tarek via pyDanny

1. What’s the coolest Python application, framework or library you have discovered in 2009?

I did a lot of playing with asyncore and am currently having bit of fun with ply. As far as the coolest goes, I’d have to give a nod to Dingus from Gary Bernhardt. I really like the record-then-assert model for mocking, and the name just takes the cake.

2. What new programming technique did you learn in 2009?

Well, this year I completely changed my development methods. More accurately I actually started practicing some sort of development method where I previously had none. Prior to this year, I just kinda vomited code and didn’t pay much mind to quality. Though I always tried to make my code presentable and maintainable, that was typically an afterthought.

This year I started writing unit tests, then I started writing them first. Before I knew it I had read Clean Code and developed a mental work flow that really helped me focus.

The result (I think) has been higher quality code, and a better understanding of what I’m doing! Also, I’m pretty sure I cranked out more code this year than I ever had before even with less time to do so! Naysayers of TDD/BDD be damned, I am proof dammit! To be fair, this might not work for everyone :).

3. What’s the name of the open source project you contributed the most in 2009? What did you do?

Likely my own projects, specifically stompy and NginxMgr. I wrote them both from the ground up..

4. What was the Python blog or website you read the most in 2009?

Pythonistas on Twitter and Planet Python

5. What are the top three things you want to learn in 2010?

  1. Python Concurrency (and multiprocessing)
  2. More meta programming tricks
  3. A functional programming language (erlang or MAYBE Haskell, though it scared me a tad the last time I tried)
Filed under  //  bdd   holidays   meme   python   stomp   tdd  
Oct 21 / 6:32am

Nginxmgr - Nginx upstream pool manager.

What?

Nginxmgr is an application for managing pools of upstream servers in an Nginx deployment. It allows you to dynamically allocate, deallocate and monitor servers in an upstream pool via health checks and an XML-RPC interface.

Why?

I wrote this software because I use Nginx as a web application load balancer and have often found the need to monitor the upstream servers and have it react like a real load balancer would. I was also looking for a way to be able to manage the upstream servers programmatically with Python and monitor the health of the upstream pools by being aware of the number of servers available.

Use Case

Typical use case for Nginxmgr is in a large environment, with a large number of upstream pools and servers. Of course, that’s not a requirement. You could also use it on a pool of just a few servers.

Checks/Handlers

Out of the box, Nginxmgr comes with one check named url_ping. It’s job is to check the status of an upstream member every ‘n’ seconds and if it fails, call the appropriate handler. The handler will then remove the server from the upstream pool and reload Nginx. The url_ping check is also configurable, allowing checks on a port other than 80 and also status codes other than 200 (in case you want to get a 404 or something back).

Checks and handlers are Python modules and functions that allow for flexibility and ease of development were new checks/handlers needed.

Interoperability With Nginx

Currently Nginxmgr runs along side Nginx as a separate daemon, however it will not attempt to start if Nginx is not running. It also does a check in the main loop before the health checks are executed to determine if Nginx was shut down or died since the last check. When that check happensm, if Nginx isn’t running, Nginxmgr will shut itself down.

Installing Nginxmgr

First, you need to get the package. You can find links to the code below in the section titled “Get The Code”. Once you have the source tarball, you should extract it, then cd into the newly created nginxmgr directory. Once there you will then run: python setup.py install. This should install all the library code and the command line script. If you’re cloning the code (hg clone), all you will need to do is run the setup script as above in the root directory of your newly acquired repository.

Configuring Nginxmgr

There are two different configuration files for Nginxmgr. One is for the core code, and one is for the url_ping check command. You should only need to mess with the core config. Below are example configs with comments explaining what is going on:

/etc/nginxmgr/nginxmgr.cfg:

[core]
# Should I run in  the background?
daemon           = True
# Should I enable debug level logging?
debug            = True
# Path to handler scripts
handler_path     = '/etc/nginxmgr/handlers/'
# Path to check scripts
checks_path      = '/etc/nginxmgr/checks/'
# Health check config definitions
healthcheck_defs = '/etc/nginxmgr/health_check_defs.cfg'
# How do you want the log to look?
log_format       = '%(asctime)s %(levelname)s %(threadName)s %(filename)s LINE %(lineno)s: %(message)s'
# Where should I log to?
log_file         = '/var/log/nginxmgr.log'
# Where should I deposit my pid?
pid_file         = '/var/run/nginxmgr.pid'
# Location of nginx base config
ngx_base_config  = '/etc/nginx/nginx.conf'
# Location of nginx binary
ngx_bin          = '/usr/sbin/nginx'
# Location of nginx upstreams config
ngx_config       = '/etc/nginx/conf.d/upstreams.conf'
# Location of nginx pid file
ngx_pid_file     = '/var/run/nginx.pid'
# Interface for XML-RPC to listen on
xml_rpc_ip       = "0.0.0.0"
# Port for XML-RPC to bind to
xml_rpc_port     = 9000

    [healthcheck]
    # Enable health checks?
    enabled = True

        [[checks]]
        # Inidividual checks

            [[[url_ping_test_upstreams]]]
            # Type maps to a python module in etc/checks
            type     = url_ping
            # Upstream maps to an upstream pool in nginx upstream.conf
            upstream = test-upstreams 
            # Handler maps to a python module:function in etc/handlers
            handler  = url_ping_handler:badupstream
                # Custom stuff to define for custom checks (defined by check module)
                [[[[extras]]]]
                # port — If port is defined, any existing port in the upstream
                # will be stripped and replaced.
                # port     = 2000
                url      = "http://%s/"
                status   = 200
            [[[url_ping_test_upstreams-two]]]
            # Type maps to a python module in etc/checks
            type     = url_ping
            # Upstream maps to an upstream pool in nginx upstream.conf
            upstream = test-upstreams-two
            # Handler maps to a python module:function in etc/handlers
            handler  = url_ping_handler:badupstream
                # Custom stuff to define for custom checks (defined by check module)
                [[[[extras]]]]
                # port — If port is defined, any existing port in the upstream
                # will be stripped and replaced.
                # port     = 2000
                url      = "http://%s/setup"
                status   = 404

/etc/nginxmgr/health_check_defs.cfg:

[url_ping]
# Check a url ever little while to make sure it's up
# Corresponds to ./checks/check_name.py:function_name
check=url_ping:ping
# Timeout (in seconds)
schedule=2

Running, Stopping and Reloading Nginxmgr

To start Nginxmgr, you would run this:

nginxmgr -c /etc/nginxmgr/nginxmgr/cfg

It will then fork off into the background and write a pid file to wherever you specify in the config (default is /var/run/nginxmgr.pid).

To shut it down properly, get the pid from the pid file and send it a kill signal(SIGTERM, SIGQUIT or SIGABRT) . If not running in daemon mode, just hit CTRL-C.

To reload the config and the health checks send the pid a SIGHUP.

You could also use Nginxmgr in an init script with out difficulty.

XML-RPC Interface

The XML-RPC interface is ideal for managing upstream pools and nodes on the fly, without having to mess with Nginx itself. It is also nice because it provides a language agnostic way to automate operations on upstream pools and provide a way to monitor the health of the pools.

XML-RPC Exposed Methods

Methods exposed to the XML-RPC interface are:

  • get_pools() — lists all of the pools available
  • get_members('pool_name') — get all members available in specified pool
  • disable_member('pool_name', 'IPADDR:PORT') — Temporarily disable member in pool
  • remove_member('pool_name', 'IPADDR:PORT') — Remove member from pool
  • enable_member('pool_name', 'IPADDR:PORT') — Enable disabled member in pool
  • add_member('pool_name', 'IPADDR:PORT') — Add new member to pool

Things to Note

I made some assumptions when developing this and as such it should be noted that Nginxmgr has only been tested on Linux(Centos and Ubuntu) with Python > 2.5. Nginxmgr makes some calls to utilities common to these systems such as ‘ps’, ‘kill’ and ‘pgrep’. The paths are currently hard coded, but that could easily be changed and/or stuffed in the configuration file.

I also make some assumptions about your Nginx setup. Mainly I assume that you separate your Nginx upstreams in it’s own file. That’s how I prefer to manage it, but It’s not required.

I have a major rewrite planned as an exercise in Test Driven Development as well as taking advantage of practices outlined in Clean Code by Robert (Uncle Bob) Martin.

In this rewrite I will also be experimenting with the Python multiprocessing module rather than threads. I’ve also considered REST instead of XML-RPC.

Documentation is non-existent. Sorry, that is one of the things I would like to work on :)

Purpose of This Blog Post

The purpose of this post is to introduce the software see if there is even any interest for such a thing in the community. My hope is that someone else will have a use for it and wish to improve upon it.

Get The Code

I use mercurial for DVCS, so you can find the code on bitbucket here: https://bitbucket.org/benjaminws/nginxmgr/

From there you can either clone the repository or download a tarball of the source.

If for whatever reason there is a problem getting the code from bitbucket, I also have a copy of the code here: http://nginxmgr.code.just-another.net/

From there you can clone the repository.

Hope this software helps someone. Thanks for reading!

Filed under  //  nginx   python  
Oct 1 / 9:33pm

JabberCat - Vaporware, materialized!

Jabbercat_words

UPDATE: Looks like bitbucket is having some issues, see my local repository if you’d like to browse or clone the code.

JabberCat is a jabber bot that can be fed messages via HTTP to enable scripts and other processes the ability to communicate via Jabber. Communicating via JabberCat is meant to be language agnostic. If your favorite language has an HTTP library(as most do), you won’t need to understand jabber to get your messages to a jabber chat or user.

This project started out as nothing more than vaporware, incubating in the brain of a fellow Pythonista named Mike Pirnat. It materialized shortly after Mike presented a talk at ClePy about ideas he had that never came to life.

JabberCat is ideal for plugging into your continuous integration environment to broadcast statistics(code coverage, etc), or even statistics/events/alerts within your network.

Currently there are two tools for passing messages to JabberCat. A web interface, and a command line tool. The web interface allows you to post messages from your browser. The command line client is ideal for piping messages to, like a few lines of a log file, or source code.

JabberCat has SSL support, but it seems to be a bit buggy at the moment due to it dropping connections unexpectedly. There are plans in the works to implement some new features and spruce up the web interface.

Currently the software is very green (read: alpha), and is not recommended for any kind of production use. You should help this project get some traction, really. Why not hop over to Bitbucket and clone/fork the main repository?

JabberCat on Bitbucket: http://bitbucket.org/benjaminws/jabbercat/

JabberCat is written in Python and is comprised of the following components:

If you think this software could be useful to you, and would like to see it evolve, please don’t hesitate to submit patches or enhancement ideas. You could also fork the repository or report issues on the issue tracker

I have submitted a talk to CodeMash to speak about JabberCat, hopefully it will be accepted! I plan on having a polished stable release by then :)

Thanks for reading!

Note: Image credit goes to Dan Buch

Filed under  //  hg   jabber   jabbercat   mercurial   python   xmpp  
Sep 19 / 8:29pm

Python STOMP Updates

Due to a flurry of activity(like, you know, a couple people) on bitbucket and twitter, it became apparent to me that people were actually using the library I created for working with message brokers that utilize the STOMP protocol. This is exciting news for me! ;-)

In response I decided it would be a good idea to, you know, maintain the software and polish it up a bit. There were three forks of the python-stomp repository on
bitbucket, so I waded through diffs to see what ideas/suggestions/improvements others had. Everything I saw looked great, so I pulled in and merged all the changes in to the main repository. Thankfully this was a trivial task because mercurial is FREAKING AWESOME. The next step was to polish it all up. So, I went to PEP8ifying where needed(thankfully others had done a great deal of that work for me), and unit testing new functionality introduced by the other developers.

There are many improvements/changes in the latest iteration of this library, so I’d like to outline some of them here.

  • Renamed to stompy
  • Fully documented with Sphinx
  • Simplified client interface with automatic transaction support (abstracted stompy.stomp as stompy.simple)
  • Intermediate message queue layer
  • Simplified authentication
  • More resilient and informative error handling
  • Polling/Non-blocking support
  • Now able to subscribe to multiple destinations at a time
  • Tested and known to work well with ActiveMQ and RabbitMQ
  • Now available on pypi!

This is just a high level overview of the major changes to stompy. For more detailed information, have a look at the source and documentation.

I’d like to thank a few people that have submitted patches and new functionality.

In closing, I’d like to point out that this “project” was an exercise in TDD(Test Driven Development) for me. I wrote the tests first, then the actual code to make the tests pass. This was also the first time I had used the mocking library Dingus. This has been a pleasurable and enlightening development experience for me!

Thanks for reading!

Filed under  //  activemq   bitbucket   etc   hg   mercurial   python   rabbitmq   stomp