Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Package and distribute your Python code

Package and distribute your Python code

Deck for my talk on packaging at PyCon India, 2013 at Bangalore, India.

Sanket Saurav

August 31, 2013
Tweet

More Decks by Sanket Saurav

Other Decks in Programming

Transcript

  1. Agenda (duh!) At the end of the talk, you can

    expect that your package: *Well, not really. **Guaranteed, or get your money back. @sanketsaurav Can be easily installable with pip or easy_install Can be specified as a dependency for another package Will have proper tests included* Will have proper documentation* Will make the world a better place!** · · · · · 4/20
  2. Laying out your package @sanketsaurav MoonGrabber |- bin/ |- CHANGES.txt

    |- docs/ |- LICENSE.txt |- MANIFEST.in |- README.rst |- setup.py |- moongrabber/ |- __init__.py |- moongun.py |- battery.py |- test/ |- __init__.py |- test_moongun.py |- test_fuel.py LAYOUT 5/20
  3. Breaking it up @sanketsaurav bin contains any scripts which use

    MoonGrabber that could be useful for the user. CHANGES.txt lists the changes to your module in successive versions. · · v<version>, <date> -- Initial release. CHANGES.TXT docs contains the documentation for your package should you choose to write some. And you should always do so. In LICENSE.txt, just paste your favorite license. MANIFEST.in specifies the extra files that you might want to include in your package. · · · include *.txt include *.json recursive-include docs *.txt MANIFEST.IN 6/20
  4. Breaking it up @sanketsaurav The README.txt file should be written

    in reStructuredText, so that PyPI can use it to generate the package's PyPI page. · =========== Moon Grabber =========== Moon Grabber is a super-awesome module which lets you steal the Moon. But promise to put it back.You can use it like this:: #!/usr/bin/env python from moongrabber import battery, moongun if battery.is_full(): moon = moongun.grab_moon(planet="Earth") README.RST 7/20
  5. Writing your setup.py @sanketsaurav from distutils.core import setup setup( name='MoonGrabber',

    version='0.4.2', author='Dr. Nefario', author_email='[email protected]', packages=['moongrabber', 'moongrabber.test'], scripts=['bin/clean-gun.py','bin/recharge-battery.py'], url='http://pypi.python.org/pypi/MoonGrabber/', license='LICENSE.txt', description='Steal the Moon from your favorite planet.', long_description=open('README.rst').read(), install_requires=[ "Django >= 1.1.1" ], ) SETUP.PY 8/20
  6. Creating a source distribution @sanketsaurav The sdist command creates a

    source distribution of your package. · $ python setup.py sdist SHELL It creates a MANIFEST file, a dist directory in your project folder. · This directory contains your archived distribution file. In this case, it is MoonGrabber-0.4.2.tar.gz. - 9/20
  7. The Cheese Shop! Register yourself with PyPI @sanketsaurav $ python

    setup.py register SHELL If you're already registered as a user on PyPI, this will register your package. If not, follow the instructions and the console and regsiter yourself. Then run the command again to register the package. · · $ python setup.py sdist upload SHELL This will re-build the source distribution and upload it to PyPI. · Whenever you want to update the package, you can use this command. - 10/20
  8. Add some classifiers @sanketsaurav Classifiers are used to additional metadata

    to your package. The classifiers argument in the setup() function takes a list of classifier strings. The list of strings can be found at pypi.python.org/pypi?%3Aaction=list_classifiers. · · · 13/20
  9. More with modules @sanketsaurav packages_dir = { '' : 'foo',

    'bar' : 'boo' } SETUP() Use it when you source folder layout is different from your package layout. · py_modules = ['foo', 'bar.zoo'] SETUP() Use it to include individual modules. · 14/20
  10. Extension modules @sanketsaurav ext_package='pkg' SETUP() Use it to list extension

    packages. · ext_modules=[ Extension('foo', ['foo.c'] ) ] SETUP() Use it to add extension modules, if you may. · library_dirs=['/usr/X11R6/lib'], libraries=['X11', 'Xt'] SETUP() Use it to include external libraries. · 15/20
  11. Adding more data @sanketsaurav package_data={'mypkg': ['data/*.dat']} SETUP() You can include

    data which is critical to your package. · data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']), ('config', ['cfg/data.cfg']), ('/etc/init.d', ['init-script'])] ) SETUP() You can add external data files too. · 16/20
  12. Creating built distributions @sanketsaurav $ python setup.py bdist SHELL This

    would create an archived built distribution. This is a dumb build. · $ python setup.py bdist_rpm $ python setup.py bdist_wininst $ python setup.py bdist_msi SHELL You can build these binaries on the respective platforms. · 17/20
  13. Do a setup.cfg Because doing setup() is too mainstream ;)

    @sanketsaurav [bdist_rpm] release = 1 packager = Greg Ward doc_files = CHANGES.txt README.txt USAGE.txt doc/ examples/ [build_ext] inplace=1 SETUP.CFG Use this when you cannot have everything predefined. Users can edit this file to customize their installation. · 18/20
  14. Thank You! You have been a great audience! twitter @sanketsaurav

    www blog.sanketsaurav.com github sanketsaurav