Skip to content

Commit 4eb21e5

Browse files
committed
Fix: use hatch for workflow
1 parent 45636f7 commit 4eb21e5

File tree

4 files changed

+282
-76
lines changed

4 files changed

+282
-76
lines changed

package-structure-code/python-package-build-tools.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Python Packaging Tools
22

3-
<!-- TODO: add a small discussion on what pinning is?-->
4-
53
## Tools for building your package
64

75
There are a several different build tools that you can use to [create your Python package's _sdist_ and _wheel_ distributions](python-package-distribution-files-sdist-wheel). Below, we discuss the features,
@@ -361,7 +359,7 @@ Build your sdist and wheel distributions|✅| Hatch will build the sdist and whe
361359
362360
```
363361

364-
_\*\* There is some argument about this approach placing a burden on maintainers to create a custom build system. But others appreciate the flexibility. The Hatch build hook approach is also comparable with the features offered by PDM._
362+
_There is some argument about this approach placing a burden on maintainers to create a custom build system. But others appreciate the flexibility. The Hatch build hook approach is also comparable with the features offered by PDM._
365363

366364
### Why you might not want to use Hatch
367365

tutorials/1-installable-code.md

Lines changed: 149 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -47,26 +47,18 @@ In this lesson you will learn:
4747
**What you need to complete this lesson**
4848

4949
To complete this lesson you will need a local Python
50-
environment and shell on your computer.
50+
environment and shell on your computer. You will also need to have [Hatch installed](get-to-know-hatch).
5151

52-
You are welcome to use any Python environment manager that you choose.
5352
If you are using Windows or are not familiar with Shell, you may want to check out the Carpentries shell lesson[^shell-lesson]. Windows users will likely need to configure a tool for any Shell and git related steps.
5453

55-
:::{todo}
56-
When this lesson is published, unlink
57-
* [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`.
58-
:::
59-
60-
* If you aren't sure which environment manager to use and
61-
you are a scientist, we suggest that you use `conda`, particularly if you are working with spatial data.
62-
6354
**What comes next**
6455

6556
In the upcoming lessons you will learn how to:
6657

58+
* [Publish your package to PyPI](publish-pypi)
6759
* Add a README file to your package to support community use
6860
* Add additional project metadata to your package to support PyPI publication
69-
* Publish your package to PyPI
61+
7062
:::
7163

7264

@@ -108,7 +100,7 @@ Notice a few things about the above layout:
108100
1. Within the `src` directory you have a package directory called `pyospackage`. Use the name of your package for that directory name. This will be the name for importing your package in Python code once installed.
109101
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.
110102
1. The `pyproject.toml` file lives at the root directory of your package.
111-
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.
103+
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 repository and the root directory name are the same as the package name.
112104

113105
### What is an `__init__.py` file?
114106

@@ -158,56 +150,43 @@ Neither 'setup.py' nor 'pyproject.toml' found.
158150
## Time to create your Python package!
159151

160152
Now that you understand the basics of the Python package directory structure, and associated key files (`__init__.py` and `pyproject.toml`), it's time to create your Python package!
161-
Below you will create a directory structure similar to the structure described above.
153+
Below you will create a directory structure similar to the structure described above using Hatch.
162154

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

166156
## Step 1: Set Up the Package Directory Structure
167157

168-
Below you create the basic directory structure required for your Python package.
169-
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 macOS or File Explorer on Windows or even a tool such as VS Code or Spyder) if you wish.
170-
171-
### Create your package's project directory structure
172-
* 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`.
173-
174-
Inside the project directory:
158+
* Open your shell or preferred terminal.
159+
* cd to the location where you'd like your package directory to live. Hatch will create the package directory for you
160+
* Choose a name for your package, preferably in lowercase and without spaces. For this tutorial we'll use `pyospackage`.
175161

176-
- Create a directory called `src`
177-
- Within the `src` directory, create a directory that is named after your package. This subdirectory will contain your package’s code.
178-
- It is ok if the project directory for your package and the directory in `src` have the same name
162+
Next run:
179163

180164
```bash
181-
# Create a project directory in shell and a src directory within
182-
mkdir -p pyospackage/src/pyospackage
183-
184-
# Change directory into pyospackage project dir
185-
cd pyospackage
186-
187-
# View the current file structure
188-
ls
165+
➜ hatch new pyospackage
166+
pyospackage
167+
├── src
168+
│ └── pyospackage
169+
│ ├── __about__.py
170+
│ └── __init__.py
171+
├── LICENSE.txt
172+
├── README.md
173+
└── pyproject.toml
189174
```
190-
### Add your `__init__.py` and `pyproject.toml` files
191-
Next create two files:
192175

193-
- 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.
194-
- At the root of your project, create a file called `pyproject.toml`
195-
196-
```bash
197-
# Create a pyproject.toml file in your project directory
198-
touch pyproject.toml
199-
# Create an empty init file within your src/pyospackage directory
200-
touch src/pyospackage/__init__.py
201-
```
202176

203177
Your final project directory structure should look like this:
204178

205179
```bash
206-
pyospackage/ # This is your project directory
207-
└─ pyproject.toml
208-
└─ src/ # This is your package directory where your code lives
209-
└── pyospackage/
210-
├── __init__.py
180+
181+
pyospackage # This is your project directory
182+
├── src
183+
│ └── pyospackage # This is your package directory where your code lives
184+
│ ├── __about__.py
185+
│ └── __init__.py
186+
├── LICENSE.txt
187+
├── README.md
188+
└── pyproject.toml # this file contains package metadata
189+
211190
```
212191

213192
## Step 2: Add code to your package
@@ -240,8 +219,8 @@ pyospackage/
240219

241220
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:
242221

243-
1. It has a [numpy-style docstring](https://www.pyopensci.org/python-package-guide/documentation/write-user-documentation/document-your-code-api-docstrings.html#three-python-docstring-formats-and-why-we-like-numpy-style)
244-
2. It uses [typing](https://www.pyopensci.org/python-package-guide/documentation/write-user-documentation/document-your-code-api-docstrings.html#adding-type-hints-to-your-docstrings)
222+
1. It has a [numpy-style docstring](numpy-docstring)
223+
2. It uses [typing](type-hints)
245224

246225
Python can support many different docstrings formats depending on the documentation build system you wish to use. The most popular supported formats for documenting Python objects are NumPy Style Docstring[^numpydoc], Google Style Docstring[^googledoc], and the Epytext Style Docstrings[^epytextdoc].
247226

@@ -276,9 +255,10 @@ def add_num(a: int, b: int) -> int:
276255
return a + b
277256
```
278257

