Skip to content

Python

  1. Version
    1. The version of Python used MUST be 3.10 or above
    2. Python projects SHOULD use one of the TNA base Docker images
  2. Style/linting
    1. Python code SHOULD be linted and formatted with Ruff
    2. If linted and formatted with Ruff, one of the shared Ruff configurations MUST be used as a base
    3. The maximum cyclomatic complexity of the code MUST be no larger than 20
    4. The maximum cyclomatic complexity of the code SHOULD be no larger than 12
    5. Absolute imports SHOULD be used
    6. Relative imports COULD be used for importing files within the same directory
  3. Dependencies
    1. Python dependencies SHOULD be managed using Poetry
    2. Python dependencies COULD be managed using uv
  4. Frameworks, tools and libraries
    1. Python applications MUST use one of the approved frameworks
  5. Packages
    1. Packages SHOULD be built using pip or Poetry
    2. Packages SHOULD be deployed to PyPI
    3. Packages on PyPI MUST be deployed with OIDC
    4. Packages COULD be hosted in AWS CodeArtifact
    5. Packages SHOULD use semver (see using version numbers)
  6. Security
    1. A CSP SHOULD be set up

Frameworks

Use either Flask, Django or FastAPI for your Python applications.

Framework Best choice for making
Flask Applications with a UI
Django Applications that need to work with data and databases
FastAPI RESTful JSON APIs

Application templates have been made for new projects to enable you to get started much quicker.

Tools and libraries

Some suggested tools and libraries for Python applications are:

Tool/library Use case
National Archives Python Utilities Helpful library of common functions
Wagtail Services that require a CMS
WTForms Validating form inputs from Flask applications
WhiteNoise Serving static files in production from django.contrib.staticfiles

When choosing other tools and libraries, pay close attention to the licences.

Aim to use as few libraries as possible. Using small or unnecessarily libraries widens our attack surface and slows down our build times. If in doubt, talk to a lead developer.

Linting and formatting

The National Archives uses Ruff as a Python linter and formatter.

The two published National Archives Ruff configurations available are:

  • ruff.toml - a general purpose Ruff configuration
  • ruff-strict.toml - a configuration with a stricter set of rules

Cyclomatic complexity

When using the standard ruff.toml configuration, the cyclomatic complexity of the code is set to a maximum of 20. When using ruff-strict.toml, the maximum complexity is reduced to 12.

Using the dev Docker image

The Dev Docker image comes preinstalled with Ruff as well as all the National Archives configurations.

You can use it as a drop-in replacement for the main Python image by configuring your docker-compose.yml:

services:
  app:
    build:
      context: .
      args:
        IMAGE: ghcr.io/nationalarchives/tna-python-dev
        IMAGE_TAG: preview

Now you can lint your code by running:

docker compose exec app format

Alternatively, you can simply run format inside the app container. Read more about formatting code in tna-python-dev.