views:

232

answers:

1

Hi

I have a few Munin plugins which report stats from an Autonomy database. They all use a small library which scrapes the XML status output for the relevant numbers.

I'm trying to bundle the library and plugins into a Puppet-installable RPM. The actual RPM-building should be straightforward; once I have a distutils-produced distfile I can make it into an RPM based on a .spec file pinched from the Dag or EPEL repos [1]. It's the distutils bit I'm unsure of -- in fact I'm not even sure my library is correctly written for packaging. Here's how it works:

idol7stats.py:

import datetime
import os
import stat
import sys
import time
import urllib
import xml.sax

class IDOL7Stats:
  cache_dir = '/tmp'

  def __init__(self, host, port):
    self.host = host
    self.port = port

  # ...

  def collect(self):
    self.data = self.__parseXML(self.__getXML())

  def total_slots(self):
    return self.data['Service:Documents:TotalSlots']

Plugin code:

from idol7stats import IDOL7Stats
a = IDOL7Stats('db.example.com', 23113)
a.collect()
print a.total_slots()

I guess I want idol7stats.py to wind up in /usr/lib/python2.4/site-packages/idol7stats, or something else in Python's search path. What distutils magic do I need? This:

from distutils.core import setup

setup(name = 'idol7stats',
  author = 'Me',
  author_email = '[email protected]',
  version = '0.1',
  py_modules = ['idol7stats'])

almost works, except the code goes in /usr/lib/python2.4/site-packages/idol7stats.py, not a subdirectory. I expect this is down to my not understanding the difference between modules/packages/other containers in Python.

So, what's the rub?

[1] Yeah, I could just plonk the library in /usr/lib/python2.4/site-packages using RPM but I want to know how to package Python code.

+2  A: 

You need to create a package to do what you want. You'd need a directory named idol7stats containing a file called __init__.py and any other library modules to package. Also, this will affect your scripts' imports; if you put idol7stats.py in a package called idol7stats, then your scripts need to "import idol7stats.idol7stats".

To avoid that, you could just rename idol7stats.py to idol7stats/__init__.py, or you could put this line into idol7stats/__init__.py to "massage" the imports into the way you expect them:

from idol7stats.idol7stats import *
Matt Campbell
Aha! Putting the code into __init__.py looks exactly what I'm after. Thanks!
markdrayton