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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
750
Smart Dumpster by Bradley E. Angell
pycon2014
0
600
Software Engineering for Hackers: Bridging the Two Solitudes by Tavish Armstrong
pycon2014
0
790
Other Decks in Technology
See All in Technology
夫婦で子育てするための育児標準化
codmoninc
PRO
0
210
Conditional PED-ANOVA: Hyperparameter Importance in Hierarchical & Dynamic Search Spaces
pfn
PRO
0
130
パッチ更新でterraform initが落ちた日
grimoh
1
140
大型犬好きによるPugの紹介
yamanoku
1
150
Benchmarking Disaggregated Serving on vLLM + Dynamo with a Real Coding-Agent Workload
nttcom
1
180
スキマバイトという雇用形態は存在しないので、雇用期間1日のアルバイト契約を事業者とワーカーが結ぶ手続きを支えるのがタイミーなんです
akitoshiga
0
190
スプシの手作業からの解脱 ~更新はClaude Codeに、見せ方と使い方はGASアプリに任せる~
kentarofujii
0
150
実践! SRE × AI - ABEMA における AIOps -
tetsuya28
8
3.1k
その Valkey 使いこなしていますか?
onk
PRO
5
1.3k
初海外で注意すべきこと12選!!!安全快適なre:invent生活にするために
yuuuuuuu168
1
120
【Data Engineering Summit2026_登壇資料】医療ビッグデータ×AIエージェントを支えるデータ基盤とハーネスエンジニアリング
jmdc_presentation
0
160
Snapshot Testing in Practice: Predictable and Reliable SwiftUI Views
fespinoza
0
220
Featured
See All Featured
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
930
The Curious Case for Waylosing
cassininazir
1
570
Practical Orchestrator
shlominoach
192
12k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
How to train your dragon (web standard)
notwaldorf
96
6.9k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Test your architecture with Archunit
thirion
2
2.4k
Speed Design
sergeychernyshev
33
2.2k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
710
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
Visualization
eitanlees
153
17k
ラッコキーワード サービス紹介資料
rakko
1
5.3M
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