PyOhio 2009: Call for Proposals

09.04.2009 17:32

posted by: Benjamin Smith

Posted Under: , , ,

PyOhio 2009: Call for Proposals

PyOhio 2009, the second annual Python programming mini-conference for Ohio and surrounding areas, will take place Saturday-Sunday, July 25-26, 2009 at the Ohio State University in Columbus, Ohio. A variety of activities are planned, including tutorials, scheduled talks, Lightning Talks, and Open Spaces.

PyOhio invites all interested people to submit proposals for scheduled talks and tutorials. PyOhio will accept abstracts on any topics of interest to Python programmers.

Standard presentations are expected to last 40 minutes with a 10 minute question-and-answer period. Other talk formats will also be considered, however; please indicate your preferred format in your proposal. Hands-on tutorial sessions are also welcomed. Tutorial instructors should indicate the expected length

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

All proposals should include abstracts no longer than 500 words in length. Abstracts must include the title, summary of the presentation, the expertise level targeted, and a brief description of the area of Python programming it relates to.

All proposals should be emailed to cfp@pyohio.org for review. Please submit proposals by May 15, 2009. Accepted speakers will be notified by June 1.

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.

2 comments | 0 pingbacks

Python STOMP Implementation

03.04.2009 19:42

posted by: Benjamin Smith

Posted Under: , , ,

Everyone else is doing it!

Quite seriously though… In my dealings with JMS Message Queuing, specifically with ActiveMQ, I felt the lack of a simple, straight-forward and easy to use Python implementation of the protocol that was also well documented and hackable.

More often than not, I found myself using Perl’s Net::Stomp module because it was so much quicker to get going. Gasp you say, a Perl module that is easier to use than a Python module?! BLASPHEMY! I implore you to believe me!

I don’t think I’ve reinvented the wheel, merely rounded it to my specifications. So, if you choose, check out my implementation of STOMP in Python over at Bitbucket: python-stomp.

It is feature-complete according to the STOMP Protocol, 100% Unit test covered, documented, comes with example usage and is simple to use.

Feedback is appreciated in the form of issues on the Bitbucket issue tracker or this blog if you want to say something nice, or mean about it!

Documentation:

Code:

0 comments | 0 pingbacks

Psyched for Pycon 2009

25.03.2009 10:24

posted by: Benjamin Smith

Posted Under: ,

I’m jazzed to be heading to Chicago again this year for pycon. Last year I had a blast and learned a lot. I even got to apply some of what I learned in practice at work and on personal projects! I’m hoping that I’ll take away as much value from the conference this year. A quick look at the talks suggest that won’t be a problem.

I’m going to try to blog while I’m there, but most likely you’ll get more out of me via twitter, so why not follow me there?

Here’s the list of talks I really want to attend:

There is no order here, scheduling is the tricky part..

There’s more, but those are the ones that stuck out to me.. Don’t think I’m in too much danger of missing anything this year.

A few of us at AG Interactive are planning a night of getting together for what we’re dubbing as #pyconbeer on twitter, so keep a search up: Twitter #pyconbeer I’m thinking we’re going to shoot for Friday evening, the 27th.

Hope to see many of you there and put names to faces!

Pycon 2009

0 comments | 0 pingbacks

Django debug toolbar FTW.

30.01.2009 12:08

posted by: Benjamin Smith

Posted Under: , , ,

If you do any development with Django, then this is a must have.

Not only is it awesomely useful, but it also has a great abbreviation that could be a throwback to WWF days of old. Any child of the mid-to-late 80’s remember the DDT?! That’s kind of what this is does, help you drive problems with your app head first into the mat - nice.

Google code page here: DDT on google code

Github here: DDT on github

Like any other python package, this one is simple to install.

Get a tarball, unpack it, cd into it..

# python setup.py build
# sudo python setup.py install

Now, use it in your django app by adding something similar to your settings.py:

# This should be appended to MIDDLEWARE_CLASSES:
'debug_toolbar.middleware.DebugToolbarMiddleware',

