Slide 1

Slide 1 text

Package and distribute your Python code PyCon India 2013, Bangalore Sanket Saurav Co-founder, CampusHash

Slide 2

Slide 2 text

Your awesome Python module is ready! What now?

Slide 3

Slide 3 text

Let's go to the Cheese Shop! No, really! PyPI == Cheese Shop ;)

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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, -- 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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

And...you're done! Yay!

Slide 12

Slide 12 text

But there's more... Let's dig deeper

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

I love questions! LOL JK. PyPI == Cheese Shop ;)

Slide 20

Slide 20 text

Thank You! You have been a great audience! twitter @sanketsaurav www blog.sanketsaurav.com github sanketsaurav