Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Python Packaging Simplified by Asheesh Laroia
Search
PyCon 2014
April 12, 2014
Technology
930
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Python Packaging Simplified by Asheesh Laroia
Presented at PyCon 2014
PyCon 2014
April 12, 2014
More Decks by PyCon 2014
See All by PyCon 2014
Postgres Performance for Humans by Craig Kerstiens
pycon2014
28
3.7k
Technical Onboarding, Training, and Mentoring by Kate Heddleston and Nicole Zuckerman
pycon2014
1
2.4k
"My big gay adventure. Making, releasing and selling an indie game made in python." by Luke Miller
pycon2014
2
1.7k
Farewell and Welcome Home, Python in Two Genders by Naomi_Ceder
pycon2014
1
820
Deliver Your Software in an Envelope by Augie Fackler and Nathaniel Manista
pycon2014
1
620
Hitchhikers Guide to Free and Open Source Participation by Elena Williams
pycon2014
6
1.3k
Localization Revisted (aka. Translations Evolved) by Ruchi Varshney
pycon2014
0
740
Smart Dumpster by Bradley E. Angell
pycon2014
0
590
Software Engineering for Hackers: Bridging the Two Solitudes by Tavish Armstrong
pycon2014
0
790
Other Decks in Technology
See All in Technology
Claude in Chrome 入門 / Introduction to Claude in Chrome
cielo1985
0
830
synctest時代のhttptest Go 1.27で変わるHTTPサーバテストの裏側 / go conference2026 synctest and httptest
budougumi0617
1
3k
aws-iot-platform-architecture-use-cases.pdf
ma2shita
0
200
データ界隈LT祭 第1回LT登壇
taromatsui_cccmkhd
2
1.4k
新機種発売前に見直そう!端末移行で再ログインが要るアプリ・要らないアプリは何が違うのか 〜シームレスに再開できる設計と実装〜
zozotech
PRO
0
200
Slack上でインフラをトラブルシュートする! Agentic Platform Engineeringの第一歩
teru0x1
5
1.7k
DEFCON34-Write-up_HYCu-MYCu
daikiokazaki
0
160
越境するなら専門用語を使うな高校校歌 / If you wanna cross border, you shouldn't use jargon
vtryo
0
140
HRC_Frontend_Conference_Fukuoka_2026.pdf
ts020
0
730
Deployment の 先にある AI Agent 基盤 - kagent vNext、Agent Substrate、Hermes から読み解く Agent Runtime の現在地 / k8s-matsuri-2-ai-agent-platform-amsy810
masayaaoyama
3
600
日経電子版を支えていく Kasane Design System/fec_fukuoka
nikkei_engineer_recruiting
0
1.6k
人間はどの意思決定を手放せるのか
kawasima
14
7k
Featured
See All Featured
Joys of Absence: A Defence of Solitary Play
codingconduct
1
520
What does AI have to do with Human Rights?
axbom
PRO
1
2.4k
Building Flexible Design Systems
yeseniaperezcruz
330
41k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
450
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
How to Talk to Developers About Accessibility
jct
2
550
SEO for Brand Visibility & Recognition
aleyda
0
4.7k
Practical Orchestrator
shlominoach
192
12k
Navigating Weather and Climate Data
rabernat
0
520
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
500
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
76k
Navigating Team Friction
lara
192
16k
Transcript
Python packaging simplified for end users, app developers, and open
source contributors Asheesh Laroia
Changes No Debian vs. ??? No compiled code talking, except
wheel No focus on Django apps
Goals 1. Be able to install 2. Be able to
distribute 3. Know how to learn more
Goals 1. Be able to install 2. Be able to
distribute 3. Know how to learn more
Goals 1. Be able to install 2. Be able to
distribute 3. Know how to learn more
Installation
$ python
$ python >>> import numbers
$ python >>> import numbers >>> numbers <module 'numbers' from
'/usr/lib/python2.7/numbers.pyc' >
>>> import sys >>> sys.path
>>> import sys >>> sys.path ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux- gnu', '/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/home/me/.local/lib/python2.7/site- packages', '/usr/local/lib/python2.7/dist- packages', '/usr/lib/python2.7/dist-packages',
>>> import sys >>> sys.path ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux- gnu', '/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/home/me/.local/lib/python2.7/site- packages', '/usr/local/lib/python2.7/dist- packages', '/usr/lib/python2.7/dist-packages',
$ python >>> import numbers >>> numbers <module 'numbers' from
'/usr/lib/python2.7/numbers.pyc' >
None
>>> import etsy >>> import etsy
>>> import etsy >>> import etsy cheeseshop cheeseshop pypi.python.org pypi.python.org
>>> import etsy >>> import etsy cheeseshop cheeseshop pypi.python.org pypi.python.org
[etsy wrapper] [etsy wrapper]
None
None
>>> import python-etsy File "<stdin>", line 1 import python-etsy ^
SyntaxError: invalid syntax
None
None
None
$ sudp pip install python-etsy $ sudp pip install python-etsy
$ sudp pip install python-etsy $ sudp pip install python-etsy
Genki Sudo Genki Sudo World Order World Order
>>> import sys >>> sys.path ['', # ... '/home/me/.local/lib/python2.7/ site-packages',
]
$ pip install --user python-etsy
$ pip install --user python-etsy Downloading/unpacking python-etsy Downloading python-etsy- 0.1.2.tar.gz
$ pip install --user python-etsy Downloading/unpacking python-etsy Downloading python-etsy- 0.1.2.tar.gz
Successfully installed python-etsy Cleaning up...
$ pip install --user python-etsy Downloading/unpacking python-etsy Downloading python-etsy- 0.1.2.tar.gz
Successfully installed python-etsy Cleaning up... $ python >>> import etsy
$ pip install --user python-etsy Downloading/unpacking python-etsy Downloading python-etsy- 0.1.2.tar.gz
Successfully installed python-etsy Cleaning up... $ python >>> import etsy >>> etsy <module 'etsy' from '/home/me/.local/lib/python2.7/ site-packages/etsy/__init__.pyc'>
None
# module # module >>> import etsy >>> import etsy
# module # module >>> import etsy >>> import etsy
# distribution # distribution $ pip install --user python-etsy $ pip install --user python-etsy
# module # module >>> import etsy >>> import etsy
# distribution # distribution $ pip install --user python-etsy $ pip install --user python-etsy # tools # tools $ pip install --user $ pip install --user
# module # module >>> import etsy >>> import etsy
# distribution # distribution $ pip install --user python-etsy $ pip install --user python-etsy # tools # tools $ pip install --user $ pip install --user # no sudo, no virtualenv # no sudo, no virtualenv
None
$ pip install --user etsy $ pip install --user etsy
$ pip install --user etsy $ pip install --user etsy
ValueError: Invalid IPv6 URL ValueError: Invalid IPv6 URL
PyPI: PyPI: Wrong or missing Wrong or missing download URLs
download URLs
PyPI: PyPI: Wrong or missing no Wrong or missing no
download URLs verification download URLs verification
PyPI: PyPI: Wrong or missing no Wrong or missing no
download URLs verification download URLs verification (fixed w/ pip 1.5) (remains) (fixed w/ pip 1.5) (remains)
pip: pip: under python 3.2: under python 3.2: $ pip
install --user jinja2 $ pip install --user jinja2 Downloading/unpacking jinja2 Downloading/unpacking jinja2
pip: pip: under python 3.2: under python 3.2: $ pip
install --user jinja2 $ pip install --user jinja2 Downloading/unpacking jinja2 Downloading/unpacking jinja2 # ... # ...
File "jinja2/runtime.py", File "jinja2/runtime.py", line 44 line 44 SyntaxError: invalid
syntax SyntaxError: invalid syntax
File "jinja2/runtime.py", File "jinja2/runtime.py", line 44 line 44 SyntaxError: invalid
syntax SyntaxError: invalid syntax Successfully installed jinja2 Successfully installed jinja2 Cleaning up... Cleaning up...
>>> import jinja2 >>> import jinja2
>>> import jinja2 >>> import jinja2 File File "…/jinja2/environment.py", line
"…/jinja2/environment.py", line 639 639 u'...'.encode('iso-8859-15') u'...'.encode('iso-8859-15') ^ ^ SyntaxError: invalid syntax SyntaxError: invalid syntax
Uninstallation
$ python >>> import etsy
$ python >>> import etsy $ pip uninstall etsy Cannot
uninstall requirement etsy, not installed
$ python >>> import etsy $ pip uninstall etsy Cannot
uninstall requirement etsy, not installed $ pip uninstall python-etsy
.../site-packages/ .../site-packages/ python_etsy*.egg-info/ python_etsy*.egg-info/ PKG-DATA PKG-DATA
.../site-packages/ .../site-packages/ python_etsy*.{dist,egg}-info/ python_etsy*.{dist,egg}-info/ {METADATA,PKG-INFO} {METADATA,PKG-INFO}
.../site-packages/ .../site-packages/ python_etsy*.{dist,egg}-info/ python_etsy*.{dist,egg}-info/ {METADATA,PKG-INFO} {METADATA,PKG-INFO} Name: python-etsy Name: python-etsy
Version: 0.1.2 Version: 0.1.2 Summary: Python wrapper for the Summary: Python wrapper for the Etsy api Etsy api
$ pip install --user python-etsy $ pip install --user python-etsy
# ... # ... Running setup.py egg_info Running setup.py egg_info for package python-etsy for package python-etsy
$ pip install --user python-etsy $ pip install --user python-etsy
# ... # ... Running Running setup.py egg_info setup.py egg_info for package python-etsy for package python-etsy
Installation of pip
$ pip pip: Command not found.
$ pip pip: Command not found. $ # download get-pip.py
$ pip pip: Command not found. $ # download get-pip.py
$ python get-pip.py --user
$ pip pip: Command not found. $ # download get-pip.py
$ python get-pip.py --user $ pip pip: Command not found.
$ pip pip: Command not found. $ # download get-pip.py
$ python get-pip.py --user $ pip pip: Command not found. $ PATH=~/.local/bin:$PATH
$ pip pip: Command not found. $ # download get-pip.py
$ python get-pip.py --user $ pip pip: Command not found. $ PATH=~/.local/bin:$PATH $ pip --version pip 1.5.4 from /home/me/.local/lib/python2.7/ site-packages (python 2.7)
Distributing your code
~ $ cd get-octopi
~ $ cd get-octopi ~/get-octopi $ ls octopi_getter.py
~ $ cd get-octopi ~/get-octopi $ ls octopi_getter.py # time
passes
~ $ cd get-octopi ~/get-octopi $ ls octopi_getter.py # time
passes ~/get-octopi $ ls octopi_getter.py setup.py LICENSE
$ python setup.py register running register running check Registering wikimarkup
to https://pypi.python.org/pypi
$ python setup.py register running register running check Registering wikimarkup
to https://pypi.python.org/pypi
$ python setup.py register running register running check Registering get-octopi
to https://pypi.python.org/pypi
$ python setup.py sdist upload python setup.py sdist upload running
sdist running check creating wikimarkup-1.0 creating dist Creating tar archive running upload
$ python setup.py sdist upload python setup.py sdist upload running
sdist running check creating wikimarkup-1.0 creating dist Creating tar archive running upload
$ python setup.py sdist upload python setup.py sdist upload running
sdist running check creating get-octopi-1.0 creating dist Creating tar archive running upload
$ python setup.py sdist upload python setup.py sdist upload running
sdist running check creating get-octopi-1.0 creating dist Creating tar archive running upload Submitting dist/get-octopi- 1.0.tar.gz to https://pypi.python.org/pypi
from distutils.core import setup setup( name='get-octopi', version='1.0', packages=['octopi_getter'], )
from distutils.core import setup setup( name='get-octopi', version='1.0', py_modules=['octopi_getter'], )
from distutils.core import setup if __name__ == '__main__': setup( name='get-octopi',
version='1.0', py_modules=['octopi_getter'], )
from distutils.core import setup setup( name='get-octopi', version='1.0', py_modules=['octopi_getter'], )
from distutils.core import setup setup( name='get-octopi', version='1.0', py_modules=['octopi_getter'], author='Asheesh Laroia',
email='
[email protected]
', )
>>> import octopi_getter >>> octopi_getter.main <function main at 0x7f2d64849500>
from distutils.core import setup # within setup() entry_points = {
'console_scripts': [ 'get-now = octopi_getter:main', ], },
from distutils.core import setup # within setup() entry_points = {
'console_scripts': [ 'get-now = octopi_getter:main', ], }, # finally $ pip install --user .
$ get-now $ get-now
$ get-now $ get-now get-now: Command not found. get-now: Command
not found.
$ get-now $ get-now get-now: Command not found. get-now: Command
not found. $ PATH=$PATH:~/.local/bin $ PATH=$PATH:~/.local/bin
$ get-now $ get-now
$ get-now $ get-now Logging into Etsy... Logging into Etsy...
$ get-now $ get-now Logging into Etsy... Logging into Etsy...
Identifying octopi... Identifying octopi...
$ get-now $ get-now Logging into Etsy... Logging into Etsy...
Identifying octopi... Identifying octopi... Purchasing... Purchasing...
$ get-now $ get-now Logging into Etsy... Logging into Etsy...
Identifying octopi... Identifying octopi... Purchasing... Purchasing... Purchased. You spent $325.21. Purchased. You spent $325.21.
$ get-now $ get-now
$ get-now $ get-now ImportError: No module named ImportError: No
module named etsy etsy
from distutils.core import setup setup( name='get-octopi', version='1.0', py_modules=['octopi_getter'], )
from distutils.core import setup setup( name='get-octopi', version='1.0', py_modules=['octopi_getter'], install_requires=[ 'python-etsy',
], )
zc.buildout vs requirements.txt vs setup( install_requires=[ 'python-etsy', ], )
Developing your code
$ pip install --user .
$ pip install --user . $ python >>> import octopi_getter
>>> octopi_getter <module ... from '.../site- packages/octopi_getter.pyc'>
$ pip install --user --editable . # aka setup.py develop
--user $ python >>> import octopi_getter >>> octopi_getter <module ... from '/home/me/ get-octopi/octopi_getter.pyc'>
$ pip install --user --editable . # aka setup.py develop
--user $ python >>> import octopi_getter >>> octopi_getter <module ... from '/home/me/ get-octopi/octopi_getter.pyc'>
from distutils.core import setup from setuptools import setup from distribute
import setup
from distutils.core import setup from setuptools import setup from distribute
import setup
from distutils.core import setup ## safe and featureless from setuptools
import setup ## pip provides this for free from distribute import setup
from distutils.core import setup setup( name='get-octopi', version='1.0', py_modules=['octopi_getter'], install_requires=[ 'python-etsy>0.1.1',
], )
$ pip install --user --editable . # ... CONFLICT
$ pip install --user --editable . # ... CONFLICT $
virtualenv . New python executable in ./bin/python Installing setuptools, pip...done. $ source bin/activate (get-octopi) $
$ pip install --user --editable . # ... CONFLICT $
virtualenv . New python executable in ./bin/python Installing setuptools, pip...done. $ source bin/activate (get-octopi) $ pip install --editable .
$ pip install --user --editable . # ... CONFLICT $
virtualenv . New python executable in ./bin/python Installing setuptools, pip...done. $ source bin/activate (get-octopi) $ pip install -e .
(get-octopi) $ pip install (get-octopi) $ pip install --user --editable
. --user --editable .
(get-octopi) $ pip install (get-octopi) $ pip install --user --editable
. --user --editable . Can not perform a '--user' Can not perform a '--user' install. User site-packages are install. User site-packages are not visible in this virtualenv. not visible in this virtualenv.
(get-octopi) $ (get-octopi) $
(get-octopi) $ (get-octopi) $ (new terminal window) (new terminal window)
$ $
(get-octopi) $ pip install lxml unable to execute 'x86_64-linux-gnu- gcc':
No such file or directory error: command 'x86_64-linux-gnu- gcc' failed with exit status 1
$ sudo apt-get install python-lxml $ python >>> import lxml
>>> $ pip install lxml Requirement already satisfied (use --upgrade to upgrade): lxml in /usr/lib/python2.7/dist-packages Cleaning up...
$ sudo apt-get install python-lxml $ python >>> import lxml
>>> $ source bin/activate (get-octopi) $ python >>> import lxml ImportError: No module called lxml.
$ sudo apt-get install python-lxml $ python >>> import lxml
>>> $ source bin/activate (get-octopi) $ python >>> import lxml ImportError: No module called lxml $ sudo apt-get build-dep python-lxml
None
Vagrant: 150MB VirtualBox: 102MB precise32.box: 300MB
Vagrant: 150MB VirtualBox: 102MB precise32.box: 300MB 1.5 hours @ 100KB/s
Vagrant: 150MB VirtualBox: 102MB precise32.box: 300MB 1.5 hours @ 100KB/s
$ vagrant provision
new engineers
new engineers new contributors
new engineers new contributors save your self
openhatch/ oh-mainline django in 5 min
- no virtualenv
- no virtualenv - no pip install
- no virtualenv - no pip install - no C
compiler
- no virtualenv - no pip install - no C
compiler - purely sqlite
# No compiler, no problem # Load Python Imaging Library
import Image
# No compiler, no problem # Load Python Imaging Library
try: import Image except:
# No compiler, no problem # Load Python Imaging Library
try: import Image except: import sys sys.modules['Image'] = ( sys.modules['sys'])
# No compiler, no problem # Load Python Imaging Library
try: import Image except: # beloved Django ImageField import sys sys.modules['Image'] = ( sys.modules['sys'])
# No compiler, no problem @skipIf(base.depends.Image is None) def test():
# ...
# No virtualenv vendor/
# No virtualenv vendor/ >>> sys.path.append(...)
# No virtualenv vendor/ >>> sys.path.append(...) search for: [kitsune vendor
library]
# settings.py DATABASES = { 'default': { 'NAME': 'site.db', 'ENGINE':
'sqlite3', }, }
# settings.py DATABASES = { 'default': { 'NAME': 'site.db', 'ENGINE':
'sqlite3', }, } if os.environ.get('USE_MYSQL', ''): DATABASES['default'] = ( OTHER_DATABASES['mysql'])
<openhatch_jenkins> Make sure the install instructions work (daily) build #230:
SUCCESS in 2 min 51 sec
<openhatch_jenkins> Make sure the install instructions work (daily) build #230:
SUCCESS in 2 min 51 sec + humans
$ time pip install twisted 41.277s total
$ time pip install twisted 41.277s total $ time pip
install twisted 5.653s total
$ time pip install twisted 41.277s total $ time pip
install twisted 5.653s total PIP_DOWNLOAD_CACHE PIP_FIND_LINKS PIP_USE_WHEEL PIP_WHEEL_DIR
$ time pip install twisted 41.277s total $ time pip
install twisted 5.653s total http://pip2014.com/
O WHEELY also conda pypi-install dh-virtualenv
Goals 1. Be able to install 2. Be able to
distribute 3. Know how to learn more
asheesh.org/scratch/Preso packaging.python.org pip2014.com Stick around for coderanger! asheesh.org @asheeshlaroia
(apologies & thanks) asheesh.org/scratch/Preso packaging.python.org pip2014.com Stick around for coderanger!
asheesh.org @asheeshlaroia
(apologies & thanks) asheesh.org/scratch/Preso packaging.python.org glyph.im/pip Stick around for coderanger!
asheesh.org @asheeshlaroia