# This should be appended to INSTALLED_APPS:
'debug_toolbar',

# Set this to localhost if developing locally
# If not developing locally, add your remote IP..
INTERNAL_IPS = ('127.0.0.1')

# Various apps available
DEBUG_TOOLBAR_PANELS = (
    'debug_toolbar.panels.version.VersionDebugPanel',
    'debug_toolbar.panels.timer.TimerDebugPanel',
    'debug_toolbar.panels.headers.HeaderDebugPanel',
    'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
    'debug_toolbar.panels.sql.SQLDebugPanel',
    'debug_toolbar.panels.cache.CacheDebugPanel',
    'debug_toolbar.panels.logger.LoggingPanel',
)

See here: README for more detail on usage/install.

Get it, use it, love it.

EDIT: Added some quick bits on how to install/use

2 comments | 1 pingback

byteflow/django+supervisord+nginx = WIN

18.01.2009 23:06

posted by: Benjamin Smith

Posted Under: , , , ,

Recently I made the final step in converting my website over to nginx. I decided to manage my django application, byteflow, with supervisor. I have had great success with this over at AGI and thought I should advocate the success I’ve had to the public by extending it to my own site.

I first heard about supervisor at pycon last year and thought it could be useful in many ways, especially at the office. In a nutshell, supervisor ‘supervises’ processes, and allows you to manage them with a simple interface, but I’ll go into more detail about it later. Around the same time that I discovered supervisor I had also started experimenting with nginx and fastcgi to run my blog. I ended up going with lighty and fastcgi instead, however, mainly due to familiarity. Things change, and so do my opinions on technology. Nginx sold me on it’s performance and simplistic configuration, plain and simple. So now, here’s the meat and potatoes.

To break it down, here is what we’re looking at.

INTARWEBS -> nginx -> fastcgi -> django/byteflow(managed by supervisor)

Everything below assumes you have installed nginx, django, byteflow and supervisor.

So how about a look at the actual setup.

First, let’s take a look at the code to fire up the django app. I’ve dubbed it runserver.py and put it in my byteflow code tree.

#!/usr/bin/env python
if __name__ == '__main__':
    from flup.server.fcgi_fork import WSGIServer
    from django.core.handlers.wsgi import WSGIHandler
    WSGIServer(WSGIHandler()).run()

This keeps the django devs happy by not relying on manage.py to keep up with the server stuffs.

It’s pretty simple.. Starts up flups’ WSGIServer and uses django’s WSGIHandler to do the dirty work. Not much to it, really.

Now, lets take a look at the supervisor setup. You can get a lot of what you need by running:

# sudo echo_supervisord_conf > /etc/supervisord.conf

That sets up a basic (but verbose!) supervisor config. I’ve trimmed it down to this:

[unix_http_server]
file=/tmp/supervisor.sock   ; (the path to the socket file)

[supervisord]
logfile=/var/log/supervisord/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB       ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10          ; (num of main logfile rotation backups;default 10)
loglevel=info               ; (log level;default info; others: debug,warn,trace)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false              ; (start in foreground if true;default false)
minfds=1024                 ; (min. avail startup file descriptors;default 1024)
minprocs=200                ; (min. avail process descriptors;default 200)
user=nobody                 ; (default is current user, required if root)
childlogdir=/var/log/supervisord/            ; ('AUTO' child log dir, default $TEMP)

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket

; Production setup
[fcgi-program:django_fcgi]
socket=tcp://127.0.0.1:8080  ; We reference this later in nginx
command = /home/bsmith/Dev/byteflow/runserver.py  ; Calls the above code
environment=PYTHONPATH=/home/bsmith/Dev/byteflow  ; Setup needed environment
environment=DJANGO_SETTINGS_MODULE=settings

; Development setup
[fcgi-program:django_dev_fcgi]
socket=tcp://127.0.0.1:8081
command = /home/bsmith/Dev/byteflow_new/runserver.py
environment=PYTHONPATH=/home/bsmith/Dev/byteflow_new
environment=DJANGO_SETTINGS_MODULE=settings

