Skip to main content
Version: Next

Python Best Practices

Package Management

Package and project management in Python is managed using uv. The sections below provide a brief overview of starting a new project with uv or migrating a current project into using uv.

Initializing a New Python Project

To start a new project or module, under the proper directory run uv init <name> where <name> is the name of the project or module. The init will create the <name> folder, pyproject.toml, README.md, and main.py files. It is recommended to layout the structure of the code like the image below. The src folder contains the code for the module, library, or application. The tests folder contains the unit and integration tests for the application. The bin folder contains utility scripts for building, testing, deploying or performing other utilities with the code. The deploy folder contains the infrastructure as code for deploying the project or task into AWS.

.
└── python-reference-task
├── bin
│ └── package.sh
├── Dockerfile
├── package.json
├── pyproject.toml
├── README.md
├── src
│ ├── main.py
│ └── python_reference_task
│ ├── __init__.py
│ ├── schema.py
│ └── task.py
├── deploy
│ ├── main.tf
│ ├── output.tf
│ └── variables.tf
└── tests
├── integration_tests
└── unit_tests
├── __init__.py
├── python_reference_task
│ ├── __init__.py
│ └── test_task.py
└── test_main.py

Migrating a Current Python Project

To migrate a current Python project to uv, perform the following steps.

  1. cd to the app directory.
  2. Run the uv init command to create the pyproject.toml file.
  3. Run the uv add -r requirements.txt to update the pyproject.toml and lock dependency versions in the uv.lock files.
  4. Remove the requirements.txt file as the requirements are now tracked by uv.

Updating PyProject.toml

As a minimum, the following fields in the pyproject.toml file should be filled out completely, as seen below.

  • Under project
    • name
    • version
    • description
    • readme
    • requires-python
  • Under project.urls
    • homepage
    • documentation
    • repository

Below is an example of a minimally filled out pyproject.toml file.

[project]
name = "example-app"
version = "0.0.1"
description = "This is a long description of what the app is and what it does."
readme = "README.md"
requires-python = ">=3.14"

[project.urls]
homepage = "https://github.com/nasa/cumulus/blob/master/example-app/"
documentation = "https://github.com/nasa/cumulus/blob/master/example-app/README.md"
repository = "https://github.com/nasa/cumulus.git"

Code Quality and Format

Python projects in this repo leverage ruff for code linting and formatting and mypy for type checking.

To add ruff to the project run the command uv tool install ruff. To add mypy to the project, run uv add --dev mypy

To check the quality of your code run npm run lint. To run the checks individually use the following commands.

  • Python linting - uvx ruff check .
  • Python formatting - uvx ruff format --diff .
  • Python type checking - uv run mypy $(find . -type f -name "*.py")

Configuring Ruff

The Ruff configuration found in the root pyproject.toml file contains the ruff configuration for the project. Ruff configuration can be extended or overridden using the extend feature.

Extend Feature

Use of the extend feature for ruff should generally be avoided so that the current global configuration is applied consistently everywhere. Only use the extend feature for when absolutely necessary, providing ample documentation for the deviation from the current global settings.

Configuring MyPy

The MyPy configuration can be found in the root pyproject.toml file.

Code Auditing

Python projects in this repo use uv-secure to check for code security.

To add uv-secure to the project, run the command uv tool install uv-secure.

To audit the dependencies of your code run npm run audit or uvx uv-secure. Configuration for uv-secure is found in the root pyproject.toml file.

Code Testing and Coverage

The testing framework for python projects in pytest.

To add pytest to the project run the command uv add --dev pytest pytest-cov.

To configure pytest add commandline options for pytest in the pyproject.toml file like the example seen below. More pytest options are available in the documentation. Additional options for pytest-cov are found in the pytest-cov documentation.

[tool.pytest]
minversion = "9.0"
addopts = [
"--maxfail=1",
"-ra",
"-q",
"--cov=myproject",
"--cov-report=lcov:.nyc_output"
]
testpaths = [
"tests",
]

To run pytest use the command uv run pytest.

In addition to pytest, developers should strongly consider using moto for mocking AWS services within code when using the boto3 SDK and the AWS API. The moto library is the preferred library for performing unit tests against AWS mocked services.

Code Documentation

It is expected that whenever possible the code functionality should be documented via a README that includes critical usage and development information such as inputs, outputs, internal and external dependencies, use cases, and critical development information. In addition, the README markdown file should utilize the proper template and conform with markdown quality standards.