279-
## Step 4. Add metadata to your `pyproject.toml` file
258+
## Step 4. Modify metadata in your `pyproject.toml` file
280259

281-
Next, you will add some metadata (information) to your `pyproject.toml` file. You are
260+
Next, you will modify some of the metadata (information) that
261+
Hatch adds to your `pyproject.toml` file. You are
282262
are welcome to copy the file we have in our [example pyospackage GitHub repository](https://github.com/pyOpenSci/pyosPackage).
283263

284264
:::{admonition} Brief overview of the TOML file
@@ -295,44 +275,141 @@ For instance, a `build-system` table most often holds two (2) variables:
295275
[hatchling](https://pypi.org/project/hatchling/)
296276
2. `build-backend = `, which is used to define the specific build-backend name, (in this example we are using `hatchling.build`).
297277

278+
```toml
279+
# An example of the build-system table which contains two variables - requires and build-backend
280+
[build-system]
281+
requires = ["hatchling"]
282+
build-backend = "hatchling.build"
283+
```
284+
298285
TOML organizes data structures, defining relationships within a configuration
299286
file.
300287

288+
[Learn more about the pyproject.toml format here.](../package-structure-code/pyproject-toml-python-package-metadata)
289+
:::
290+
301291
:::{todo}
302292
You will learn more about the `pyproject.toml` format in the
303293
[next lesson when you add additional metadata / information to this file.](5-pyproject-toml.md)
304294
:::
305295

296+
- Open up the `pyproject.toml` file that Hatch created in your favorite text editor. Is should look something like the example below.
297+
298+
306299
```toml
307-
# An example of the build-system table which contains two variables - requires and build-backend
308300
[build-system]
309301
requires = ["hatchling"]
310302
build-backend = "hatchling.build"
303+
304+
[project]
305+
name = "pyospackage"
306+
dynamic = ["version"]
307+
description = ''
308+
readme = "README.md"
309+
requires-python = ">=3.8"
310+
license = "MIT"
311+
keywords = []
312+
authors = [
313+
{ name = "Leah Wasser", email = "[email protected]" },
314+
]
315+
classifiers = [
316+
"Development Status :: 4 - Beta",
317+
"Programming Language :: Python",
318+
"Programming Language :: Python :: 3.8",
319+
"Programming Language :: Python :: 3.9",
320+
"Programming Language :: Python :: 3.10",
321+
"Programming Language :: Python :: 3.11",
322+
"Programming Language :: Python :: 3.12",
323+
"Programming Language :: Python :: Implementation :: CPython",
324+
"Programming Language :: Python :: Implementation :: PyPy",
325+
]
326+
dependencies = []
327+
328+
[project.urls]
329+
Documentation = "https://github.com/unknown/pyospackage#readme"
330+
Issues = "https://github.com/unknown/pyospackage/issues"
331+
Source = "https://github.com/unknown/pyospackage"
332+
333+
[tool.hatch.version]
334+
path = "src/pyospackage/__about__.py"
335+
311336
```
312337

313-
[Learn more about the pyproject.toml format here.](../package-structure-code/pyproject-toml-python-package-metadata)
338+
Edit the file as follows:
339+
340+
1. Delete `dynamic = ["version"]`: This sets up dynamic versioning based on tags stored in your git commit history. We will walk through implementing this in a later lesson.
341+
2. Add `version = 0.1.0` in the place of `dynamic = ["version"]` which you just deleted. This sets up manual versioning.
342+
3. Fill in the description if it doesn't already exist.
343+
344+
```toml
345+
[project]
346+
name = "pyospackage"
347+
# dynamic = ["version"] <- replace this...
348+
version = 0.1 # with this
349+
description = 'A simple Python package that adds numbers together' # Add a description of your package if that is not already populated
350+
```
351+
352+
3. Remove the `[tool.hatch.version]` table from the bottom of the file.
353+
354+
```toml
355+
[tool.hatch.version]
356+
path = "src/pyospackage/__about__.py"
357+
```
358+
359+
:::{note}
360+
You will learn how to automate defining a package
361+
version using git tags in the version and release your package lesson.
314362
:::
315363

316-
- Open up your `pyproject.toml` file in your favorite text editor.
317-
- Add the metadata below to your `pyproject.toml`
364+
### Step 3: Adjust your project classifiers
365+
366+
Hatch by default provides a list of classifiers that define what
367+
Python versions your package supports. While this won't impact your package build, let's remove some of them that you likely don't need.
368+
369+
* Remove support for python 3.8
370+
371+
Also because we are assuming you're creating a pure Python package, you can remove the following classifiers:
372+
373+
```toml
374+
"Programming Language :: Python :: Implementation :: CPython",
375+
"Programming Language :: Python :: Implementation :: PyPy",
376+
```
377+
378+
Your new pyproject.toml file should now look something like this:
379+
318380

319381
```toml
320382
[build-system]
321383
requires = ["hatchling"]
322384
build-backend = "hatchling.build"
323385

324386
[project]
325-
name = "pyospackage" # rename this if you plan to publish to test PyPI
326-
# Here you add the package version manually.
327-
# You will learn how to setup dynamic versioning in a followup tutorial.
328-
version = "1.1.0"
387+
name = "pyospackage"
388+
version = "0.1.0"
389+
description = 'A python package that adds numbers together.'
390+
readme = "README.md"
391+
requires-python = ">=3.9"
392+
license = "MIT"
393+
keywords = []
394+
authors = [
395+
{ name = "FirstName LastName", email = "[email protected]" },
396+
]
397+
classifiers = [
398+
"Development Status :: 4 - Beta",
399+
"Programming Language :: Python",
400+
"Programming Language :: Python :: 3.9",
401+
"Programming Language :: Python :: 3.10",
402+
"Programming Language :: Python :: 3.11",
403+
"Programming Language :: Python :: 3.12",
404+
]
405+
dependencies = []
406+
407+
[project.urls]
408+
Documentation = "https://github.com/unknown/pyospackage#readme"
409+
Issues = "https://github.com/unknown/pyospackage/issues"
410+
Source = "https://github.com/unknown/pyospackage"
329411

330412
```
331-
332-
Note that above you manually add your package's version number to the
333-
`pyproject.toml` file. You will learn how to automate defining a package
334-
version using git tags in the version and release your package lesson. <ADD LINK>
335-
336413
:::{admonition} The bare minimum needed in a pyproject.toml file
337414
:class: tip
338415

@@ -352,11 +429,11 @@ At this point you should have:
352429

353430
You are now ready to install (and build) your Python package!
354431

355-
Let’s try it out.
432+
While you can do this using hatch, we are going to use pip for this lesson, so you can see how to install your tool into your preferred environment.
356433

357-
- First open your preferred shell (Windows users may be using something like gitbash) and `cd` into your project directory
434+
- First open your preferred shell (Windows users may be using something like gitbash) and `cd` into your project directory if you are not already there.
358435
- Activate the Python environment that you wish to use.
359-
- Finally run `python -m pip install -e .`
436+
- Run `python -m pip install -e .`
360437

361438
:::{todo}
362439
Add this back in when the lesson is published
@@ -484,15 +561,14 @@ pyOpenSci repository.
484561
## Congratulations! You created your first Python package
485562
486563
You did it! You have now created a Python package that you can install
487-
into any Python environment. While there is still more to do if you want
488-
to publish your package, you have completed the first major step.
564+
into any Python environment.
489565
490566
In the upcoming lessons you will:
491567
568+
* Learn how to [build and publish your Python package to (test) PyPI](publish-pypi)
492569
* Add a README file and LICENSE to your package
493570
* Add more metadata to your `pyproject.toml` file to support PyPI publication.
494-
* Learn how to build your package distribution files (**sdist** and **wheel**) and publish to **test PyPI**.
495-
* Finally you will learn how to publish to **conda-forge** from **PyPI**.
571+
* learn how to publish to **conda-forge** from **PyPI**.
496572
497573
:::{todo}
498574
This is the content with links once the links are live we can uncomment this and remove the unlinked content above!

0 commit comments

Comments
 (0)