Skip to content

Commit d9ed95d

Browse files
committed
Fix: edits to cleanup flow
1 parent 9f1c142 commit d9ed95d

File tree

1 file changed

+67
-57
lines changed

1 file changed

+67
-57
lines changed

tutorials/1-installable-code.md

Lines changed: 67 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ will have the bare minimum elements needed to be installable into a Python envir
1515
1. Is it clear where to add commands? bash vs. Python console
1616
Bash vs zsh is different
1717
2. Does this lesson run as expected on windows and mac?
18+
3. ADD: note about what makes something "package worthy", with a common misconception being that a package should be production-ready code that's valuable to a broad audience. this may not be a pervasive misconception in python, but a quick break-out with an explanation of what a package can consist of would be helpful.
1819
:::
1920

2021
:::{figure-md} code-to-python-package
@@ -25,27 +26,34 @@ A basic installable package needs a few things: code, a [specific package file s
2526

2627
:::
2728

28-
:::{admonition} Learning Objectives
29+
:::{admonition} About this lesson
2930
:class: tip
3031

3132
In this lesson you will learn:
3233

3334
- How to make your code installable into any Python environment both locally and from GitHub
34-
- How to create a basic `pyproject.toml` file to declare dependencies and metadata
35+
- How to create a basic `pyproject.toml` file that includes package dependencies and metadata. This file is required to make your package installable.
3536
- How to declare a [build backend](build_backends) which will be used to [build](build-package) and install your package
3637
- How to install your package in editable mode for interactive development
3738

38-
To complete this lesson you will need a local Python (development)
39-
environment. You are welcome to use any environment manager that you choose.
39+
**What you need to complete this lesson**
40+
41+
To complete this lesson you will need a local Python
42+
environment and shell on your computer.
43+
44+
You are welcome to use any Python environment manager that you choose.
45+
If you are using Windows or are not familiar with Shell, you may want to [consult the Carpentries shell lesson.](https://swcarpentry.github.io/shell-novice/). Windows users will likely need to configure a tool for any Shell and git related steps.
4046

4147
* [If you need guidance creating a Python environment, review this lesson](extras/1-create-environment.md) which walks you through creating an environment using both `venv` and `conda`.
4248
* If you aren't sure which environment manager to use and
43-
you are a scientist, we suggest that you use `conda`, particularly if you are working with any sort of spatial data.
49+
you are a scientist, we suggest that you use `conda`, particularly if you are working with spatial data.
4450

45-
In the upcoming lessons you will learn how to
51+
**What comes next**
52+
53+
In the upcoming lessons you will learn how to:
4654

4755
* Add a README file to your package to support community use
48-
* Add project metadata to your package to support PyPI publication
56+
* Add additional project metadata to your package to support PyPI publication
4957
* Publish your package to PyPI
5058
:::
5159

@@ -73,7 +81,7 @@ To make your Python code installable you need to create a specific directory str
7381
- Some code.
7482
- An `__init__.py` file in your code directory.
7583

76-
The directory structure you’ll create below looks like this:
84+
The directory structure you’ll create in this lesson will look like this:
7785

7886
```bash
7987
pyospackage/ # Your project directory
@@ -89,37 +97,25 @@ pyospackage/ # Your project directory
8997

9098
Notice a few things about the above layout:
9199

92-
1. Your package code lives within a `src/packagename` directory. We suggest that you use `src` directory as it ensures that you are running tests on the installed version of your code. However, you are welcome to instead use a [flat layout](https://www.pyopensci.org/python-package-guide/package-structure-code/python-package-structure.html#about-the-flat-python-package-layout) which does not have a src/ directory at the root. [Learn more here.](https://www.pyopensci.org/python-package-guide/package-structure-code/python-package-structure.html#the-src-layout-and-testing)
100+
1. Your package code lives within a `src/packagename` directory. We suggest that you use `src` (short for **source code**) directory as it [ensures that you are running tests on the installed version of your code](https://www.pyopensci.org/python-package-guide/package-structure-code/python-package-structure.html#the-src-layout-and-testing). However, you are welcome to instead use a [flat layout](https://www.pyopensci.org/python-package-guide/package-structure-code/python-package-structure.html#about-the-flat-python-package-layout) which does not have a `src` directory at the root.
93101
1. Within the `src` directory you have a package directory called `pyospackage`. Use the name of your package for that directory name.
94102
1. In your package directory, you have an `__init__.py` file and all of your Python modules. You will learn more about the __init__.py file below.
95103
1. The `pyproject.toml` file lives at the root directory of your package.
96104
1. The name of the root directory for the package is **pyospackage** which is the name of the package. This is not a requirement but you will often see that the GitHub / GitLab repo and the root directory name are the same as the package name.
97105

98106
### What is an __init__.py file?
99107

100-
When a directory contains an `__init__.py` file, it can be imported directly into Python.
108+
The `__init__.py` file tells Python that a directory
109+
should be treated as a Python package. As such, a directory with an `__init__.py` file can be imported
110+
directly into Python. The __init__.py file does not need
111+
to contain any code in order for Python to recognize it; it can be empty.
101112

102113
For example, following the file structure example above which has an `__init__.py` file within it, you can run:
103114

104115
```python
105116
import pyospackage
106117
```
107118

108-
The `__init__.py` file tells Python that a directory should be treated
109-
as a Python package.
110-
111-
112-
:::{admonition} The **__init__**.py file
113-
:class: tip
114-
115-
The __init__.py file does not need to contain any code, it can be
116-
empty. Since Python 3.3 came out, you can install a package without an
117-
`__init__.py` file. However, we suggest that you include empty __init__.py files in your
118-
package structure as it allows you to customize your package’s user
119-
experience.
120-
:::
121-
122-
123119
### What is a pyproject.toml file?
124120

125121
The **pyproject.toml** file is:
@@ -140,7 +136,8 @@ installable including:
140136
:::{admonition} Why the pyproject.toml file is important
141137
:class: tip
142138

143-
The `pyproject.toml` file replaces some of the functionality of both the setup.py file and setup.cfg files.
139+
The `pyproject.toml` file replaces some of the functionality of both the
140+
`setup.py` file and `setup.cfg` files.
144141
If you try to pip install a package with no `pyproject.toml` you will get the following error:
145142

146143
```bash
@@ -154,18 +151,21 @@ Neither 'setup.py' nor 'pyproject.toml' found.
154151

155152
## Time to create your Python package!
156153

157-
Now that you understand the basics of the Python package directory structure, it's time to create a Python package! Below you will create a directory structure similar to the structure described above.
154+
Now that you understand the basics of the Python package directory
155+
structure, and associated key files (`__init__.py` and `pyproject.toml`),
156+
it's time to create your Python package! Below you will create a directory
157+
structure similar to the structure described above.
158158

159-
If you don’t wish to create each of the files and directories below, you can always [fork and clone and customize the pyOpenSci example package.](https://github.com/pyOpenSci/pyosPackage)
159+
If you don’t wish to create each of the files and directories below, you
160+
can always [fork and clone and customize the pyOpenSci example package.](https://github.com/pyOpenSci/pyosPackage)
160161

161162
## Step 1: Set Up the Package Directory Structure
162163

163164
Below you create the basic directory structure required
164-
for your Python package. Note that there are instructions for creating the files and directories using shell. However you can also create files and directories in your preferred file directory tool (e.g. Finder on MAC or File Explorer on Windows) if you wish.
165+
for your Python package. Note that there are instructions for creating the files and directories using shell. However you can also create files and directories in your preferred file directory tool (e.g. Finder on MAC or File Explorer on Windows or even a tool such as VSCode or Spyder) if you wish.
165166

166-
Create a new project directory for your package. Choose a
167-
name for your package, preferably in lowercase and
168-
without spaces (e.g., "pyospackage").
167+
### Create your package's project directory structure
168+
* Create a new project directory for your package. Choose a name for your package, preferably in lowercase and without spaces. For this tutorial we'll use `pyospackage`.
169169

170170
Inside the project directory:
171171

@@ -176,12 +176,14 @@ Inside the project directory:
176176
```bash
177177
# Create a project directory in shell and a src directory within
178178
mkdir -R pyospackage/src/pyospackage
179+
179180
# Change directory into pyospackage project dir
180181
cd pyospackage
182+
181183
# View the current file structure
182184
ls
183185
```
184-
186+
### Add your `__init__.py` and `pyproject.toml` files
185187
Next create two files:
186188

187189
- Inside the package directory, create a new file named `__init__.py` . This file ensures Python sees this directory as a package. You will use this file to customize how parts of your package are imported and to declare your package’s version in a future lesson.
@@ -212,7 +214,7 @@ If you don't have code already and are just learning how to
212214
create a Python
213215
package, then create an empty `add_numbers.py` file.
214216

215-
:::{admonition} Python modules and the __init__.py file
217+
:::{admonition} Python modules and the `__init__.py` file
216218
:class: tip
217219

218220
When you see the word module, we are referring to a `.py` file containing Python
@@ -226,6 +228,7 @@ modules.
226228

227229
:::
228230

231+
Your project directory should now look like this:
229232
```
230233
pyospackage/
231234
└─ pyproject.toml
@@ -236,7 +239,7 @@ pyospackage/
236239
237240
```
238241

239-
## Step 3. Add code to your `add_numbers` module
242+
## Step 3. Add code to your `add_numbers.py` module
240243

241244
If you are following along and making a Python package from scratch then you can add the code below to your `add_numbers.py` module. The function below adds two integers together and returns the result. Notice that the code below has a few features that we will review in future tutorials:
242245

@@ -282,7 +285,7 @@ are welcome to copy the file we have in our [example pyospackage GitHub reposito
282285
:::{admonition} Brief overview of the TOML file
283286
:class: tip
284287

285-
The TOML format consists of tables and variables. Tables are sections of information denoted by square brackets:
288+
[The TOML format](https://toml.io/en/) consists of tables and variables. Tables are sections of information denoted by square brackets:
286289

287290
`[this-is-a-table]`.
288291

@@ -317,7 +320,7 @@ requires = ["hatchling"]
317320
build-backend = "hatchling.build"
318321

319322
[project]
320-
name = "pyospackage_gh_user_name" # rename this if you plan to publish to test PyPI
323+
name = "pyospackage" # rename this if you plan to publish to test PyPI
321324
# Here you add the package version manually.
322325
# You will learn how to setup dynamic versioning in a followup tutorial.
323326
version = "1.1"
@@ -349,7 +352,7 @@ You are now ready to install (and build) your Python package!
349352

350353
Let’s try it out.
351354

352-
- First open bash and `cd` into your package directory
355+
- First open your preferred shell (Windows users may be using something like gitbash) and `cd` into your project directory
353356
- 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).
354357
- Finally run `python -m pip install -e .`
355358

@@ -358,11 +361,13 @@ Let’s try it out.
358361
# Below we use conda but you can do the same thing with venv!
359362
> conda activate pyosdev
360363
(pyosdev)
361-
>> conda info
364+
> conda info
362365
active environment : pyosdev
363366
active env location : /Users/your-path/mambaforge/envs/pyosdev
364-
# Install the package
365-
>> python -m pip install -e .
367+
# Cd into your project directory
368+
> cd pyospackage
369+
# Install your package
370+
> python -m pip install -e .
366371

367372
Obtaining file:///Users/leahawasser/Documents/GitHub/pyos/pyosPackage
368373
Installing build dependencies ... done
@@ -382,7 +387,7 @@ Let's break down `pip install -e .`
382387
`pip install -e .` installs your package into the current active
383388
Python environment in **editable mode** (`-e`). Installing your package in
384389
editable mode, allows you to work on your code and then test the updates
385-
interactively in your favorite Python interface. One important caveat of editable mode is that every time you update your code, you may need to restart your Python kernel.
390+
interactively in your favorite Python interface. One important caveat of editable mode is that every time you update your code, you may need to restart Python.
386391
387392
If you wish to install the package regularly (not in editable
388393
mode) you can use:
@@ -432,7 +437,7 @@ pyosPackage 0.1.0 /Users/yourusername/path/here/pyosP
432437
433438
## 6. Test out your new package
434439
435-
After installing your package, type “python” at the command prompt to start
440+
After installing your package, type “python” at the command prompt in your chosen terminal to start
436441
a Python session in your active Python environment.
437442
438443
You can now import your package and access the `add_num` function.
@@ -446,20 +451,6 @@ Type "help", "copyright", "credits" or "license" for more information.
446451
3
447452
```
448453
449-
## Congratulations! You created your first Python package
450-
451-
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 if you want to publish your package, you have completed the first major step.
452-
453-
In the upcoming lessons you will:
454-
455-
* Add a [README file](2-add-readme.md) and [LICENSE ](4-add-license-file.md) to your package
456-
* [Add more metadata to your `pyproject.toml`](5-pyproject-toml.md) file to support PyPI publication.
457-
* [Learn how to build your your package distribution](6-publish-pypi.md) files (**sdist** and **wheel**) and publish to **test PyPI**.
458-
* Finally you will learn how to publish to **conda-forge** from **PyPI**.
459-
460-
If you have a package that is ready for the mainstream user then
461-
you can also publish your package on PyPI.
462-
463454
464455
:::{admonition} Installing packages from GitHub
465456
@@ -469,4 +460,23 @@ always install packages directly from GitHub using the syntax:
469460
```bash
470461
pip install git+https://github.com/user/repo.git@branch_or_tag
471462
```
463+
464+
To make your package github installable, you can simply:
465+
466+
1. Create a new GitHub repo
467+
2. Push the contents of the project directory that you created above, to GitHub
468+
3. Finally install the package from GitHub using the command above.
472469
:::
470+
471+
## Congratulations! You created your first Python package
472+
473+
You did it! You have now created a Python package that you can install
474+
into any Python environment. While there is still more to do if you want
475+
to publish your package, you have completed the first major step.
476+
477+
In the upcoming lessons you will:
478+
479+
* Add a [README file](2-add-readme.md) and [LICENSE](4-add-license-file.md) to your package
480+
* [Add more metadata to your `pyproject.toml`](5-pyproject-toml.md) file to support PyPI publication.
481+
* [Learn how to build your package distribution](6-publish-pypi.md) files (**sdist** and **wheel**) and publish to **test PyPI**.
482+
* Finally you will learn how to publish to **conda-forge** from **PyPI**.

0 commit comments

Comments
 (0)