Simple enough, eh? Comments in the configuration should explain what’s going on.

Now you can crank it up by running:

$ sudo supervisord

and check the status…

$ sudo supervisorctl status
django_dev_fcgi:django_dev_fcgi_0 RUNNING    pid 15949, uptime 0:00:08
django_fcgi:django_fcgi_0        RUNNING    pid 15950, uptime 0:00:08

Could it be more simple? I doubt it. This barely begins to scratch the surface of what supervisor can do. Process groups/pools, XML-RPC interface for remote management, built-in web interface for process management(utilizing XML-RPC interface), tons of process management options (priority, umask, user/group, capture std* pipes, environment variables, auto restart/start, process naming), event listeners/handling and a simple configuration ta boot! All I’m sayin’ is, it’s awesome…I’m just sayin’.

Keeping with our simple but awesome theme, enter nginx…

My main config:

user www-data;
# Could vary by number of processors available.
worker_processes  1;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
    use epoll;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log      /var/log/nginx/access.log;

    sendfile        on;

    keepalive_timeout  65;
    tcp_nodelay        on;

    gzip  on;

    include /etc/nginx/sites/*;

}

and my various site-specific configurations that I keep /etc/nginx/sites:

server {
        # We listen on port 80
        listen 80;
        server_name just-another.net;

        # access and error logs for our site
        access_log /var/log/nginx/my_site_access_log;
        error_log /var/log/nginx/my_site_error_log;

        # Configure redirect for our fastcgi server
        # The fastcgi server later runs on localhost Port 8080
        location / {
                expires 10d;
                # to fastcgi server could use socket..
                #fastcgi_pass unix:{project_location}/log/django.sock;
                fastcgi_pass 127.0.0.1:8080;
                fastcgi_param PATH_INFO $fastcgi_script_name;
                fastcgi_param REQUEST_METHOD $request_method;
                fastcgi_param QUERY_STRING $query_string;
                fastcgi_param CONTENT_TYPE $content_type;
                fastcgi_param CONTENT_LENGTH $content_length;
                fastcgi_param REMOTE_ADDR $remote_addr;
                fastcgi_pass_header Authorization;
                fastcgi_intercept_errors on;
        }

        location /images {
    # For my own images..
            alias /home/bsmith/public_html/images;
            expires 10d;
        }

        # Alias for static content like themes
        location /static {
            alias /home/bsmith/Dev/byteflow/static;
            expires 10d;
        }

        # Alias for python contrib.admin stuff, needed for admin interface
        location /admin-media {
    # Point to my most recent install of django.
            alias /home/bsmith/Dev/django_trunk/django/contrib/admin/media;
            expires 10d;
        }
        # Point to media
        location /media {
            alias /home/bsmith/public_html/media;
            expires 10d;
        }
        # Use feedburner for my feeds.
        rewrite ^/rpc(.*) http://feeds.feedburner.com/Just-anothernetBlogPosts$1 permanent;
}

Pretty simple, eh? I have the same server setup for my ‘dev’ site, only with a volatile code base that I can hack on.

Now when I make code changes all I need to do is reload the supervisor process like so:

$ sudo supervisorctl restart django_fcgi:django_fcgi_0

for the production site or replacing the process name with django_dev_fcgi:django_dev_fcgi_0 to restart the dev site. I could also restart everything by replacing a process name with all as an argument.

The possibilities here for process management endless and I couldn’t be happier with how simple it has become to run what I have.

Basically, this setup is easy to get running and easy to keep running. Highly recommended for any lazy django site maintainer like myself!

17 comments | 2 pingbacks

The tubes, the tubes!

28.12.2008 15:31

posted by: Benjamin Smith

Posted Under: , ,

I strive daily for high availability at my job, and seeing things like this almost makes it seem in vein: The Tubes Are Clogged

I spent an hour this morning researching what seemed like a non-issue on my side. Thankfully I was right, sadly it was because of this outage at Level3.

Big hand, long reach. Touch lots, break lots.

FEAR.

0 comments | 0 pingbacks

It’s a yolk!

18.12.2008 17:14

posted by: Benjamin Smith

Posted Under: , ,

Enjoy…

That's one large....leg

1 comment | 0 pingbacks

Those dishes won’t wash themselves..

16.12.2008 23:47

posted by: Benjamin Smith

Posted Under: , , ,

Totally inspired by Wil Wheaton while doing the dishes, something dawned on me. I have a blog; why don’t I use it to catalog the random thoughts I have, not only tech related, but thoughts in general. I’ve been very selective about what I write, but I realize that I don’t just write blogs for everyone else to read, but also as a way to reflect, jog my own memory (holy crap like a journal wtfkickbrains).

So now I bring you; what ran through my head while doing the dishes. Maybe one of many posts that don’t make much sense, but mean something!

  • Pair programming sounds like a neat idea, it could really help me hone my skills.
  • Who the hell leaves this much peanut butter on a knife, it’s a bitch to clean and damn wasteful.
  • Mike Patton is a musical fucking genius and should be celebrated till the end of time.
  • I should have done these earlier, but I was too busy making python do exactly what I wanted, with ease.
  • I really shouldn’t let these sit so long before I get to them.
  • Weens The Mollusk is a fantastic album.
  • My trip to Knoxville this weekend is going to be a long one.. Kinda wish I still lived there, would be a much shorter trip.
  • I should blog about my thoughts, and post it to twitter because I don’t usually do that and that’s what they are for.

So, that’s it in a nutshell. Almost verbatim what I was thinking, put to text. Expect more of this, kind of therapeutic in its own way..

1 comment | 0 pingbacks

CentOS 5 Upgrade and Yum

22.11.2008 13:17

posted by: Benjamin Smith

Posted Under: , ,

At the office I recently upgraded a machine to CentOS 5.2 from CentOS 4.7 (filesystem stayed intact). Everything was cool until I ran into a bit of an issue when attempting to update and regen the yum cache. I got a python traceback that looked like this:

# yum update
base      : ################################################## 2458/2458
update                    100% |=========================|  951 B    00:00
primary.xml.gz            100% |=========================| 242 kB    00:00
Traceback (most recent call last):
  File "/usr/bin/yum", line 29, in ?
    yummain.main(sys.argv[1:])
  File "/usr/share/yum-cli/yummain.py", line 105, in main
    result, resultmsgs = base.doCommands()
  File "/usr/share/yum-cli/cli.py", line 289, in doCommands
    self._getTs()
  File "/usr/lib/python2.4/site-packages/yum/depsolve.py", line 85, in _getTs
    self._getTsInfo()
  File "/usr/lib/python2.4/site-packages/yum/depsolve.py", line 91, in _getTsInfo
    self._tsInfo.setDatabases(self.rpmdb, self.pkgSack)
  File "/usr/lib/python2.4/site-packages/yum/__init__.py", line 537, in <lambda>
    pkgSack = property(fget=lambda self: self._getSacks(),
  File "/usr/lib/python2.4/site-packages/yum/__init__.py", line 392, in _getSacks
    self.repos.populateSack(which=repos)
  File "/usr/lib/python2.4/site-packages/yum/repos.py", line 242, in populateSack
    sack.populate(repo, mdtype, callback, cacheonly)
  File "/usr/lib/python2.4/site-packages/yum/yumRepo.py", line 168, in populate
    dobj = repo_cache_function(xml, csum)
  File "/usr/lib64/python2.4/site-packages/sqlitecachec.py", line 42, in getPrimary
    self.repoid))
TypeError: Can not prepare packages insertion: table packages has no column named location_base

Eeek! Got the same error when running yum makecache. Quick look at the traceback is somewhat obvious, the DB schema changed, but the DB didn’t get upgraded! Easy fix is to clear out your yum cache like so:

# cd /var/cache/yum
# rm -r *

And then you’ll want to regenerate your cache like so:

# yum makecache

Hope this helps anyone else who runs into this issue!

4 comments | 0 pingbacks

Ubuntu (Intrepid) and Aventail SSL VPN Client

20.11.2008 21:56

posted by: Benjamin Smith

Posted Under: , , ,

Since upgrading to Ubuntu 8.10 (Intrepid) I had been having trouble with my SSL VPN connectivity. Rather than sit down and figure it out I chose to fire up a virtual box instance of 8.04 and use it to get work done. Finally, tonight, I hit the tipping point and decided to figure this out. First I discovered debug mode with the SSL client. You can enable it on the command line by running

# startct -d

That will put a log in /var/log/AvConnect.log with lots of debugging goodness. The first thing I noticed was a fun error that looked kinda like this:

XGSSL::Connect() DoHandShake Failed!!!

Obviously enough, this led me to believe that this was a problem with the ssl handshake.

So, I decided at this point to inspect the guts of the Aventail client. Seemed simple enough, a few shell scripts (startct,stopct,uninstall) and some perl (cctel.pl) and then there’s this mysterious binary, AvConnect. I decided to look deeper and found this..

# file /usr/local/Aventail/AvConnect 
/usr/local/Aventail/AvConnect: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped

Looks like it uses shared libs, let’s see where it’s linking..

# ldd /usr/local/Aventail/AvConnect 
linux-gate.so.1 =>  (0xb8008000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7fd4000)
libssl.so.0.9.7 => /usr/lib/libssl.so.0.9.7 (0xb7e93000)
libcrypto.so.0.9.7 => /usr/lib/libcrypto.so.0.9.7 (0xb7d3c000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7d16000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7bb8000)
/lib/ld-linux.so.2 (0xb8009000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7bb4000)
libz.so.1 => /usr/lib/libz.so.1 (0xb7b9e000)

Did a bit more digging by running some tests with OpenSSL.

# openssl version
OpenSSL 0.9.8g 19 Oct 2007

# openssl s_client -CAfile /etc/ssl/certs/Entrust_Root_Certification_Authority.pem -connect <myvpnhost>:443 -showcerts

Which seemed to work fine..

So, puzzled I compared the openssl package on my 8.04 VM to what I had installed, shockingly they matched.

# openssl version
OpenSSL 0.9.8g 19 Oct 2007

Taking a shot in the dark I decided to upgrade my local install of openssl from source. Fairly run of the mill install..

# wget http://openssl.org/source/openssl-0.9.8i.tar.gz

# tar zxvfm openssl-0.9.8i.tar.gz

To get the shared objects, you’ll want to run configure like so:

# cd openssl-0.9.8i
# ./config shared

Now, do the magic..

# make && make test

Install it in the default location /usr/local/ssl

# sudo make install

Then, you’ll want to update your links in /usr/lib to point at the new shared objects.

# sudo ln -s /usr/local/ssl/lib/libcrypto.so /usr/lib/libcrypto.so

# sudo ln -s /usr/local/ssl/lib/libssl.so /usr/lib/libssl.so

# sudo rm /usr/lib/libcrypto.so.0.9.7

# sudo ln -s /usr/lib/libcrypto.so /usr/lib/libcrypto.so.0.9.7

# sudo rm /usr/lib/libssl.so.0.9.7

# sudo ln -s /usr/lib/libssl.so /usr/lib/libssl.so.0.9.7

Then test it out by running startct and you should be able to connect as usual. I have yet to figure out why the ssl handshake fails with the packaged version of openssl, so if anyone has any clue about that or has a smarter work around, please let me know :)

This is, of course, not the recommended action for people new to Linux/Ubuntu and I provide no guarantee that it will work for you. I just wished to provide a possible work around for anyone having the same issue googling around aimlessly.

Enjoy

EDIT: More comprehensive shuffling of lib links per comments and observations below. Thanks devodl and js!

21 comment | 0 pingbacks
More Posts: »