3
3
A project structure
4
4
====================
5
5
6
- This chapter explains a full Python project structure. What kind of directory layout
7
- you can use and how make release a software to the world.
6
+ This chapter explains a full Python project structure. What kind of directory
7
+ layout you can use and how make release a software to the world.
8
8
9
9
We will call our example project *factorial *.
10
10
::
11
11
12
- $ mkdir factorial
13
- $ cd factorial /
12
+ $ mkdir pymfactorial
13
+ $ cd pymfactorial /
14
14
15
15
Primary code
16
16
=============
17
17
18
- The name of the Python module will be *myfact *, so we will create the directory next.
18
+ The name of the Python module will be *myfact *, so we will create the directory
19
+ next.
20
+
19
21
::
20
22
21
23
$ mkdir myfact
@@ -41,12 +43,14 @@ The primary code will be in a file called *fact.py*
41
43
return -1
42
44
43
45
We also have a *__init__.py * file for the module.
46
+
44
47
::
45
48
46
49
from fact import factorial
47
50
__all__ = [factorial, ]
48
51
49
52
We also added a *README.rst * file. So, the directory structure looks like
53
+
50
54
::
51
55
52
56
$ ls
@@ -58,199 +62,233 @@ We also added a *README.rst* file. So, the directory structure looks like
58
62
MANIFEST.in
59
63
============
60
64
61
- Now we have to write a *MANIFEST.in * file which will be used to find out which all
62
- files will be part of the source tar ball of the project at the time of using *sdist * command.
65
+ Now we have to write a *MANIFEST.in * file which will be used to find out which
66
+ all files will be part of the source tar ball of the project at the time of
67
+ using *sdist * command.
68
+
63
69
::
64
70
65
71
include *.py
66
72
include README.rst
67
73
68
74
If you want to exclude some file, you can use *exclude * statements in this file.
69
75
76
+ LICENSE file
77
+ =============
78
+
79
+ Always remember to add a proper license to your project. You can take help
80
+ from `this site <https://choosealicense.com/ >`_ if you are new to software
81
+ licensing.
82
+
83
+ The following is the content of our project, which is licensed under **MIT **.
84
+
85
+ ::
86
+
87
+ MIT License
88
+
89
+ Copyright (c) 2018 Kushal Das <[email protected] >
90
+
91
+ Permission is hereby granted, free of charge, to any person obtaining a copy
92
+ of this software and associated documentation files (the "Software"), to deal
93
+ in the Software without restriction, including without limitation the rights
94
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
95
+ copies of the Software, and to permit persons to whom the Software is
96
+ furnished to do so, subject to the following conditions:
97
+
98
+ The above copyright notice and this permission notice shall be included in all
99
+ copies or substantial portions of the Software.
100
+
101
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
102
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
103
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
104
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
105
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
106
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
107
+ SOFTWARE.
108
+
109
+
70
110
Installing python-setuptools package
71
111
====================================
72
112
73
- You have to install *python-setuptools * package in your system. For this we are using
74
- a virtualenv (not showing the steps here)
113
+ You have to install *python3-setuptools * package in your system. For this we are
114
+ using a virtualenv (not showing the steps here). We will also install *wheel *
115
+ package.
75
116
117
+ ::
76
118
77
- $ pip install setuptools
119
+ $ pip install setuptools wheel
78
120
79
121
80
122
setup.py
81
123
=========
82
124
83
- Finally we have to write a *setup.py * which then can be used to create a source tarball
84
- or installing the software.
125
+ Finally we have to write a *setup.py * which then can be used to create a source
126
+ tarball or installing the software.
127
+
85
128
::
86
129
87
- #!/usr/bin/env python
130
+ #!/usr/bin/env python3
88
131
"""Factorial project"""
89
132
from setuptools import find_packages, setup
90
133
91
- setup(name = 'factorial',
134
+ with open("README.rst", "r") as fobj:
135
+ long_description = fobj.read()
136
+
137
+ setup(name = 'pymfactorial',
92
138
version = '0.1',
93
- description = "Factorial module.",
94
- long_description = "A test module for our book." ,
139
+ description = "pym Factorial module.",
140
+ long_description = long_description ,
95
141
platforms = ["Linux"],
96
142
author="Kushal Das",
97
143
98
144
url="https://pymbook.readthedocs.io/en/latest/",
99
145
license = "MIT",
100
146
packages=find_packages()
101
- )
102
- *name * is the name of the project, *version * is the release version. You can easily
103
- understand *description * and *long_description *. *platforms * is a list of the platforms
104
- this module can work on. *find_packages * is a special function which can find
105
- all modules under your source directory.
147
+ )
148
+
149
+ **name ** is the name of the project, **version ** is the release version. You can
150
+ easily understand **description ** and **long_description **. *platforms * is a
151
+ list of the platforms this module can work on. **find_packages ** is a special
152
+ function which can find all modules under your source directory.
106
153
107
154
.. note :: To learn more you can read the `packaging docs <https://packaging.python.org/en/latest/distributing.html>`_.
108
155
109
156
110
157
Usage of setup.py
111
158
==================
112
159
113
- To create a source release one execute the following command.
160
+ To create a source release and also a binary wheel for distribution, use the following
161
+ command.
162
+
114
163
::
115
164
116
- $ python setup.py sdist
165
+ $ python3 setup.py sdist bdist_wheel
117
166
running sdist
118
167
running egg_info
119
- creating factorial .egg-info
120
- writing factorial .egg-info/PKG-INFO
121
- writing top-level names to factorial .egg-info/top_level .txt
122
- writing dependency_links to factorial .egg-info/dependency_links.txt
123
- writing manifest file 'factorial .egg-info/SOURCES.txt'
124
- reading manifest file 'factorial .egg-info/SOURCES.txt'
168
+ creating pymfactorial .egg-info
169
+ writing top-level names to pymfactorial .egg-info/top_level.txt
170
+ writing dependency_links to pymfactorial .egg-info/dependency_links .txt
171
+ writing pymfactorial .egg-info/PKG-INFO
172
+ writing manifest file 'pymfactorial .egg-info/SOURCES.txt'
173
+ reading manifest file 'pymfactorial .egg-info/SOURCES.txt'
125
174
reading manifest template 'MANIFEST.in'
126
- writing manifest file 'factorial .egg-info/SOURCES.txt'
175
+ writing manifest file 'pymfactorial .egg-info/SOURCES.txt'
127
176
running check
128
- creating factorial -0.1
129
- creating factorial -0.1/factorial.egg-info
130
- creating factorial -0.1/myfact
131
- making hard links in factorial -0.1...
132
- hard linking MANIFEST.in -> factorial -0.1
133
- hard linking README.rst -> factorial -0.1
134
- hard linking setup.py -> factorial -0.1
135
- hard linking factorial.egg-info/PKG-INFO -> factorial -0.1/factorial.egg-info
136
- hard linking factorial.egg-info/SOURCES.txt -> factorial -0.1/factorial.egg-info
137
- hard linking factorial .egg-info/dependency_links.txt -> factorial -0.1/factorial .egg-info
138
- hard linking factorial .egg-info/top_level .txt -> factorial -0.1/factorial .egg-info
139
- hard linking myfact/__init__.py -> factorial -0.1/myfact
140
- hard linking myfact/fact.py -> factorial -0.1/myfact
141
- Writing factorial -0.1/setup.cfg
177
+ creating pymfactorial -0.1
178
+ creating pymfactorial -0.1/myfact
179
+ creating pymfactorial -0.1/pymfactorial.egg-info
180
+ copying files to pymfactorial -0.1...
181
+ copying MANIFEST.in -> pymfactorial -0.1
182
+ copying README.rst -> pymfactorial -0.1
183
+ copying setup.py -> pymfactorial -0.1
184
+ copying myfact/__init__.py -> pymfactorial -0.1/myfact
185
+ copying myfact/fact.py -> pymfactorial -0.1/myfact
186
+ copying pymfactorial .egg-info/PKG-INFO -> pymfactorial -0.1/pymfactorial .egg-info
187
+ copying pymfactorial .egg-info/SOURCES .txt -> pymfactorial -0.1/pymfactorial .egg-info
188
+ copying pymfactorial.egg-info/dependency_links.txt -> pymfactorial -0.1/pymfactorial.egg-info
189
+ copying pymfactorial.egg-info/top_level.txt -> pymfactorial -0.1/pymfactorial.egg-info
190
+ Writing pymfactorial -0.1/setup.cfg
142
191
creating dist
143
192
Creating tar archive
144
- removing 'factorial-0.1' (and everything under it)
145
-
146
- One can see the tarball under *dist * directory.
193
+ removing 'pymfactorial-0.1' (and everything under it)
194
+ running bdist_wheel
195
+ running build
196
+ running build_py
197
+ creating build
198
+ creating build/lib
199
+ creating build/lib/myfact
200
+ copying myfact/fact.py -> build/lib/myfact
201
+ copying myfact/__init__.py -> build/lib/myfact
202
+ warning: build_py: byte-compiling is disabled, skipping.
203
+
204
+ installing to build/bdist.linux-x86_64/wheel
205
+ running install
206
+ running install_lib
207
+ creating build/bdist.linux-x86_64
208
+ creating build/bdist.linux-x86_64/wheel
209
+ creating build/bdist.linux-x86_64/wheel/myfact
210
+ copying build/lib/myfact/fact.py -> build/bdist.linux-x86_64/wheel/myfact
211
+ copying build/lib/myfact/__init__.py -> build/bdist.linux-x86_64/wheel/myfact
212
+ warning: install_lib: byte-compiling is disabled, skipping.
213
+
214
+ running install_egg_info
215
+ Copying pymfactorial.egg-info to build/bdist.linux-x86_64/wheel/pymfactorial-0.1-py3.5.egg-info
216
+ running install_scripts
217
+ creating build/bdist.linux-x86_64/wheel/pymfactorial-0.1.dist-info/WHEEL
218
+ creating '/home/kdas/code/pym/code/factorial/dist/pymfactorial-0.1-py3-none-any.whl' and adding '.' to it
219
+ adding 'myfact/__init__.py'
220
+ adding 'myfact/fact.py'
221
+ adding 'pymfactorial-0.1.dist-info/top_level.txt'
222
+ adding 'pymfactorial-0.1.dist-info/WHEEL'
223
+ adding 'pymfactorial-0.1.dist-info/METADATA'
224
+ adding 'pymfactorial-0.1.dist-info/RECORD'
225
+ removing build/bdist.linux-x86_64/wheel
226
+
227
+ One can see the output files under *dist * directory.
147
228
::
148
229
149
230
$ ls dist/
150
- factorial-0.1.tar.gz
151
-
152
- .. note :: Remember to use a virtualenv while trying to install the code :)
153
-
154
- To install from the source use the following command.
155
- ::
231
+ pymfactorial-0.1-py3-none-any.whl pymfactorial-0.1.tar.gz
156
232
157
- $ python setup.py install
233
+ .. warning :: Remember to use a virtualenv while trying to install the code :)
158
234
159
- .. note :: To learn more, read from `packaging.python.org <https://packaging.python.org/en/latest/distributing.html>`_.
160
235
161
236
Python Package Index (PyPI)
162
237
============================
163
238
164
- Do you remember the *pip * command we are using still now? Ever thought from where those packages
165
- are coming from? The answer is `PyPI <http://pypi.python .org/pypi >`_. It is a
166
- repository of software for the Python programming language.
239
+ Do you remember the ** pip ** command we are using still now? Ever thought from
240
+ where those packages are coming from? The answer is `PyPI <http://pypi..org/ >`_.
241
+ It is a repository of software for the Python programming language.
167
242
168
- For our example, we will use the test server of PyPI which is `https://testpypi.python .org/pypi <https://testpypi.python .org/pypi >`_
243
+ For our example, we will use the test server of PyPI which is `https://test.pypi .org/ <https://test.pypi .org/ >`_
169
244
170
245
Creating account
171
246
-----------------
172
247
173
- First register yourself in `this link <https://testpypi.python.org/pypi?%3Aaction=register_form >`_. You will
174
- receive an email with a link, go to that link and confirm your registration.
248
+ First register yourself in `this link
249
+ <https://test.pypi.org/account/register/> `_. You will receive
250
+ an email with a link, go to that link and confirm your registration.
175
251
176
- .pypirc file
177
- -------------
178
252
179
- Your account details genrally stay inside a file called * .pypirc * under your home directory.
180
- The content of the file will look like
181
- ::
253
+ .. note :: Remember to change the name of the project
254
+ to something else in the ` setup.py ` to test following
255
+ instructions.
182
256
183
- [distutils]
184
- index-servers =
185
- pypi
257
+ Uploading your project
258
+ -----------------------
186
259
187
- [pypi]
188
- repository: https://testpypi.python.org/pypi
189
- username: <username>
190
- password: <password>
260
+ Now finally we can upload our project to the PyPI server using **twine ** command.
261
+ Remember that this command needs to be invoked immediately after you build the
262
+ source/binary distribution files.
191
263
192
- Replace <username> and <password> with your newly created account details .
264
+ First, we will have to install ** twine ** using ** pip ** (we are using a virtualenv) .
193
265
194
- .. note :: Remember to change the name of the project to something else in the `setup.py`to test following instructions.
266
+ ::
195
267
196
- Registering your project
197
- -------------------------
268
+ $ pip install twine
269
+ $ twine upload --repository-url https://test.pypi.org/legacy/ dist/*
270
+ Uploading distributions to https://test.pypi.org/legacy/
271
+ Enter your username: kushaldas
272
+ Enter your password:
273
+ Uploading pymfactorial-0.1-py3-none-any.whl
274
+ 100%|██████████████████████████████████████| 4.29k/4.29k [00:01<00:00, 3.77kB/s]
275
+ Uploading pymfactorial-0.1.tar.gz
276
+ 100%|██████████████████████████████████████| 3.83k/3.83k [00:00<00:00, 7.57kB/s]
198
277
199
- Next we will register our project to the PyPI service. This is done using the `register ` command. We will
200
- also use `-r ` to point it to the test server.
201
- ::
278
+ Now if you visit the `site <https://test.pypi.org/pypi/pymfactorial/ >`_, you will
279
+ find your project is ready to be used by others.
202
280
203
- $ python setup.py register -r https://testpypi.python.org/pypi
204
- running register
205
- running egg_info
206
- writing factorial.egg-info/PKG-INFO
207
- writing top-level names to factorial.egg-info/top_level.txt
208
- writing dependency_links to factorial.egg-info/dependency_links.txt
209
- reading manifest file 'factorial.egg-info/SOURCES.txt'
210
- reading manifest template 'MANIFEST.in'
211
- writing manifest file 'factorial.egg-info/SOURCES.txt'
212
- running check
213
- Registering factorial to https://testpypi.python.org/pypi
214
- Server response (200): OK
281
+ Install from the test PyPI
282
+ ===========================
215
283
216
- Uploading your project
217
- -----------------------
284
+ You can use the following command to install from the test PyPI.
218
285
219
- Now finally we can upload our project to the PyPI server using `upload ` command.
220
- Remember that this command needs to be invoked immediately after you build the source/binary
221
- distribution files.
222
286
::
223
287
224
- $ python setup.py sdist upload -r https://testpypi.python.org/pypi
225
- running sdist
226
- running egg_info
227
- writing factorial.egg-info/PKG-INFO
228
- writing top-level names to factorial.egg-info/top_level.txt
229
- writing dependency_links to factorial.egg-info/dependency_links.txt
230
- reading manifest file 'factorial.egg-info/SOURCES.txt'
231
- reading manifest template 'MANIFEST.in'
232
- writing manifest file 'factorial.egg-info/SOURCES.txt'
233
- running check
234
- creating factorial-0.1
235
- creating factorial-0.1/factorial.egg-info
236
- creating factorial-0.1/myfact
237
- making hard links in factorial-0.1...
238
- hard linking MANIFEST.in -> factorial-0.1
239
- hard linking README.rst -> factorial-0.1
240
- hard linking setup.py -> factorial-0.1
241
- hard linking factorial.egg-info/PKG-INFO -> factorial-0.1/factorial.egg-info
242
- hard linking factorial.egg-info/SOURCES.txt -> factorial-0.1/factorial.egg-info
243
- hard linking factorial.egg-info/dependency_links.txt -> factorial-0.1/factorial.egg-info
244
- hard linking factorial.egg-info/top_level.txt -> factorial-0.1/factorial.egg-info
245
- hard linking myfact/__init__.py -> factorial-0.1/myfact
246
- hard linking myfact/fact.py -> factorial-0.1/myfact
247
- Writing factorial-0.1/setup.cfg
248
- Creating tar archive
249
- removing 'factorial-0.1' (and everything under it)
250
- running upload
251
- Submitting dist/factorial-0.1.tar.gz to https://testpypi.python.org/pypi
252
- Server response (200): OK
288
+ $ pip install --index-url https://test.pypi.org/simple/ pymfactorial
253
289
254
- Now if you visit the ` site < https://testpypi.python.org/pypi/factorial/ >`_, you will find
255
- your project is ready to be used by others.
290
+ More readings
291
+ ==============
256
292
293
+ Please visit https://packaging.python.org to learn more about Python packaging.
294
+ There are many guides and tutorials available on that site.
0 commit comments