diff --git a/index.md b/index.md index 164a3bec..d5080bde 100644 --- a/index.md +++ b/index.md @@ -1,5 +1,11 @@ # pyOpenSci Python Open Source Package Development Guide +```{toctree} +:hidden: +:caption: Tutorials +Tutorials +``` + ```{toctree} :hidden: :caption: Documentation diff --git a/tutorials/1-installable-code.md b/tutorials/1-installable-code.md index 03af00a7..1e51e825 100644 --- a/tutorials/1-installable-code.md +++ b/tutorials/1-installable-code.md @@ -1,21 +1,35 @@ -# Make your Python code pip installable +# Make your Python code installable -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. +In the previous lesson, you learned about both what a Python package is. You also learned about the [benefits of creating a Python +package](tutorials/intro.html#why-create-a-python-package) including: - +2. Does this lesson run as expected on windows and mac? +::: + +:::{figure-md} code-to-python-package -:::{figure-md} code-to-script +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. -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. +A basic installable package needs a few things: code, a [specific package file structure](https://www.pyopensci.org/python-package-guide/package-structure-code/python-package-structure.html) 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. -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 @@ -33,41 +47,58 @@ environment. You are welcome to use any environment manager that you choose. * [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`. * If you aren't sure which environment manager to use and -you are a scientist, we suggest that you use `conda`. +you are a scientist, we suggest that you use `conda`, particularly if you are working with any sort of spatial data. ::: -## Make your package installable + + +## Make a basic installable Python package :::{figure-md} packages-environment 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. -Making your source code pip-installable is the first step towards creating a Python package. Once your code is pip-installable, it is a Python package and can be added to any Python environment on your computer and imported in the same way that you might import a package such as `Pandas` or `Geopandas`. +Making your source code pip-installable is the first step towards creating a Python package. Once your code is pip-installable, it is a Python package and can be added to any Python environment on your computer and imported in the same way that you might import a package such as Pandas or GeoPandas. ::: -## Make a basic Python package - It’s time to create the most basic version of a Python package. -While this code can't be yet published to PyPI or conda and -is not documented, it will be installable on your computer or -anyone elses. + +What you'll be able to do with this package at the end of this lesson is: + +* Install it into any Python environment on your computer +* If you share your code with someone else on GitHub or some other file/sharing or cloud based sharing platform, others will be able to install your package too. + +While installable code is the first step towards making a Python package, there are some limitations. What you won't be able to do +by the end of this lesson is publish your package to PyPI and then conda-forge. + +The next 3 lessons in this series will teach you how to add the proper +metadata and documentation that you will need to publish to PyPI. + +:::{admonition} Installing packages from GitHub + +If you wish to share your code without publishing to PyPI you can +always install packages directly from GitHub using the syntax: + +`pip install git+https://github.com/user/repo.git@branch_or_tag`` + +::: ### What does a basic package directory structure look like? To make your code installable you need: -- A `pyproject.toml` file -- An (optional but recommended) `__init__.py` file in your code directory -- A specific directory structure +- A `pyproject.toml` file. +- A specific directory structure. - Some code. +- An `__init__.py` file in your code directory. The directory structure you’ll create in this first section looks like this: ```bash pyospackage/ └─ pyproject.toml - └─ src/ # The src directory ensures your tests always run on the installed - └── pyospackage/ # Package directory where code lives, use the package name + └─ src/ # The source (src/) directory ensures your tests always run on the installed version of your code + └── pyospackage/ # Package directory where code lives, use the package name ├── __init__.py ├── add_numbers.py └── # Add any other .py modules that you want here @@ -79,40 +110,66 @@ Below, you will learn about each element of the above package structure. Notice a few things about the above layout: -1. Your package code lives within a `src/packagename` directory. We suggest that you use `src/` directory as it ensure 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) -2. Within the `src/` directory you have a package directory called `pyospackage/`. Use the name of your package for that directory name. -3. In your package directory, you have an `__init__.py` file and all of your Python modules. -4. The `pyproject.toml` file lives at the root directory of your package. -## Init.py and pyproject.toml files +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) +1. Within the `src/` directory you have a package directory called `pyospackage/`. Use the name of your package for that directory name. +1. In your package directory, you have an `__init__.py` file and all of your Python modules. +1. The `pyproject.toml` file lives at the root directory of your package. +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. + +## __init__.py and pyproject.toml files The `__init__.py` and `pyproject.toml` files in the above layout are important to understand. More on that below. -### What is an init.py file? +### What is an __init__.py file? + +When a directory contains an `__init__.py` file, it can be imported directly into Python. + +For example, following the file structure example above which has an __init__.py file within it, you can run: + +``` +import pyospackage +``` + +The `__init__.py` file tells Python that a directory should be treated +as a Python package. + + +JEREMIAH - potentially remove init.py shortcutsl.... I'm not sure if these three points add anything for a beginner. I see a package already as organized modules, and that you get for free with an empty file. Also IIRC in slack we said that creating shortcuts in __init__.py can actually be harmful - probably not a tactic to start with. A version can go in __init__.py but also version strings as python data is a whole can of worms in python packaging. -The `__init__.py` file tells Python that the directory it’s in should be treated as a Python package. The `__init__.py` file also: - Allows you to organize multiple modules within the package. -- Allows you to create shortcuts for importing specific functions, and classes into your code (more on that later!) +- Allows you to create shortcuts for importing specific functions and classes into your code (more on that later!) - Allows you to create a version object for people to call **version** -:::{admonition} The **init**.py file +:::{admonition} The **__init__**.py file :class: tip -Since Python 3.3 came out, you can install a package without an `__init__.py` file. However, we suggest that you include it in your package structure as it allows you to customize your package’s user experience. +The __init__.py file does not need to contain any code, it can be +empty. Since Python 3.3 came out, you can install a package without an +`__init__.py` file. However, we suggest that you include empty __init__.py files in your +package structure as it allows you to customize your package’s user +experience. ::: + +> Perhaps the resolution is to be really clear that this is an overview and they'll learn more about all 3 things in later lessons? question about publication, etc + ### What is a pyproject.toml file? The **pyproject.toml** file is: -- Where you store your project’s metadata (including its name, authors, license, etc) -- Where you store dependencies (the packages that it depends on) -- Used to specify and configure what build back end you want to use to build your package distributions that are used for PyPI publication. +- Where you define your project’s metadata (including its name, authors, license, etc) +- Where you define dependencies (the packages that it depends on) +- Used to specify and configure what build back end you want to use to [build your package](../package-structure-code/python-package-distribution-files-sdist-wheel). -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: +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 a few basic items defined for the package to be +installable including: - The `build-backend` that you want to use, - The project `name` and `version`. @@ -136,7 +193,7 @@ Neither 'setup.py' nor 'pyproject.toml' found. Now that you understand the basics, it's time to create a Python package! Below you will create a directory structure similar to the structure described above. -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, here.](https://github.com/pyOpenSci/pyosPackage) +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) ### Step 1: Set Up the Package Directory Structure diff --git a/tutorials/intro.md b/tutorials/intro.md new file mode 100644 index 00000000..ff389bdb --- /dev/null +++ b/tutorials/intro.md @@ -0,0 +1,12 @@ +# Python packaging 101 + +When we merge PR 1 this file will be updated with +full content. please ignore for now it's a placeholder for the toctree + +:::{toctree} +:hidden: +:caption: Python Packaging 101 + +What is a Python package? +Make your code pip installable <1-installable-code> +:::