mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-13 13:31:19 +00:00
268 lines
7.6 KiB
Markdown
268 lines
7.6 KiB
Markdown
---
|
|
stage: none
|
|
group: unassigned
|
|
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/development/development_processes/#development-guidelines-review.
|
|
title: Create a new python projects
|
|
---
|
|
|
|
When creating a new Python repository, some guidelines help keep our code standardized.
|
|
|
|
## Recommended libraries
|
|
|
|
### Development & testing
|
|
|
|
- [`pytest`](https://docs.pytest.org/): Primary testing framework for writing and running tests.
|
|
- [`pytest-cov`](https://pytest-cov.readthedocs.io/): Test coverage reporting plugin for `pytest`.
|
|
- [`black`](https://black.readthedocs.io/): Opinionated code formatter that ensures consistent code
|
|
style.
|
|
- [`flake8`](https://flake8.pycqa.org/): Linter for style enforcement.
|
|
- [`pylint`](https://pylint.pycqa.org/): Comprehensive linter for error detection and quality
|
|
enforcement.
|
|
- [`mypy`](https://mypy.readthedocs.io/): Static type checker.
|
|
- [`isort`](https://pycqa.github.io/isort/): Utility to sort imports.
|
|
|
|
### Package manager & build system
|
|
|
|
- [`poetry`](https://python-poetry.org/): Modern packaging and dependency management.
|
|
|
|
### Common utilities
|
|
|
|
- [`typer`](https://typer.tiangolo.com/): Library for building CLI applications.
|
|
- [`python-dotenv`](https://saurabh-kumar.com/python-dotenv/): Environment variable management.
|
|
- [`pydantic`](https://docs.pydantic.dev/latest/): Data validation and settings management using
|
|
Python type annotations.
|
|
- [`fastapi`](https://fastapi.tiangolo.com): Modern, high-performance web framework for building
|
|
APIs.
|
|
- [`structlog`](https://www.structlog.org/): Structured logging library.
|
|
- [`httpx`](https://docs.pydantic.dev/latest/): Asynchronous and performant HTTP client.
|
|
- [`rich`](https://rich.readthedocs.io/en/latest/): Terminal formatting library for rich text.
|
|
- [`sqlmodel`](https://sqlmodel.tiangolo.com/): Intuitive and robust ORM.
|
|
- [`tqdm`](https://github.com/tqdm/tqdm): Fast, extensible progress bar for CLI.
|
|
|
|
## Recommended folder structure
|
|
|
|
Depending on the type of project, for example, API service, CLI application or library, the folder
|
|
structure can be varied. The following structure is for a standard CLI application.
|
|
|
|
```plaintext
|
|
project_name/
|
|
├── .gitlab/ # GitLab-specific configuration
|
|
│ ├── issue_templates/ # Issue templates
|
|
│ └── merge_request_templates/ # MR templates
|
|
├── .gitlab-ci.yml # CI/CD configuration
|
|
├── project_name/ # Main package directory
|
|
│ ├── __init__.py # Package initialization
|
|
│ ├── cli.py # Command-line interface entry points
|
|
│ ├── config.py # Configuration handling
|
|
│ └── core/ # Core functionality
|
|
│ └── __init__.py
|
|
├── tests/ # Test directory
|
|
│ ├── __init__.py
|
|
│ ├── conftest.py # pytest fixtures and configuration
|
|
│ └── test_*.py # Test modules
|
|
├── docs/ # Documentation
|
|
├── scripts/ # Utility scripts
|
|
├── README.md # Project overview
|
|
├── CONTRIBUTING.md # Contribution guidelines
|
|
├── LICENSE # License information
|
|
├── pyproject.toml # Project metadata and dependencies (Poetry)
|
|
```
|
|
|
|
## Linter configuration
|
|
|
|
We should consolidate configurations into `pyproject.toml` as much as possible.
|
|
|
|
### `pyproject.toml`
|
|
|
|
```toml
|
|
[tool.black]
|
|
line-length = 120
|
|
|
|
[tool.isort]
|
|
profile = "black"
|
|
|
|
[tool.mypy]
|
|
python_version = 3.12
|
|
ignore_missing_imports = true
|
|
|
|
[tool.pylint.main]
|
|
jobs = 0
|
|
load-plugins = [
|
|
# custom plugins
|
|
]
|
|
|
|
[tool.pylint.messages_control]
|
|
enable = [
|
|
# custom plugins
|
|
]
|
|
|
|
[tool.pylint.reports]
|
|
score = "no"
|
|
```
|
|
|
|
### `setup.cfg`
|
|
|
|
```ini
|
|
[flake8]
|
|
extend-ignore = E203,E501
|
|
extend-exclude = **/__init__.py,.venv,tests
|
|
indent-size = 4
|
|
max-line-length = 120
|
|
```
|
|
|
|
## Example Makefile
|
|
|
|
```makefile
|
|
# Excerpt from project Makefile showing common targets
|
|
|
|
# lint
|
|
.PHONY: install-lint-deps
|
|
install-lint-deps:
|
|
@echo "Installing lint dependencies..."
|
|
@poetry install --only lint
|
|
|
|
.PHONY: format
|
|
format: black isort
|
|
|
|
.PHONY: black
|
|
black: install-lint-deps
|
|
@echo "Running black format..."
|
|
@poetry run black ${CI_PROJECT_DIR}
|
|
|
|
.PHONY: isort
|
|
isort: install-lint-deps
|
|
@echo "Running isort format..."
|
|
@poetry run isort ${CI_PROJECT_DIR}
|
|
|
|
.PHONY: lint
|
|
lint: flake8 check-black check-isort check-pylint check-mypy
|
|
|
|
.PHONY: flake8
|
|
flake8: install-lint-deps
|
|
@echo "Running flake8..."
|
|
@poetry run flake8 ${CI_PROJECT_DIR}
|
|
|
|
.PHONY: check-black
|
|
check-black: install-lint-deps
|
|
@echo "Running black check..."
|
|
@poetry run black --check ${CI_PROJECT_DIR}
|
|
|
|
.PHONY: check-isort
|
|
check-isort: install-lint-deps
|
|
@echo "Running isort check..."
|
|
@poetry run isort --check-only ${CI_PROJECT_DIR}
|
|
|
|
.PHONY: check-pylint
|
|
check-pylint: install-lint-deps install-test-deps
|
|
@echo "Running pylint check..."
|
|
@poetry run pylint ${CI_PROJECT_DIR}
|
|
|
|
.PHONY: check-mypy
|
|
check-mypy: install-lint-deps
|
|
@echo "Running mypy check..."
|
|
@poetry run mypy ${CI_PROJECT_DIR}
|
|
|
|
# test
|
|
.PHONY: test
|
|
test: install-test-deps
|
|
@echo "Running tests..."
|
|
@poetry run pytest
|
|
|
|
.PHONY: test-coverage
|
|
test-coverage: install-test-deps
|
|
@echo "Running tests with coverage..."
|
|
@poetry run pytest --cov=duo_workflow_service --cov=lints --cov-report term --cov-report html
|
|
```
|
|
|
|
## Example GitLab CI Configuration
|
|
|
|
```yaml
|
|
# Excerpt from .gitlab-ci.yml showing linting and testing jobs
|
|
|
|
image: python:3.13
|
|
|
|
stages:
|
|
- lint
|
|
- test
|
|
|
|
variables:
|
|
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
|
POETRY_CACHE_DIR: "$CI_PROJECT_DIR/.cache/poetry"
|
|
POETRY_VERSION: "2.1.2"
|
|
|
|
cache:
|
|
key: ${CI_COMMIT_REF_SLUG}
|
|
paths:
|
|
- $PIP_CACHE_DIR
|
|
- $POETRY_CACHE_DIR
|
|
- .venv/
|
|
|
|
# Base template for Python jobs
|
|
.poetry:
|
|
before_script:
|
|
- pip install poetry==${POETRY_VERSION}
|
|
- poetry config virtualenvs.in-project true
|
|
- poetry add --dev black isort flake8 pylint mypy pytest pytest-cov
|
|
|
|
# Linting jobs
|
|
black:
|
|
extends: .poetry
|
|
stage: lint
|
|
script:
|
|
- poetry run black --check ${CI_PROJECT_DIR}
|
|
|
|
isort:
|
|
extends: .poetry
|
|
stage: lint
|
|
script:
|
|
- poetry run isort --check-only ${CI_PROJECT_DIR}
|
|
|
|
flake8:
|
|
extends: .poetry
|
|
stage: lint
|
|
script:
|
|
- poetry run flake8 ${CI_PROJECT_DIR}
|
|
|
|
pylint:
|
|
extends: .poetry
|
|
stage: lint
|
|
script:
|
|
- poetry run pylint ${CI_PROJECT_DIR}
|
|
|
|
mypy:
|
|
extends: .poetry
|
|
stage: lint
|
|
script:
|
|
- poetry run mypy ${CI_PROJECT_DIR}
|
|
|
|
# Testing jobs
|
|
test:
|
|
extends: .poetry
|
|
stage: test
|
|
script:
|
|
- poetry run pytest --cov=duo_workflow_service --cov-report=term --cov-report=xml:coverage.xml --junitxml=junit.xml
|
|
coverage: '/TOTAL.+?(\d+\%)/'
|
|
artifacts:
|
|
when: always
|
|
reports:
|
|
junit: junit.xml
|
|
coverage_report:
|
|
coverage_format: cobertura
|
|
path: coverage.xml
|
|
```
|
|
|
|
## Adding reviewer roulette
|
|
|
|
We recommend reviewer roulette to distribute review workload across reviewers and maintainers. A pool of Python Reviewers is available
|
|
for small Python projects and can be configured following [these steps](maintainership.md#how-to-set-up-a-python-code-review-process).
|
|
|
|
To create a pool of reviewers specific to a project:
|
|
|
|
1. Follow the
|
|
[GitLab Dangerfiles instructions](https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles/-/blob/master/README.md#simple_roulette)
|
|
to add the configuration to your project.
|
|
|
|
1. Implement the
|
|
[Danger Reviewer component](https://gitlab.com/gitlab-org/components/danger-review#example) in
|
|
your GitLab CI pipeline to automatically trigger the roulette.
|