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

PyOhio 2015 - Python Packaging from Init to Deploy

Ec6de98b75fa5831bc2f13564c5242fa?s=47 Dave Forgac
August 02, 2015

PyOhio 2015 - Python Packaging from Init to Deploy

Python packaging really isn't that bad (anymore.) In this talk you'll learn how you can take your beautiful new Python code and share it with the world in a way that everyone benefits. I will cover tools and techniques you can use to get the boring stuff out of the way so you can focus on your code and deploy quickly, frequently, and consistently.

Ec6de98b75fa5831bc2f13564c5242fa?s=128

Dave Forgac

August 02, 2015
Tweet

More Decks by Dave Forgac

Other Decks in Technology

Transcript

  1. Python Packaging from Init to Deploy

  2. Slides & Notes http://daveops.com/pyohio2015

  3. Dave Forgac dave@forgac.com @tylerdave

  4. A long time ago in a galaxy far, far away...

  5. How to package? There should be one — and preferably

    only one — obvious way to do it.
  6. Which is it? distutils setuptools distribute ?

  7. Copy, replace

  8. Fast forward ⏩

  9. PyPA! PyPUG!

  10. What did I learn?

  11. Definitions

  12. Module Saved Python code

  13. (Import) Package Namespace (directory)

  14. (Distribution) Package Shareable / installable

  15. Source Distribution sdist

  16. Built Distribution bdist_egg bdist_wheel

  17. Wheel Universal Pure Python Platform

  18. PyPI ≠

  19. Components . ├── data │ └── data_file ├── DESCRIPTION.rst ├──

    MANIFEST.in ├── README.rst ├── sample │ ├── __init__.py │ └── package_data.dat ├── setup.cfg ├── setup.py └── tests ├── __init__.py └── test_simple.py
  20. Code

  21. setup.py

  22. setup.cfg

  23. MANIFEST.in

  24. README.rst

  25. DESCRIPTION.rst

  26. setup.py (1) from setuptools import setup, find_packages setup( name='pyohio2015', version='0.1.0',

    # PEP440 description='Example package for PyOhio talk.', long_description='Displayed on PyPI project page.', url='https://github.com/tylerdave/PyOhio-2015-Example', author='Dave Forgac', author_email='tylerdave@tylerdave.com', …
  27. setup.py (2) … license='MIT', classifiers=[ 'Development Status :: 3 -

    Alpha', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', ], …
  28. setup.py (3) … keywords='example project pyohio', packages=find_packages(exclude=['docs', 'tests*'] install_requires=['requests'], package_data={

    'sample': ['package_data.dat'] } data_files=None …
  29. setup.py (4) … # scripts= , entry_points={ 'console_scripts': [ 'hello=pyohio2015:say_hello',

    ], } )
  30. More Components

  31. LICENSE

  32. Tests ./tests tox.ini

  33. Docs ./docs

  34. CI .travis.yml

  35. requirements.txt

  36. .gitignore

  37. Other files (rst | md | txt) HISTORY or CHANGES

    or CHANGELOG CONTRIBUTING AUTHORS
  38. Let's make a package!

  39. Requirements pip install wheel pip install twine pip install tox

  40. Repitition & Boilerplate We automate! We automate! We let someone

    else!
  41. pip install cookiecutter

  42. Make virtualenv (I use virtualenvwrapper) mkvirtualenv pyohio2015

  43. Run cookiecutter dave@xps:$ cookiecutter https://github.com/tylerdave/cookiec python-package.git … full_name (default is

    "Dave Forgac")? email (default is "tylerdave@tylerdave.com")? github_username (default is "tylerdave")? project_name (default is "Python Boilerplate")? PyOhio 2015 repo_name (default is "boilerplate")? pyohio2015 project_short_description (default is "Python Boilerplate co all the boilerplate you need to create a Python package.")? package for PyOhio talk. release_date (default is "2015-08-02")? year (default is "2015")? version (default is "0.1.0")?
  44. Git init cd pyohio2015 git init git add . git

    commit -m 'initial commit'
  45. Add your code pyohio2015/cli.py: from __future__ import print_function def hello():

    """ Returns a Hello, World! """ return("Hello, PyOhio!") def say_hello(): """ Prints Hello, World message """ print(hello())
  46. Add tests tests/test_pyohio2015.py: import pyohio2015 class TestPyohio2015(unittest.TestCase): def setUp(self): self.hello_message

    = "Hello, PyOhio!" def test_prints_hello_pyohio(self): output = pyohio2015.hello() assert(output == self.hello_message)
  47. Run tests tox … OK ___________________________ summary ________________________ py26: InterpreterNotFound:

    python2.6 py27: commands succeeded py33: InterpreterNotFound: python3.3 py34: commands succeeded
  48. Commit git add . git commit -m "add hello world

    functionality"
  49. Services

  50. Create github repo

  51. Add repo to Travis CI https://travis-ci.org/

  52. Git push To git@github.com:tylerdave/PyOhio-2015-Example.git * [new branch] master -> master

    Branch master set up to track remote branch master from origin.
  53. See builds succeeding!

  54. None
  55. None
  56. PyPI

  57. Save PyPI Settings $HOME/.pypirc [distutils] index-servers=pypi [pypi] repository = https://pypi.python.org/pypi

    username = <username> password = <password>
  58. Build

  59. Create distribution files ./setup.py sdist ./setup.py bdist_wheel

  60. Sign distribution files gpg --detach-sign -a

  61. Register Package Upload from pyohio2015.egg-info/PKG-INFO

  62. Upload twine upload dist/*

  63. None
  64. Iterate

  65. Develop Mode ./setup.py develop or pip install -e .

  66. Make changes

  67. Update version in setup.py and [package]/__init__.py

  68. Commit, tag, & push git commit -m "awesome new functionality!"

    git push origin master git tag v0.2.0 git push origin --tags
  69. Build, sign, & upload

  70. Versioneer

  71. Caveats

  72. Thank You! Talk & Contact Info: http://daveops.com/pyohio2015 dave@forgac.com @tylerdave