Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for the .python-version file #1664

Merged
merged 1 commit into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,4 @@ jobs:
- name: Run buildpack using default app fixture
run: make run
- name: Run buildpack using an app fixture that's expected to fail
run: make run FIXTURE=spec/fixtures/python_version_invalid/
run: make run FIXTURE=spec/fixtures/python_version_file_invalid_version/
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## [Unreleased]

- Added support for configuring the Python version using a `.python-version` file. Both the `3.N` and `3.N.N` version forms are supported (the former is recommended). The existing `runtime.txt` file will take precedence if both files are found, however, we recommend switching to `.python-version` since it is more commonly supported in the Python ecosystem. ([#1664](https://github.com/heroku/heroku-buildpack-python/pull/1664))
- Added support for specifying only the Python major version in `runtime.txt` instead of requiring the full Python version (for example `python-3.N` instead of `python-3.N.N`). ([#1664](https://github.com/heroku/heroku-buildpack-python/pull/1664))

## [v260] - 2024-10-10

Expand Down
107 changes: 49 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,61 +8,52 @@ This is the official [Heroku buildpack](https://devcenter.heroku.com/articles/bu

Recommended web frameworks include **Django** and **Flask**, among others. The recommended webserver is **Gunicorn**. There are no restrictions around what software can be used (as long as it's pip-installable). Web processes must bind to `$PORT`, and only the HTTP protocol is permitted for incoming connections.

See it in Action
----------------
```
$ ls
my-application requirements.txt runtime.txt
$ git push heroku main
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 276 bytes | 276.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> Installing python
remote: -----> Installing pip
remote: -----> Installing SQLite3
remote: -----> Installing requirements with pip
remote: Collecting flask (from -r /tmp/build_c2c067ef79ff14c9bf1aed6796f9ed1f/requirements.txt (line 1))
remote: Downloading ...
remote: Installing collected packages: Werkzeug, click, MarkupSafe, Jinja2, itsdangerous, flask
remote: Successfully installed Jinja2-2.10 MarkupSafe-1.1.0 Werkzeug-0.14.1 click-7.0 flask-1.0.2 itsdangerous-1.1.0
remote:
remote: -----> Discovering process types
remote: Procfile declares types -> (none)
remote:
```

A `requirements.txt` must be present at the root of your application's repository to deploy.

To specify your python version, you also need a `runtime.txt` file - unless you are using the default Python runtime version.

Current default Python Runtime: Python 3.12.7

Alternatively, you can provide a `setup.py` file, or a `Pipfile`.
Using `pipenv` will generate `runtime.txt` at build time if one of the field `python_version` or `python_full_version` is specified in the `requires` section of your `Pipfile`.

Specify a Buildpack Version
---------------------------

You can specify the latest production release of this buildpack for upcoming builds of an existing application:

$ heroku buildpacks:set heroku/python


Specify a Python Runtime
------------------------

Supported runtime options include:

- `python-3.13.0` on all [supported stacks](https://devcenter.heroku.com/articles/stack#stack-support-details)
- `python-3.12.7` on all [supported stacks](https://devcenter.heroku.com/articles/stack#stack-support-details)
- `python-3.11.10` on all [supported stacks](https://devcenter.heroku.com/articles/stack#stack-support-details)
- `python-3.10.15` on all [supported stacks](https://devcenter.heroku.com/articles/stack#stack-support-details)
- `python-3.9.20` on all [supported stacks](https://devcenter.heroku.com/articles/stack#stack-support-details)
- `python-3.8.20` on Heroku-20 only
## Getting Started

See the [Getting Started on Heroku with Python](https://devcenter.heroku.com/articles/getting-started-with-python) tutorial.

## Application Requirements

A `requirements.txt` or `Pipfile` file must be present in the root (top-level) directory of your app's source code.

## Configuration

### Python Version

We recommend that you specify a Python version for your app rather than relying on the buildpack's default Python version.

For example, to request the latest patch release of Python 3.13, create a `.python-version` file in
the root directory of your app containing:
`3.13`

The buildpack will look for a Python version in the following places (in descending order of precedence):

1. `runtime.txt` file (deprecated)
2. `.python-version` file (recommended)
3. The `python_full_version` field in the `Pipfile.lock` file
4. The `python_version` field in the `Pipfile.lock` file

If none of those are found, the buildpack will use a default Python version for the first
build of an app, and then subsequent builds of that app will be pinned to that version
unless the build cache is cleared or you request a different version.

The current default Python version is: 3.12

The supported Python versions are:

- Python 3.13
- Python 3.12
- Python 3.11
- Python 3.10

These Python versions are deprecated on Heroku:

- Python 3.9
- Python 3.8 (only available on the [Heroku-20](https://devcenter.heroku.com/articles/heroku-20-stack) stack)

Python versions older than those listed above are no longer supported, since they have reached
end-of-life [upstream](https://devguide.python.org/versions/#supported-versions).

## Documentation

For more information about using Python on Heroku, see [Dev Center](https://devcenter.heroku.com/categories/python-support).
3 changes: 3 additions & 0 deletions bin/compile
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ fi
python_version::read_requested_python_version "${BUILD_DIR}" "${package_manager}" "${cached_python_version}" requested_python_version python_version_origin
meta_set "python_version_reason" "${python_version_origin}"

# TODO: More strongly recommend specifying a Python version (eg switch the messaging to
# be a warning instead, after version resolution, and mention .python-version inline)
# TODO: Add runtime.txt deprecation warning.
case "${python_version_origin}" in
default)
puts-step "No Python version was specified. Using the buildpack default: Python ${requested_python_version}"
Expand Down
4 changes: 3 additions & 1 deletion bin/steps/python
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ PYTHON_URL="${S3_BASE_URL}/python-${python_full_version}-ubuntu-${UBUNTU_VERSION
# TODO: Update this message to be more specific once Python 3.8 support is dropped.
if ! curl --output /dev/null --silent --head --fail --retry 3 --retry-connrefused --connect-timeout 10 "${PYTHON_URL}"; then
display_error <<-EOF
Error: Python ${python_full_version} is not available for this stack (${STACK}).
Error: Python ${python_full_version} isn't available for this stack (${STACK}).
For a list of the supported Python versions, see:
https://devcenter.heroku.com/articles/python-support#supported-runtimes
Expand All @@ -35,6 +35,8 @@ function warn_if_patch_update_available() {
# Extract the patch version component of the version strings (ie: the '5' in '3.10.5').
local requested_patch_number="${requested_full_version##*.}"
local latest_patch_number="${latest_patch_version##*.}"
# TODO: Update this message to suggest using the .python-version major version syntax to stay up to date,
# once runtime.txt is deprecated and sticky-versioning only pins to the major version.
if ((requested_patch_number < latest_patch_number)); then
puts-warn
puts-warn "A Python security update is available! Upgrade as soon as possible to: Python ${latest_patch_version}"
Expand Down
Loading