Writing a python module is great, but what’s really important is getting it out to others so they can make use of it too. What’s the best way to do that?
Of course, the best way is to use existing infrastructure in the Python community. PyPI is the place to get Python modules. You can browse them on the web, and they are all just a “easy_install” or “pip install” away.
Want people to be able to “pip install” or “easy_install” your module?
First, you must have your module in an standard module format. In this case, we’re just going to assume we’re starting a new project.
PasteScript is great for creating skeletons for projects. Let’s install it.
:::console $ pip install PasteScript
In this case, we just need to creat a the basic Python package layout.
:::console $ cd projects $ paster create --template=basic_package fibtools Selected and implied templates: PasteScript#basic_package A basic setuptools-enabled package Variables: egg: fibtools package: fibtools project: fibtools Enter version (Version (like 0.1)) ['']: 0.1.0 Enter description (One-line description of the package) ['']: A set of tools for working with fibonacci numbers Enter long_description (Multi-line description (in reST)) ['']: This set of tools is great for generating fibonacci numbers and doing things with them! Enter keywords (Space-separated keywords/tags) ['']: fibonacci, numbers, math Enter author (Author name) ['']: Your Name Enter author_email (Author email) ['']: firstname.lastname@example.org Enter url (URL of homepage) ['']: homepage.my.site Enter license_name (License name) ['']: MIT Enter zip_safe (True/False: if the package can be distributed as a .zip file) [False]: Creating template basic_package Creating directory ./fibtools Recursing into +package+ Creating ./fibtools/fibtools/ Copying __init__.py to ./fibtools/fibtools/__init__.py Copying setup.cfg to ./fibtools/setup.cfg Copying setup.py_tmpl to ./fibtools/setup.py
It creates a directory for your module and creates files required by distutils.
:::console $ ls -R fibtools fibtools: fibtools/ fibtools.egg-info/ setup.cfg setup.py fibtools/fibtools: __init__.py fibtools/fibtools.egg-info: dependency_links.txt entry_points.txt not-zip-safe PKG-INFO SOURCES.txt top_level.txt
Now let’s edit the init.py for our module, and put in some basic functionality.
We’ll just make a simple generator that spits out Fibonacci numbers.
:::python #!/usr/bin/env python def fibs(): a = 1 b = 1 while True: yield a (a, b) = (b, a+b) if __name__ == "__main__": generator = fibs() for i in range(10): print generator.next()
To test that your module works on your system you can go into your “projects/fibtools” directory and run “python setup.py develop”.
What this does is make links in your “/usr/lib/python/site-packages” directory to wherever the module is in your file system. This way, if you make changes to your module then the site-packages version always stays up to date. This is great, obviously, if you’re doing development and will need to test your changes. Once you’ve done this, you can import your module in a python shell just as you’d expect.
:::python >>> import fibtools >>> g = fibtools.fibs() >>> print g.next() 1 >>> print g.next() 1 >>> print g.next() 2 >>> print g.next() 3
Once your module works to your satisfaction, you can now register your module with PyPI.
:::console $ pwd ~/projects/fibtools $ python setup.py register running register running egg_info writing fibtools.egg-info/PKG-INFO writing top-level names to fibtools.egg-info/top_level.txt writing dependency_links to fibtools.egg-info/dependency_links.txt writing entry points to fibtools.egg-info/entry_points.txt reading manifest file 'fibtools.egg-info/SOURCES.txt' writing manifest file 'fibtools.egg-info/SOURCES.txt' running check We need to know who you are, so please choose either: 1. use your existing login, 2. register as a new user, 3. have the server generate a new password for you (and email it to you), or 4. quit Your selection [default 1]:
At this point, if you already have a PyPI account, you can just use your existing login to register your module. Otherwise, you’ll have to make an account. It’s quick and painless, of course, and just requires a username, password, and email address. It’s easiest if you cache your credentials locally, it’s simpler to upload updated versions of your module later.
Distutils will then automatically upload your code to PyPI and you can tell your friends to “pip install” or “easy_install” it.
By default, there is one flaw with the setup.py that is generated by Paster. It’s not big, but can be a bit of a hindrance. So let’s fix it, and re-upload your script to PyPI with a fixed version of setup.py.
:::python from setuptools import setup, find_packages import sys, os version = '0.1.0' setup(name='fibtools', version=version, description="A set of tools for working with fibonacci numbers", long_description="""\ This set of tools is great for generating fibonacci numbers and doing things with them!""", classifiers=, # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers keywords='fibonacci, numbers, math', author='Your Name', email@example.com', url='homepage.my.site', license='MIT', packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), include_package_data=True, zip_safe=False, install_requires=[ # -*- Extra requirements: -*- ], entry_points=""" # -*- Entry points: -*- """, )
We need to add a keywords list so that people can find our module. Add this anywhere inside of the parentheses:
::python keywords = ['fibtools', 'fibonacci', 'numbers']
And while we’re at it, we have to update the version number. PyPI does not let you re-upload a package with the same version twice. This is so that people can always know if they have the latest available version of a package; they can’t know if version numbers don’t increment. So change the “version” variable to “0.1.1” and now let’s re-upload the corrected version.
:::consolepwd ~/projects/fibtools python setup.py sdist upload running sdist running egg_info writing requirements to fibtools.egg-info/requires.txt writing fibtools.egg-info/PKG-INFO writing top-level names to fibtools.egg-info/top_level.txt writing dependency_links to fibtools.egg-info/dependency_links.txt reading manifest file 'fibtools.egg-info/SOURCES.txt' writing manifest file 'fibtools.egg-info/SOURCES.txt' warning: sdist: standard file not found: should have one of README, README.txt creating fibtools-0.1.1 creating fibtools-0.1.1 creating fibtools-0.1.1/fibtools creating fibtools-0.1.1/fibtools.egg-info making hard links in fibtools-0.1.1... Writing fibtools-0.1.1/setup.cfg Creating tar archive removing 'fibtools-0.1.1' (and everything under it) running upload Submitting dist/fibtools-0.1.1.tar.gz to http://pypi.python.org/pypi Server response (200): OK
And that’s it! Now people can “pip install” or “easy_install” your module.