17. Layout
Can depend on distribution mechanism:
● Single file
● Zip file
– Python entry point
– Splat/run
● System package
● PyPi/Distribute/pip package
18. Single File
● chmod and place in $PATH
● add #!/usr/bin/env python
55. Example
>>> import sys
>>> def parse(fin):
... for line in upper(fin):
... sys.stdout.write(line)
>>> def upper(iterable):
... for item in iterable:
... yield str(item).upper()
56. Create file to parse
>>> with open('/tmp/data', 'w')
as fout:
... fout.write('line1n ')
... fout.write('line2n ')
57. Filename to file
>>> filename = '/tmp/data'
>>> with open(filename) as fin:
... parse(fin)
LINE1
LINE2
58. String data to file
>>> data = "stringn datan "
>>> import StringIO
>>>
parse(StringIO.StringIO(data))
STRING
DATA
66. Chaining scripts and python
cat 0-2, add 10 to them (in python) and wc
-l results.
>>> import os
>>> p5 = subprocess.Popen('cat', shell=True,
stdout=subprocess.PIPE, stdin=subprocess.PIPE, close_fds=True)
>>> def p6(input):
... ''' add 10 to line in input '''
... for line in input:
... yield '%d%s ' %(int(line.strip())+10, os.linesep)
67. Chaining scripts and python
(2)
>>> p7 = subprocess.Popen('wc -l', shell=True,
stdout=subprocess.PIPE, stdin=subprocess.PIPE, close_fds=True)
>>> [p5.stdin.write(str(x)+os.linesep) for x in xrange(3)]
>>> p5.stdin.close()
>>> [p7.stdin.write(x) for x in p6(p5.stdout.xreadlines())]
>>> p7.stdin.close()
>>> p7.stdout.read()
'3n'
109. Licensing
Some include dunder meta in project docstring (requests
__init__.py):
:copyright: (c) 2013 by Kenneth Reitz.
:license: Apache 2.0, see LICENSE for more
details.
(note IANAL)
110. Licensing (2)
Some include dunder meta in project (requests
__init__.py):
__title__ = 'requests'
__version__ = '1.1.0'
__build__ = 0x010100
__author__ = 'Kenneth Reitz'
__license__ = 'Apache 2.0'
__copyright__ = 'Copyright 2013 Kenneth Reitz'
(note IANAL)
113. End User Docs
Sphinx is a tool that makes it easy to create
intelligent and beautiful documentation,
written by Georg Brandl and licensed
under the BSD license.
http://sphinx-doc.org
129. Makefile (7)
Since clean isn't a file, need to use .PHONY
to indicate that to make. (If you had a file
named clean it wouldn't try to build it).
130. Makefile (8)
(Simply Expanded) Variables (expanded when set):
BIN := env/bin
PY := $(BIN)/python
NOSE := $(BIN)/nosetests
.PHONY: build
build: env
<TAB>$(PY) setup.py sdist
131. Makefile (9)
(Recursively Expanded) Variables (expanded when used):
FILE = foo
DATA = $(FILE)
# If DATA expanded would be foo
FILE = bar
# If DATA expanded would be bar
144. Inspired by Rick Harding's
Talk
http://pyvideo.org/video/1354/starting-you
r-project-right-setup-and-automation
https://github.com/mitechie/pyohio_2012
146. Makefile for Python (2)
Make dependencies:
.PHONY: deps
deps: env
<TAB>$(PIP) install -r
requirements.txt
147. Makefile for Python (3)
Testing with nose:
.PHONY: test
test: nose deps
<TAB>$(NOSE)
# nose depends on the nosetests binary
nose: $(NOSE)
$(NOSE): env
<TAB>$(PIP) install nose
148. Contrary Opinions
“Dynamic languages don't need anything
like make, unless they have some
compile-time interface dependencies
between modules”
http://stackoverflow.com/questions/758093
9/why-are-there-no-makefiles-for-automati
on-in-python-projects
159. setup.py non-Python files
● add files to MANIFEST.in (include in
package)
● add files to package_data in setup.py
(include in install) Not recursive
160. MANIFEST.in language
● include|exclude pat1 pat2 ...
● recursive-(include|exclude) dir pat1 pat2 ...
● global-(include|exclude) dir pat1 pat2 ...
● prune dir
● graft dir
http://docs.python.org/release/1.6/dist/sdist-cmd.html#sdist-c
md
166. PyPi Upload (2)
$ python setup.py sdist register upload
...
Creating tar archive
removing 'rst2odp-0.2.4' (and everything under it)
running register
running check
We need to know who you are, so please choose either:
1. use your existing login,
2. register as a new user,
3. have the server generate a new password for you (and email it to you),
or
4. quit
Your selection [default 1]:
1
167. PyPi Upload (3)
Username: mharrison
Password:
Registering rst2odp to http://pypi.python.org/pypi
Server response (200): OK
I can store your PyPI login so future submissions will be faster.
(the login will be stored in /home/matt/.pypirc)
Save your login (y/N)?y
running upload
Submitting dist/rst2odp-0.2.4.tar.gz to http://pypi.python.org/pypi
Server response (200): OK
168. PyPi Note
Though PyPi packages are signed there is
no verification step during package
installation
175. Testing (3)
Use nose to run:
$ env/bin/nosetests
..
-------------
Ran 2 tests in 0.007s
OK
176. Testing (4)
Makefile integration:
NOSE := env/bin/nosetests
# --------- Testing ----------
.PHONY: test
test: nose deps
<TAB>$(NOSE)
# nose depends on the nosetests binary
nose: $(NOSE)
$(NOSE): env
<TAB>$(PIP) install nose