You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: tutorials/1-installable-code.md
+42-58Lines changed: 42 additions & 58 deletions
Original file line number
Diff line number
Diff line change
@@ -3,16 +3,19 @@
3
3
The first step in creating a Python package based on code that you
4
4
have is to make that code pip installable. You will learn how to make
5
5
your code pip installable in this lesson.
6
-
<!-- TODO: make sure it's clear where they add commands!! bash vs python
7
6
8
-
Bash vs zsh it's different
7
+
<!--
8
+
TODO: is it clear where to add commands!! bash vs. python console
9
+
10
+
Bash vs zsh is different
11
+
does this work on windows and mac? i know it works on mac/linux
9
12
-->
10
13
11
14
:::{figure-md} code-to-script
12
15
13
-
<imgsrc="../images/tutorials/code-to-script-diagram.png"alt="Diagram showing .. more here if this stays."width="700px">
16
+
<imgsrc="../images/tutorials/code-to-script-diagram.png"alt="Diagram showing the basic steps to creating an installable package. There are 4 boxes with arrows pointing towards the right. The boxes read, your code, create package structure, add metadata to pyproject.toml and pip install package."width="700px">
14
17
15
-
It might be cool to make another version of this with add license and readme file. and end with build and publish to PyPI. then after that pip install from PyPI This is just a concept - if we use change the icons to match the steps
18
+
A basic installable package needs a few things. Code, a specific package structure and a `pyproject.toml` containing your package's name and version. Once you have these items in the correct directory structure, you can pip install your package into any environment on your computer.
16
19
:::
17
20
18
21
:::{admonition} Learning Objectives
@@ -38,9 +41,9 @@ you are a scientist, we suggest that you use `conda`.
38
41
39
42
:::{figure-md} packages-environment
40
43
41
-
<imgsrc="../images/tutorials/environment-package-install.png"alt="Diagram showing .. more here if this stays."width="700px">
44
+
<imgsrc="../images/tutorials/environment-package-install.png"alt="This diagram has two smaller boxes with arrows pointing to the right to a python environment. The small boxes read your-package and pip install package. The environment box on the right reads - your python environment. It them lists your-package along with a few other core packages such as matplotlib, numpy, pandas, xarray and geopandas."width="700px">
42
45
43
-
Making your code pip installable is the first step towards creating a Python package. Once it is pip installable, you can add it to any Python environment on your computer and import that package in the same way that you might import a package such as Pandas or Geopandas.
46
+
Making your code pip installable is the first step towards creating a Python package. Once it is pip installable, you can add it to any Python environment on your computer and import that package in the same way that you might import a package such as `Pandas` or `Geopandas`.
44
47
:::
45
48
46
49
## Make a basic Python package
@@ -111,10 +114,10 @@ The **pyproject.toml** file is:
111
114
112
115
After the `__init__.py` and `pyproject.toml` files have been added, your package can be built and distributed as an installable Python package using tools such as pip. Note that the `pyproject.toml` file needs to have the a few basic items defined for it to be installable including:
113
116
114
-
- The build-backend that you want to use,
115
-
- The project name and version.
117
+
- The `build-backend` that you want to use,
118
+
- The project `name` and `version`.
116
119
117
-
:::{admonition} pro tip
120
+
:::{admonition} Why the pyproject.toml file is important
118
121
:class: tip
119
122
120
123
The `pyproject.toml` file replaces some of the functionality of both the setup.py file and setup.cfg files.
@@ -168,10 +171,18 @@ If you don't have code already and are just learning how to
168
171
create a Python
169
172
package, then create an empty `add_numbers.py` file.
170
173
171
-
:::{admonition} pro tip
174
+
:::{admonition} Python modules and the __init__.py file
172
175
:class: tip
173
176
174
-
When you see the word module, we are referring to a `.py` file containing Python code.
177
+
When you see the word module, we are referring to a `.py` file containing Python
178
+
code.
179
+
180
+
The _init_.py allows Python to recognize that a directory contains at least one
181
+
module that may be imported and used in your code. A package can have multiple
182
+
modules.
183
+
184
+
[Learn more about Python packages and modules in the python documentation.](https://docs.python.org/3/tutorial/modules.html#packages)
Next, you will add some metadata (information) to your `pyproject.toml` file. You are
228
239
are welcome to copy the file we have in our example repo here.
229
240
230
-
<!--
231
-
# TODO: add link to repo when it's ready
232
-
233
-
# below: add links to the packaging guide for build tools etc etc... -->
234
-
235
-
#### A brief overview of the TOML file
241
+
:::{admonition} Brief overview of the TOML file
242
+
:class: tip
236
243
237
244
The TOML format consists of tables and variables. Tables are sections of information denoted by square brackets:
238
245
@@ -257,6 +264,9 @@ requires = ["hatchling"]
257
264
build-backend = "hatchling.build"
258
265
```
259
266
267
+
[Learn more about the pyproject.toml format here.](../package-structure-code/pyproject-toml-python-package-metadata)
268
+
:::
269
+
260
270
- Open up your `pyproject.toml` file in your favorite text editor.
261
271
- Add the metadata below to your `pyproject.toml`
262
272
@@ -297,9 +307,6 @@ You are now ready to install (and build) your Python package!
297
307
298
308
Let’s try it out.
299
309
300
-
<!--
301
-
NOTE: just in case we may want to include the bash lessons here?? -->
302
-
303
310
- First open bash and `cd` into your package directory
304
311
- Activate the Python environment that you wish to use. If you need help with working with virtual environments [check out this lesson](extras/1-create-environment.md).
`pip install -e .` installs your package into the current active
336
341
Python environment in **editable mode** (`-e`). Installing your package in
337
342
editable mode, allows you to work on your code and then test the updates
@@ -342,10 +347,11 @@ mode) you can use:
342
347
343
348
- `python -m pip install . `
344
349
345
-
:::{admonition} Using `python -m` when calling `pip`
346
-
:class: tip
350
+
**Using `python -m` when calling `pip`**
347
351
348
-
Above, you use`python -m` to call the version of pip installed into your current active environment.
352
+
Above, you use`python -m` to call the version of pip installed into your
353
+
current active environment. `python -m` is important to ensure that you are
354
+
calling the version of pip installed in your current environment.
349
355
:::
350
356
351
357
#### Look for pyospackage in your environment
@@ -399,9 +405,15 @@ Type "help", "copyright", "credits" or "license" for more information.
399
405
3
400
406
```
401
407
402
-
## OPTIONAL: Customize access to Python functions using the `__init__.py` file
408
+
<!-- As you review - please tell me what you think about the section below.
409
+
There were some various opinions on whether to surface specific functionality
410
+
in a package. i've found it useful in my work when done thoughtfully.
403
411
404
-
<!-- > TODO: note that they may or may not understand modules etc... I have some text on this but make sure to link to that in the intro tutorials on the basics of packaging. Could this also introduce problematic behavior if users are learning and just add functions to the init file...it could... -->
412
+
But for beginners it could create more confusion if we don't provide
413
+
specific use-cases for doing this. Thoughts? -->
414
+
415
+
416
+
## OPTIONAL: Customize access to Python functions using the `__init__.py` file
405
417
406
418
Let's make one more tweak to the code.
407
419
@@ -442,44 +454,16 @@ The decision to add specific functions, methods or classes to your
442
454
considering what functionality in your package you want to "elevate" to the top
443
455
level vs. what makes the most sense to keep in individual modules.
444
456
445
-
:::{important}
446
-
447
-
TODO: We had a bit of discussion in slack about this and i'd like to
448
-
get more feedback via a review before fleshing this section out more. i'm still unclear on when this should be taught and what guidelines to provide as to when to surface functionality in a package...
449
-
> TODO: Guidelines for when and how to add methods and such to the `__init__.py` file here.
450
-
451
-
> `__all__ = ['add_num']`
452
-
453
-
:::
454
-
455
457
### Congratulations! You created (the beginning of) your first Python package
456
458
457
459
You did it! You have now created a Python package that you can install into any Python environment. While there is still more to do, you have completed the first major step.
458
460
459
461
In the upcoming lessons you will:
460
462
461
-
* add a [README file](2-add-readme.md) and [LICENSE ](4-add-license-file.md) to your package
463
+
* Add a [README file](2-add-readme.md) and [LICENSE ](4-add-license-file.md) to your package
462
464
* [Add more metadata to your `pyproject.toml`](5-pyproject-toml.md) file to support PyPI publication.
463
-
* [Learn how to build your your package distribution](6-publish-pypi.md) files (**sdist** and **wheel**) and
464
-
publish to **test PyPI**.
465
-
* Finally you will learn how to publish to conda-forge from PyPI.
465
+
* [Learn how to build your your package distribution](6-publish-pypi.md) files (**sdist** and **wheel**) and publish to **test PyPI**.
466
+
* Finally you will learn how to publish to **conda-forge** from **PyPI**.
466
467
467
468
If you have a package that is ready for the mainstream user then
468
469
you can also publish your package on PyPI.
469
-
470
-
<!--
471
-
### Lesson TODOs ###
472
-
473
-
- Make sure they are using the clean dev envt (i think that is mentioned)
474
-
- Then define **all** = [“”] to avoid issues with pylance / mypy - still unclear regarding best practices for surfacing functions / methods. it seems like doing it here could lend them to bad practices of surfacing EVERYTHING. At the same time knowing how to surface say a specific class in a package can be useful especially if it's a big package and there is one core structure that a user will use a lot. Then again calling for a module isn't that hard>
475
-
476
-
TODO: don't forget to have them add /dist to their .gitignore ...
477
-
478
-
https://hatch.pypa.io/latest/intro/#existing-project <- hatch will migrate from setup.py for you >
479
-
480
-
FROM CAROL: Probably more accurate to say that the _init_.py allows Python to recognize that the directory is a module that may be imported and used. A package can have multiple modules.
481
-
482
-
- https://docs.python.org/3/tutorial/modules.html#packages -< link to this docs...>
483
-
484
-
- i think it would be cool to have a package spectrum graphic. on the left is you just have code that you want to use, then the code can be installed, then you can build a package... etc etc so each tutorial would highlight a step across that spectrum
0 commit comments