Python Project Guardrails
Enforce Python-specific project standards including lockfile presence, linter configuration, and Python version requirements.
python to your lunar-config.yml:uses: github://earthly/lunar-lib/policies/python@v1.0.0
Included Guardrails
This policy includes 4 guardrails that enforce standards for your devex build and ci.
lockfile-exists
Ensures the project has a dependency lockfile (poetry.lock, Pipfile.lock, or pinned requirements.txt) for reproducible builds.
linter-configured
Ensures a Python linter is configured (ruff, flake8, or pylint). Linters catch bugs and enforce consistent code style.
min-python-version
Ensures the project uses at least the minimum required Python version. Helps maintain security and compatibility standards.
min-python-version-cicd
Ensures the Python version used in CI/CD commands meets the minimum required version for build environments.
How Guardrails Fit into Lunar
Lunar guardrails define your engineering standards as code. They evaluate data collected by integrations and produce pass/fail checks with actionable feedback.
Policies support gradual enforcement—from silent scoring to blocking PRs or deployments—letting you roll out standards at your own pace without disrupting existing workflows.
Learn How Lunar Works →Required Integrations
This policy evaluates data gathered by one or more of the following integration(s).
Make sure to enable them in your lunar-config.yml.
Configuration
Configure this policy in your lunar-config.yml.
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
min_python_version
|
Optional |
3.9
|
Minimum required Python version (e.g., "3.9", "3.11") |
min_python_version_cicd
|
Optional |
3.9
|
Minimum required Python version for CI/CD commands |
Documentation
View on GitHubPython Project Guardrails
Enforce Python-specific project standards including lockfile presence, linter configuration, and Python version requirements.
Overview
This policy validates Python projects against best practices for dependency management and project structure. It ensures projects have proper lockfiles for reproducible builds, a configured linter for code quality, and meet minimum Python version requirements in both the project and CI/CD environments.
Policies
This plugin provides the following policies (use include to select a subset):
| Policy | Description | Failure Meaning |
|---|---|---|
lockfile-exists |
Validates a lockfile exists | Missing dependency pinning |
linter-configured |
Ensures a linter is configured | No linter setup |
min-python-version |
Ensures minimum Python version | Python version too old |
min-python-version-cicd |
Ensures minimum Python version in CI/CD | CI/CD Python version too old |
Required Data
This policy reads from the following Component JSON paths:
| Path | Type | Provided By |
|---|---|---|
.lang.python |
object | python collector |
.lang.python.poetry_lock_exists |
boolean | python collector |
.lang.python.pipfile_lock_exists |
boolean | python collector |
.lang.python.linter_configured |
boolean | python collector |
.lang.python.version |
string | python collector |
.lang.python.cicd.cmds |
array | python collector |
Installation
Add to your lunar-config.yml:
policies:
- uses: github://earthly/lunar-lib/policies/python@v1.0.0
on: [python] # Or use tags like ["domain:backend"]
enforcement: report-pr
# include: [lockfile-exists, linter-configured] # Only run specific checks
with:
min_python_version: "3.9" # Minimum Python version (default: "3.9")
min_python_version_cicd: "3.9" # Minimum CI/CD Python version (default: "3.9")
Examples
Passing Example
{
"lang": {
"python": {
"version": "3.12.1",
"build_systems": ["poetry"],
"pyproject_exists": true,
"poetry_lock_exists": true,
"linter_configured": true,
"linter": "ruff",
"type_checker_configured": true,
"type_checker": "mypy"
}
}
}
Failing Example
{
"lang": {
"python": {
"version": "3.8.5",
"build_systems": ["pip"],
"requirements_txt_exists": true,
"poetry_lock_exists": false,
"pipfile_lock_exists": false,
"linter_configured": false
}
}
}
Failure messages:
"No dependency lockfile found. Use one of: poetry.lock, Pipfile.lock, or pin all versions in requirements.txt""No Python linter configured. Set up one of: Ruff, Flake8, or Pylint""Python version 3.8.5 is below minimum 3.9. Update to Python 3.9 or higher."
Remediation
lockfile-exists
- For Poetry projects: run
poetry lockto generatepoetry.lock - For Pipenv projects: run
pipenv lockto generatePipfile.lock - For pip projects: pin all versions in
requirements.txt(e.g.,flask==3.0.0)
linter-configured
- Ruff (recommended): Add
[tool.ruff]topyproject.tomlor create.ruff.toml - Flake8: Create
.flake8or add[flake8]tosetup.cfg - Pylint: Create
.pylintrc
min-python-version
- Update your project to use a newer Python version
- Update
python_requiresinsetup.pyorpyproject.toml - Update your
.python-versionfile (if using pyenv)
min-python-version-cicd
- Update your CI/CD pipeline to use a newer Python version
- For GitHub Actions: update
python-versionin your workflow - For Docker-based builds: update your base Python image version
Open Source
This policy is open source and available on GitHub. Contribute improvements, report issues, or fork it for your own use.
Common Use Cases
Explore how individual guardrails work with specific integrations.
Ready to Automate Your Standards?
See how Lunar can turn your engineering wiki, compliance docs, or postmortem action items into automated guardrails with our 100+ built-in guardrails.