Skip to content

Commit

Permalink
Added some structure
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosbornes committed Apr 4, 2024
1 parent 9c3b037 commit 9433b39
Show file tree
Hide file tree
Showing 34 changed files with 587 additions and 2 deletions.
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "monthly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
43 changes: 43 additions & 0 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: docs
on:
push:
branches:
- main
pull_request:
branches:
- main

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: write

jobs:
docs:
runs-on: ubuntu-latest

steps:
- name: Check out repo
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: pyproject.toml

- name: Install pip packages
run: |
pip install -r tests/requirements.txt
pip install .[docs]
- name: Build docs
run: mkdocs build
id: build_docs

- name: Rebuild and deploy docs
run: mkdocs gh-deploy --force
if: github.ref == 'refs/heads/main' && steps.build_docs.outcome == 'success'
32 changes: 32 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: release

on:
release:
types: [published]

jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install dependencies
run: |
python -m pip install build
pip install -r tests/requirements.txt
pip install -e .
- name: Build sdist
run: python -m build --sdist

- name: Publish package
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
69 changes: 69 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Docs
.cache/
docs/reference/*
*doctrees*
/site

# Python ignores
__pycache__/
*.py[cod]
*$py.class
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
pip-log.txt
pip-delete-this-directory.txt
.ipynb_checkpoints
profile_default/
ipython_config.py
.spyderproject
.spyproject

# Unit test ignores
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
.mypy_cache/
.dmypy.json
dmypy.json
.pyre/
.pytype/

# OS ignores
.DS_Store

# Editors ignores
.vscode*

# Environments
.env
.venv
venv/
env/
ENV/
env.bak/
venv.bak/
23 changes: 23 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
ci:
autoupdate_schedule: monthly
autofix_commit_msg: pre-commit auto-fixes
autoupdate_commit_msg: pre-commit autoupdate

repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.3.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-format

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/adamchainz/blacken-docs
rev: 1.16.0
hooks:
- id: blacken-docs
5 changes: 5 additions & 0 deletions .sourcery.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
github:
ignore_labels:
- sourcery-ignore
rule_settings:
python_version: "3.9"
1 change: 1 addition & 0 deletions docs/example_docs/about/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--8<-- "CHANGELOG.md"
1 change: 1 addition & 0 deletions docs/example_docs/about/conduct.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--8<-- "CODE_OF_CONDUCT.md"
5 changes: 5 additions & 0 deletions docs/example_docs/about/license.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# License

```title="LICENSE.md"
--8<-- "LICENSE.md"
```
23 changes: 23 additions & 0 deletions docs/example_docs/code/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Type Hinting

## Overview

In the sample functions provided with the template repository, you will see something like:

```
def make_array(val: float, length: int = 3) -> NDArray:
```

If you aren't familiar with [type-hinting](https://docs.python.org/3/library/typing.html), that's what the `: float`, `: int`, and `-> NDArray` are indicating. They tell the user what the expected types are for each parameter and return. They are not enforced in any way; they are merely hints (as the name suggests). It is always advisable to use type hints in your code, so get in the habit of doing so!

!!! Tip

If you have to import a given function solely for type-hinting purposes, you should put it within an [`if TYPE_CHECKING` block](https://docs.python.org/3/library/typing.html#typing.TYPE_CHECKING) (as demonstrated in `/src/template/examples/sample.py`). It will then only be imported when using a type-checking utility, reducing the overall import time of your module.

!!! Note

You do not need to touch the `py.typed` file. It is a marker that Python uses to indicate that type-hinting should be used in any programs that depend on your code.

## Type Checking

As mentioned, the type hints are just that: hints. If you want to ensure that the types are strictly adhered to across your codebase, you can use [mypy](https://mypy-lang.org/) to do so. This is a slightly more advanced tool, however, so is not something you need to worry about right now.
26 changes: 26 additions & 0 deletions docs/example_docs/code/source.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Source Code

## Adding Your Code

All source code (i.e. your various modules, functions, classes, and so on) should be placed in the `/src/<MyPackageName>` directory. A sample file named `examples/sample.py` is included here as a representative example, which you should replace.

All the code in the `src` directory can be imported now that you have installed your package.

!!! Tip

As an example, you can import and use the demonstration [template.examples.sample][] functions as follows:

```python
from MyPackageName.examples.sample import add, make_array

print(add(1, 2)) # 3
print(make_array(3, length=4)) # [3, 3, 3, 3]
```

!!! Note

For any subfolder within `src/<MyPackageName>` containing Python code, you must have an `__init__.py` file, which will tell Python that this is a module you can import.

## Docstrings

The code comments beneath each function are called docstrings. They should provide an overview of the purpose of the function, the various parameters, and the return values (if any). Here, we are using the [NumPy style](https://numpydoc.readthedocs.io/en/latest/format.html) docstrings, but you can pick a different style if you like later on.
15 changes: 15 additions & 0 deletions docs/example_docs/code/tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Testing

## Overview

Writing effective tests for your code is a crucial part of the programming process. It is the best way to ensure that changes you make to your codebase throughout the development process do not break the core functionality of your code. This may be your first time writing tests, but trust me that it is essential.

## Pytest

Put any unit tests in the `/tests` folder. A sample test (i.e. `/tests/sample/examples/test_sample.py`) is included as a representative example.

!!! Note

All your testing scripts should start with `test_` in the filename.

When you installed the package with the `[dev]` extras, you installed everything you need to run your unit tests. To run the unit tests locally, run `pytest .` in the base directory. It will let you know if any tests fail and what the reason is for each failure.
22 changes: 22 additions & 0 deletions docs/example_docs/github/commits.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Saving Your Work

There are still a few more steps left, but at this point you will want to make sure to save your work!

## Pushing Your Changes

[Commit](https://github.com/git-guides/git-commit) any changes you've made and [push](https://github.com/git-guides/git-push) them to your repository

If you are using a program like GitKraken, this will involve the following steps:

1. Save your work.
2. Recommended: make a new branch for your work (e.g. `develop`)
3. Click "Stage all changes".
4. Add a helpful commit message.
5. Commit the changes.
6. Click "push".

!!! Tip

It is advisable to make changes in a new branch rather than in `main` so that you can ensure your unit tests pass before the code is merged into the codebase.

Then go on GitHub to see your changes. Assuming you pushed your changes to a new branch, you'll likely see a message asking if you want to make a Pull Request to merge in your changes into the `main` branch.
40 changes: 40 additions & 0 deletions docs/example_docs/github/workflows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# GitHub Actions

## Workflows

The last major piece of the puzzle is GitHub Actions, which is an automated suite of workflows that run every time a commit or pull request is made. The GitHub workflows can be found in the `.github/workflows` folder.

## Tests

The `/.github/workflows/tests.yaml` file contains the workflow to have GitHub automatically run the full suite of tests on every commit and pull request. For the most basic case outlined here, you do not need to make any modifications (other than, perhaps, the desired Python versions you wish to test on).

By default, the test suite is set up to install the following packages:

```bash
pip install -r tests/requirements.txt
pip install .[dev]
```

As you can see above, it will install specific versions of the dependencies outlined in `/tests/requirements.txt`. Unlike `pyproject.toml`, you want to include specific versions here so that your test suite is reproducible.

The `/.github/dependabot.yml` file is set up such that [Dependabot](https://docs.github.com/en/code-security/getting-started/dependabot-quickstart-guide) will automatically open pull requests to update any versions in your `/tests/requirements.txt` file as they come out so that your code will always be tested on the newest releases of the various dependencies. This will ensure that your code doesn't break as dependencies update, but if it does, you will know what needs fixing.

## Documentation

The `/.github/workflows/docs.yaml` file contains the workflow to have GitHub test the build process for the documentation and deploy it (if enabled).

To have your documentation automatically deployed on a GitHub webpage:

1. Go to the settings page of your repository.
2. Click the "Pages" section under "Code and automation."
3. Select "Deploy from a branch" under "Source"
4. Set the branch to be "gh-pages" with "/ (root)" as the folder.
5. Wait a minute and refresh the page. You'll see a message that your site is live with a URL to the documentation.

![](../media/deploy_docs.png)

Once this process is done, the documentation will be live and will update with each commit.

## Release

The `/.github/workflows/release.yaml` file contains the workflow to have GitHub upload your package to PyPI every time you mint a new release on GitHub. This is a slightly more advanced topic that you can read more about at a later time, but it's there for when you need it.
17 changes: 17 additions & 0 deletions docs/example_docs/installation/install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Pip Installing

Now it's time to install your Python package! You will want to install your Python package in "editable" mode, which means you won't have to re-install your code every time you make updates to it. Additionally, you will want to install several optional dependencies (listed under the `[project.optional-dependencies]` header in `pyproject.toml`) to ensure that you can test and build the documentation for your code.

With all this in mind, you will want to run the following in the command line from the base of the package directory:

```bash
pip install -e .[dev,docs]
```

Here, the `-e` means editable mode, the `.` means the current directory, and the `[dev,docs]` means it will install the "dev" and "docs" optional dependency set listed in the `pyproject.toml` file.

!!! Tip

You should generally start from a clean Python environment, such as a new Conda environment if you are using Anaconda or one of its variants.

To make sure you installed your package successfully, open a Python console and run `import <MyPackageName>`. It should return without any errors. If there are errors, it's likely because you forgot to replace a "template" placeholder with the name of your package.
34 changes: 34 additions & 0 deletions docs/example_docs/installation/pyproject.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# pyproject.toml

The `pyproject.toml` file contains all of the necessary information on how Python will install your package.

## Metadata

There are several metadata-related fields that you will likely want to update. You should have already updated the `name` of the package in a prior step when you replaced "template" everywhere, but you will also want to change the following:

- `description`
- `license` (if you changed the default `LICENSE.md` file)
- `authors`
- `keywords`

Aside from the `name`, none of the above are strictly necessary and can be left as-is (or removed) if you are unsure.

## Dependencies

The most important fields to update are related to the dependencies: the Python packages that your own code relies on. This will ensure that they are automatically installed when installing your Python package.

The required dependencies are listed under the `[project]` header in the `dependencies` field. By default, the template repository lists `["numpy"]`. Include any dependencies you want in this list, separated by commas. This should be all the packages you import in your code that are not standard Python libraries.

!!! Tip

Not sure what dependencies you need just yet? No problem. You can come back to this later.

!!! Note

If you know a specific minimum version is needed for your code, you should set that here as well (e.g. `["numpy>=1.23.0"]`). However, only use this when it is necessary so that users aren't restricted to a given version without a valid reason.

## Python Version

If you know your code can only run on certain Python versions, you should specify that in the `requires-python` field under the `[project]` header. When in doubt, we recommend setting it to the range of [currently supported Python versions](https://devguide.python.org/versions/#versions) (specifically those with security and bugfix statuses).

You can also update the listed versions in the `classifiers` field, although this is only for informational purposes. The list of supported Python classifier fields can be found on the corresponding [PyPI page](https://pypi.org/classifiers/).
Loading

0 comments on commit 9433b39

Please sign in to comment.