Skip to main content
U.S. flag

An official website of the United States government

The .gov means it’s official.
Federal government websites often end in .gov or .mil. Before sharing sensitive information, make sure you’re on a federal government site.

The site is secure.
The https:// ensures that you are connecting to the official website and that any information you provide is encrypted and transmitted securely.

Python development guide

This is a WORK IN PROGRESS. Help us make it better by submitting an issue or joining us in the 18F only, #python channel!

This document is structured by topic; under each, we include “Standards”, “Defaults”, and “Suggestions”.

Standards are practices that have a strong consensus across TTS; they should generally be followed to ease the ATO process and make on-boarding simpler.

Defaults are safe selections that tend to be used by a large number of our projects; you may find yourself with a better or more tailored solution, however.

Suggestions contain examples that have worked well on a project or two; they're not widely used enough to be defaults, but are worth considering.


We've standardized on Python 3.x over 2.x. All new projects should begin their life in 3.x, though legacy libraries can continue to support 2.x (in addition to 3.x) through tox. When starting a Python project, select the latest Python release available on and incrementally update as new releases are issued.

When using Django, we default to starting with the most recent Long Term Support release. This will give your project the most runway of support. If a second LTS becomes available while building the project, upgrade at the earliest convenience. Devs that follow will thank you.

Otherwise, our standard practice is to use the latest release of our libraries when first installing. Security updates (as indicated by GitHub or Snyk) should be applied ASAP, but all libs should be updated at some routine interval (e.g. quarterly).

Finally, in an effort to ensure our deployments are repeatable, our code standards require all dependencies (including dependencies' dependencies) be pinned to specific versions. This should also apply to the development environment (e.g. linters, testing tools, etc.) Suggestions for implementing that include


Our standard tool for ensuring consistency across Python code bases is flake8. Its default settings are a good first step, as is using its integration with isort for import order. We suggest investigating flake8's plugin ecosystem for more functionality.

Use Black for automatic code formatting.

Using Code Climate to measure complexity scores (by way of radon) is also a reasonable default to ensure you see potentially confounding functions and classes.


The Python ecosystem is large and full of alternative solutions to similar problems. Here we document a few common use cases and the libraries we recommend when trying to solve them.

Purpose Library Conviction
Test Runner py.test Standard
Web framework Django Default
ORM Django Default
API Django Rest Framework Default
HTTP Client Requests Default
Task Queue Celery Suggestion

Type support

Python 3.5 and beyond have had partial support for static type hints. Static typing can both make code authors' intent clearer and reduce the number of bugs through static analysis. It's also notorious for slowing down the pace of prototyping and requiring a great deal of boiler-plate.

Given this state, we believe it's reasonable to default to using type annotations when they make your intent clearer (i.e. as a form of documentation). We suggest using a static analysis tool (such as mypy) to catch logic bugs, but only where it's practical. Consider a white-list of files to run against.

18F Engineering

An official website of the GSA’s Technology Transformation Services

Looking for U.S. government information and services?