Python Coding Conventions
Generally speaking, follow Pythonic coding styles and guidelines.
This document is designed to point you in the right direction and propose a few approaches to coding to maintain consistency.
Project Conventions
Projects must be designed and organized in a specific way to ensure they are both docker compatible and they will continue to function going forward. PEP-518 lays out a new project format to describe project dependencies. In addition PEP-517 describes a very-likely to pass way to handle and build project dependencies.
As part of adapting to the changing landscape we are changing from the pipenv
tool to poetry
. Pipenv no longer fits in the broader vision of how Python dependencies are managed and never provided much of a deployment vision, either.
Poetry
, on the other hand, maintains a somewhat opinioned vision of how to build and deploy Python applications and libraries both that is consistent with the future of Python (already integrates the pyproject.toml
) as well as intends to provide standardized hooks for build and deployment.
- Projects must be small and single-purposed.
- Projects should always be hosted in a git repository.
- All projects should follow the below structure replacing app with the name of the package:
.
├── app
│ ├── subpackage
│ │ ├── __init__.py
│ │ └── somefile.py
│ ├── main.py
│ └── __init__.py
└── pyproject.toml
Note that the pyproject sits one level above the actual code. This is very similar to, like, C/C++ projects or Go projects where you’d typically have your project file sitting above the source files. Ideally this should be a more familiar and considerably easier to build format.
- Any Web API service should be exposed through
FastAPI
- All developers should use
poetry
for environment creation and management. - All docker images should build from the
python-poetry
orpython-poetry-fastapi
images in Harbor - Packages should be deployed and pulled using the Azure Devops artifacts repository
- Sensitive data like passwords and users should be read out of configuration (secrets, files, environment variables) and not be checked in to source control.
Naming and Style Conventions
- Follow the style guidelines as provided in PEP8.
- For purposes of convention, prefer single quotes to double quotes in anything beyond multi-line strings.
- Any time in a project that doesn’t follow convention then follow the general conventions of that project (e.g. Overlord).
Classes vs. Modules vs. Packages
- A single file should not contain more than 1 public class
- Use classes to represent encapsulation of both behavior and state.
- Use classes as a mixin object to inject functionality in to another class.
- Use a single Module when you have a single piece of behavior.
- Use a Package to combine modules or packages based on domain.
- Avoid name-pollution by always having all python in a top-level Package.
- Favor generators, list comprehensions, and iterators over classes if it is clean to do so.
- Prefer readability and usability over dogmatic adherance to rules.
Dependency Injection
- For classes, favor mixins for dependency injection. See here for a discussion on the topic.
- For functions, pass functions as parameters (service injection).
Environment and Setup
- All packages should maintain compatibility with pip
- All python projects must be self-contained and may only rely on
pip
andpython
to run. - A library should be just installable through
poetry install {package}
- A non-docker runnable app should have a self-contained script that sets up the environment
- A docker app will not require anything special as long as it uses
python-poetry
or something based onpython-poetry
Cross Platform
- Assume python projects will be installed cross-platform.
- Always use
os
module functions to do things like path construction and file manipulation.
Type Annotations
- Functions and methods should be annotated as much as possible
Docstrings
- Docstrings are required for any code being exposed to anyone outside Atlas.
- Docstrings should be used for complex integrations with external tools.
- Docstrings are a nice to have for any internal code.