Skip to content

Commit

Permalink
Fix: prepare lesson 2 for bug bash
Browse files Browse the repository at this point in the history
  • Loading branch information
lwasser committed Dec 6, 2023
1 parent 6011ff6 commit 6291794
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Use a pyproject.toml file for your package configuration & metadata

:::{admonition} TODOs for this page
<!-- :::{admonition} TODOs for this page
:class: important
what's missing
- missing explanation of `requires-python =` in this page -- discussed in slack with pradyun --
:::
::: -->

:::{admonition} Important pyproject.toml take aways
:class: todo
Expand Down
100 changes: 42 additions & 58 deletions tutorials/1-installable-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
The first step in creating a Python package based on code that you
have is to make that code pip installable. You will learn how to make
your code pip installable in this lesson.
<!-- TODO: make sure it's clear where they add commands!! bash vs python

Bash vs zsh it's different
<!--
TODO: is it clear where to add commands!! bash vs. python console
Bash vs zsh is different
does this work on windows and mac? i know it works on mac/linux
-->

:::{figure-md} code-to-script

<img src="../images/tutorials/code-to-script-diagram.png" alt="Diagram showing .. more here if this stays." width="700px">
<img src="../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">

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
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.
:::

:::{admonition} Learning Objectives
Expand All @@ -38,9 +41,9 @@ you are a scientist, we suggest that you use `conda`.

:::{figure-md} packages-environment

<img src="../images/tutorials/environment-package-install.png" alt="Diagram showing .. more here if this stays." width="700px">
<img src="../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">

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.
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`.
:::

## Make a basic Python package
Expand Down Expand Up @@ -111,10 +114,10 @@ The **pyproject.toml** file is:

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:

- The build-backend that you want to use,
- The project name and version.
- The `build-backend` that you want to use,
- The project `name` and `version`.

:::{admonition} pro tip
:::{admonition} Why the pyproject.toml file is important
:class: tip

The `pyproject.toml` file replaces some of the functionality of both the setup.py file and setup.cfg files.
Expand Down Expand Up @@ -168,10 +171,18 @@ If you don't have code already and are just learning how to
create a Python
package, then create an empty `add_numbers.py` file.

:::{admonition} pro tip
:::{admonition} Python modules and the __init__.py file
:class: tip

When you see the word module, we are referring to a `.py` file containing Python code.
When you see the word module, we are referring to a `.py` file containing Python
code.

The _init_.py allows Python to recognize that a directory contains at least one
module that may be imported and used in your code. A package can have multiple
modules.

[Learn more about Python packages and modules in the python documentation.](https://docs.python.org/3/tutorial/modules.html#packages )

:::

```
Expand Down Expand Up @@ -227,12 +238,8 @@ def add_num(a: int, b: int) -> int:
Next, you will add some metadata (information) to your `pyproject.toml` file. You are
are welcome to copy the file we have in our example repo here.

<!--
# TODO: add link to repo when it's ready
# below: add links to the packaging guide for build tools etc etc... -->

#### A brief overview of the TOML file
:::{admonition} Brief overview of the TOML file
:class: tip

The TOML format consists of tables and variables. Tables are sections of information denoted by square brackets:

Expand All @@ -257,6 +264,9 @@ requires = ["hatchling"]
build-backend = "hatchling.build"
```

[Learn more about the pyproject.toml format here.](../package-structure-code/pyproject-toml-python-package-metadata)
:::

- Open up your `pyproject.toml` file in your favorite text editor.
- Add the metadata below to your `pyproject.toml`

Expand Down Expand Up @@ -297,9 +307,6 @@ You are now ready to install (and build) your Python package!

Let’s try it out.

<!--
NOTE: just in case we may want to include the bash lessons here?? -->

- First open bash and `cd` into your package directory
- 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).
- Finally run `python -m pip install -e .`
Expand Down Expand Up @@ -330,8 +337,6 @@ Obtaining file:///Users/leahawasser/Documents/GitHub/pyos/pyosPackage
Let's break down `pip install -e .`
`pip install -e .` installs your package into the current active
Python environment in **editable mode** (`-e`). Installing your package in
editable mode, allows you to work on your code and then test the updates
Expand All @@ -342,10 +347,11 @@ mode) you can use:
- `python -m pip install . `
:::{admonition} Using `python -m` when calling `pip`
:class: tip
**Using `python -m` when calling `pip`**
Above, you use`python -m` to call the version of pip installed into your current active environment.
Above, you use`python -m` to call the version of pip installed into your
current active environment. `python -m` is important to ensure that you are
calling the version of pip installed in your current environment.
:::
#### Look for pyospackage in your environment
Expand Down Expand Up @@ -399,9 +405,15 @@ Type "help", "copyright", "credits" or "license" for more information.
3
```
## OPTIONAL: Customize access to Python functions using the `__init__.py` file
<!-- As you review - please tell me what you think about the section below.
There were some various opinions on whether to surface specific functionality
in a package. i've found it useful in my work when done thoughtfully.
<!-- > 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... -->
But for beginners it could create more confusion if we don't provide
specific use-cases for doing this. Thoughts? -->
## OPTIONAL: Customize access to Python functions using the `__init__.py` file
Let's make one more tweak to the code.
Expand Down Expand Up @@ -442,44 +454,16 @@ The decision to add specific functions, methods or classes to your
considering what functionality in your package you want to "elevate" to the top
level vs. what makes the most sense to keep in individual modules.
:::{important}
TODO: We had a bit of discussion in slack about this and i'd like to
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...
> TODO: Guidelines for when and how to add methods and such to the `__init__.py` file here.
> `__all__ = ['add_num']`
:::
### Congratulations! You created (the beginning of) your first Python package
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.
In the upcoming lessons you will:
* add a [README file](2-add-readme.md) and [LICENSE ](4-add-license-file.md) to your package
* Add a [README file](2-add-readme.md) and [LICENSE ](4-add-license-file.md) to your package
* [Add more metadata to your `pyproject.toml`](5-pyproject-toml.md) file to support PyPI publication.
* [Learn how to build your your package distribution](6-publish-pypi.md) files (**sdist** and **wheel**) and
publish to **test PyPI**.
* Finally you will learn how to publish to conda-forge from PyPI.
* [Learn how to build your your package distribution](6-publish-pypi.md) files (**sdist** and **wheel**) and publish to **test PyPI**.
* Finally you will learn how to publish to **conda-forge** from **PyPI**.
If you have a package that is ready for the mainstream user then
you can also publish your package on PyPI.
<!--
### Lesson TODOs ###
- Make sure they are using the clean dev envt (i think that is mentioned)
- 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>
TODO: don't forget to have them add /dist to their .gitignore ...
https://hatch.pypa.io/latest/intro/#existing-project <- hatch will migrate from setup.py for you >
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.
- https://docs.python.org/3/tutorial/modules.html#packages -< link to this docs...>
- 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
-->
7 changes: 7 additions & 0 deletions tutorials/6-publish-pypi.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ TODO: Go back to pyproj toml lesson and add a dev dependencies section with buil
`pip install build`
-->

<!--
### Lesson TODOs ###
TODO: don't forget to have them add /dist to their .gitignore ...
https://hatch.pypa.io/latest/intro/#existing-project <- hatch will migrate from setup.py for you >
-->

In the previous lessons, you've learned:

Expand Down

0 comments on commit 6291794

Please sign in to comment.