Getting Started With ``setuptools`` and ``setup.py`` **************************************************** ``setuptools`` is a rich and complex program. This tutorial will focus on the bare minimum basics you need to get setuptools running so you can: * Register your package on pypi. * Build egg, source, and window installer 'distributables'. * Upload these 'distributables' to pypi. Installing setuptools and easy install ====================================== To install setuptools visit http://pypi.python.org/pypi/setuptools and follow the instructions for your operating system. Also, check out http://peak.telecommunity.com/DevCenter/EasyInstall for more instructions on how to install setup tools. Currently (as of November, 2009), setuptools is pretty easy to install for Python version 2.3 through 2.6. Bootstrapping setuptools ----------------------- If you are having trouble setting up setuptools for your platform, you may want to check out the 'bootstrap' setuptools script at http://peak.telecommunity.com/dist/ez_setup.py. You can run this like this:: $ python ez_setup.py and it will install setuptools for whichever version of Python ``python`` refers to. For example on windows:: $ C:\Python24\python.exe ez_setup.py will install a setuptools for your python24 distribution. Setting up ``setup.py`` ======================= All the features of what can go into a ``setup.py`` file is beyond the scope of this simple tutorial. I'll just focus on a very basic and common format needed to get this project onto pypi. The contents of ``setup.py`` is just pure python:: import os from setuptools import setup # Utility function to read the README file. # Used for the long_description. It's nice, because now 1) we have a top level # README file and 2) it's easier to type in the README file than to put a raw # string in below ... def read(fname): return open(os.path.join(os.path.dirname(__file__), fname)).read() setup( name = "an_example_pypi_project", version = "0.0.4", author = "Andrew Carter", author_email = "andrewjcarter@gmail.com", description = ("An demonstration of how to create, document, and publish " "to the cheese shop a5 pypi.org."), license = "BSD", keywords = "example documentation tutorial", url = "http://packages.python.org/an_example_pypi_project", packages=['an_example_pypi_project', 'tests'], long_description=read('README'), classifiers=[ "Development Status :: 3 - Alpha", "Topic :: Utilities", "License :: OSI Approved :: BSD License", ], ) Directory Structure ------------------- The directory structure, so far, should look like this:: some_root_dir/ |-- README |-- setup.py |-- an_example_pypi_project | |-- __init__.py | |-- useful_1.py | |-- useful_2.py |-- tests |-- |-- __init__.py |-- |-- runall.py |-- |-- test0.py README ------ A nice idea stolen from http://pypi.python.org/pypi/Sphinx-PyPI-upload is to include a README text file which your code. This would be visible when someone, say, cloned your repo. Using the simple ``read`` function, it is easy to include this in the ``long_description`` keyword arg for the :func:`setuptools.setup` function. Classifiers ----------- A really nice website is http://pypi.python.org/pypi?%3Aaction=list_classifiers which lists all the classifiers you can use in the ``setup`` call. A sample of this website is:: Development Status :: 1 - Planning Development Status :: 2 - Pre-Alpha Development Status :: 3 - Alpha Development Status :: 4 - Beta Development Status :: 5 - Production/Stable Development Status :: 6 - Mature Development Status :: 7 - Inactive Environment :: Console Environment :: Console :: Curses Environment :: Console :: Framebuffer Environment :: Console :: Newt Environment :: Console :: svgalib Using ``setup.py`` ================== The basic usage of ``setup.py`` is:: $ python setup.py To see all commands type:: $ python setup.py --help-commands And you will get:: Standard commands: build build everything needed to install build_py "build" pure Python modules (copy to build directory) build_ext build C/C++ extensions (compile/link to build directory) build_clib build C/C++ libraries used by Python extensions build_scripts "build" scripts (copy and fixup #! line) clean clean up temporary files from 'build' command install install everything from build directory install_lib install all Python modules (extensions and pure Python) install_headers install C/C++ header files install_scripts install scripts (Python or otherwise) install_data install data files sdist create a source distribution (tarball, zip file, etc.) register register the distribution with the Python package index bdist create a built (binary) distribution bdist_dumb create a "dumb" built distribution bdist_rpm create an RPM distribution bdist_wininst create an executable installer for MS Windows upload upload binary package to PyPI Extra commands: rotate delete older distributions, keeping N newest files develop install package in 'development mode' setopt set an option in setup.cfg or another config file saveopts save supplied options to setup.cfg or other config file egg_info create a distribution's .egg-info directory upload_sphinx Upload Sphinx documentation to PyPI install_egg_info Install an .egg-info directory for the package alias define a shortcut to invoke one or more commands easy_install Find/get/install Python packages bdist_egg create an "egg" distribution test run unit tests after in-place build build_sphinx Build Sphinx documentation usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] or: setup.py --help [cmd1 cmd2 ...] or: setup.py --help-commands or: setup.py cmd --help Intermezzo: .pypirc file and gpg ================================ In order to interact with pypi, you first need to setup an account. Go to http://pypi.python.org/pypi and click on ``Register``. Now, once registered, when you run ``setup.py`` commands that interact with pypi you'll have to enter your username and password each time. To get around this, place a ``.pypirc`` file in your ``$HOME`` directory on linux. On windows, an you'll need to set a ``HOME`` environ var to point to the directory where this file lives. The structure of a ``.pypirc`` file is pretty simple:: [pypirc] servers = pypi [server-login] username:your_awesome_username password:your_awesome_password .. note:: There's probably away around having your plain text password in this file, but I don't know of the solution and haven't looked into it. Also, you often want to ``sign`` the files using gpg encryption. Visit http://www.gnupg.org/ on linux or http://www.gpg4win.org/ on windows to install this software. Registering Your Project ======================== With your ``setup.py`` and ``.pypirc`` in place, registering your project is pretty simple. Just type:: $ python setup.py register I would say more, but it is just that simple. Uploading Your Project ====================== There are three major ``setup.py`` commands we will use: * ``bdist_egg``: This creates an egg file. This is what is necessary so someone can use ``easy_install your_project``. * ``bdist_wininst``: This will create an ``.exe`` that will install your project on a windows machine. * ``sdist``: This create a raw source distribution which someone can download and run ``python setup.py`` directly. .. note:: A key point here is you need to run these commands with the version of python you want to support. We'll cover this in the `Putting It All Together With The Full Windows Script`_ below. You can run these commands by themselves and simply create the files but not upload them. However, for this project, we always marry these commands with the ``upload`` directive which will both *build* and *upload* the necessary files. Putting It All Together With The Full Windows Script ==================================================== This project was build on a windows machine. To best understand how it all works and the other options used when using ``setup.py`` let's just look at the ``.bat`` file I use to build the package and upload it to pypi:: set HOME=C:\Users\Owner\ cd C:\eclipse\workspace\HG_AN_EXAMPLE_PYPI_PROJECT C:\Python24\python.exe setup.py bdist_egg upload --identity="Andrew Carter" --sign --quiet C:\Python25\python.exe setup.py bdist_egg upload --identity="Andrew Carter" --sign --quiet C:\Python26\python.exe setup.py bdist_egg upload --identity="Andrew Carter" --sign --quiet C:\Python24\python.exe setup.py bdist_wininst --target-version=2.4 register upload --identity="Andrew Carter" --sign --quiet C:\Python25\python.exe setup.py bdist_wininst --target-version=2.5 register upload --identity="Andrew Carter" --sign --quiet C:\Python26\python.exe setup.py bdist_wininst --target-version=2.6 register upload --identity="Andrew Carter" --sign --quiet C:\Python26\python.exe setup.py sdist upload --identity="Andrew Carter" --sign pause For linux, it would be pretty much the same commands, just changing around the directories to point to the correct python versions. .. note:: I use the ``set HOME=C:\Users\Owner\`` instead of setting an environ variable on windows