mirror of
https://github.com/kennethreitz/heroku-buildpack-python.git
synced 2026-06-05 23:10:16 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 89a49e2b37 | |||
| d39b8c19b2 | |||
| 9a24c9d17d | |||
| 29abb059b6 | |||
| eb056bc58d | |||
| 70a152bd46 | |||
| 0b580d997e | |||
| 9f63582a23 | |||
| 5f33811357 | |||
| 3bd0a0e7cc | |||
| b7c3cdb607 |
@@ -8,7 +8,7 @@ This is the official [Heroku buildpack](https://devcenter.heroku.com/articles/bu
|
|||||||
|
|
||||||
Recommended web frameworks include **Django** and **Flask**. 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.
|
Recommended web frameworks include **Django** and **Flask**. 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.
|
||||||
|
|
||||||
Some Python packages with obscure C dependencies (e.g. scipy) are [not compatible](https://devcenter.heroku.com/articles/python-c-deps).
|
Some Python packages with obscure C dependencies (e.g. scipy) are [not compatible](https://devcenter.heroku.com/articles/python-c-deps).
|
||||||
|
|
||||||
See it in Action
|
See it in Action
|
||||||
----------------
|
----------------
|
||||||
@@ -29,7 +29,7 @@ Deploying a Python application couldn't be easier:
|
|||||||
Downloading requests-2.12.4-py2.py3-none-any.whl (576KB)
|
Downloading requests-2.12.4-py2.py3-none-any.whl (576KB)
|
||||||
Installing collected packages: requests
|
Installing collected packages: requests
|
||||||
Successfully installed requests-2.12.4
|
Successfully installed requests-2.12.4
|
||||||
|
|
||||||
-----> Discovering process types
|
-----> Discovering process types
|
||||||
Procfile declares types -> (none)
|
Procfile declares types -> (none)
|
||||||
|
|
||||||
@@ -46,11 +46,11 @@ Specify a Python Runtime
|
|||||||
Specific versions of the Python runtime can be specified with a `runtime.txt` file:
|
Specific versions of the Python runtime can be specified with a `runtime.txt` file:
|
||||||
|
|
||||||
$ cat runtime.txt
|
$ cat runtime.txt
|
||||||
python-3.6.0
|
python-3.6.1
|
||||||
|
|
||||||
Runtime options include:
|
Runtime options include:
|
||||||
|
|
||||||
- `python-2.7.13`
|
- `python-2.7.13`
|
||||||
- `python-3.6.0`
|
- `python-3.6.1`
|
||||||
- `pypy-5.6.0` (unsupported, experimental)
|
- `pypy-5.7.0` (unsupported, experimental)
|
||||||
- `pypy3-5.5.0` (unsupported, experimental)
|
- `pypy3-5.5.0` (unsupported, experimental)
|
||||||
|
|||||||
+20
-1
@@ -15,6 +15,10 @@
|
|||||||
# Fail fast and fail hard.
|
# Fail fast and fail hard.
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
|
# Standard Library.
|
||||||
|
export BPLOG_PREFIX="buildpack.python"
|
||||||
|
export BUILDPACK_LOG_FILE=${BUILDPACK_LOG_FILE:-/dev/null}
|
||||||
|
|
||||||
[ "$BUILDPACK_XTRACE" ] && set -o xtrace
|
[ "$BUILDPACK_XTRACE" ] && set -o xtrace
|
||||||
|
|
||||||
# Prepend proper path for virtualenv hackery. This will be deprecated soon.
|
# Prepend proper path for virtualenv hackery. This will be deprecated soon.
|
||||||
@@ -48,7 +52,7 @@ export PATH=$PATH:$ROOT_DIR/vendor/:$ROOT_DIR/vendor/pip-pop
|
|||||||
|
|
||||||
# Sanitizing environment variables.
|
# Sanitizing environment variables.
|
||||||
unset GIT_DIR PYTHONHOME PYTHONPATH
|
unset GIT_DIR PYTHONHOME PYTHONPATH
|
||||||
unset RECEIVE_DATA RUN_KEY BUILD_INFO DEPLOY LOG_TOKEN DYNO
|
unset RECEIVE_DATA RUN_KEY BUILD_INFO DEPLOY LOG_TOKEN
|
||||||
unset CYTOKINE_LOG_FILE GEM_PATH
|
unset CYTOKINE_LOG_FILE GEM_PATH
|
||||||
|
|
||||||
# Syntax sugar.
|
# Syntax sugar.
|
||||||
@@ -137,10 +141,14 @@ if [[ $BUILD_DIR != '/app' ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Install Python.
|
# Install Python.
|
||||||
|
let start=$(nowms)
|
||||||
source $BIN_DIR/steps/python
|
source $BIN_DIR/steps/python
|
||||||
|
mtime "python.install.time" "${start}"
|
||||||
|
|
||||||
# Sanity check for setuptools/distribute.
|
# Sanity check for setuptools/distribute.
|
||||||
|
let start=$(nowms)
|
||||||
source $BIN_DIR/steps/setuptools
|
source $BIN_DIR/steps/setuptools
|
||||||
|
mtime "setuptools.install.time" "${start}"
|
||||||
|
|
||||||
# Pipenv support.
|
# Pipenv support.
|
||||||
source $BIN_DIR/steps/pipenv
|
source $BIN_DIR/steps/pipenv
|
||||||
@@ -169,20 +177,28 @@ sub-env $BIN_DIR/steps/geo-libs
|
|||||||
source $BIN_DIR/steps/gdal
|
source $BIN_DIR/steps/gdal
|
||||||
|
|
||||||
# Install dependencies with Pip (where the magic happens).
|
# Install dependencies with Pip (where the magic happens).
|
||||||
|
let start=$(nowms)
|
||||||
source $BIN_DIR/steps/pip-install
|
source $BIN_DIR/steps/pip-install
|
||||||
|
mtime "pip.install.time" "${start}"
|
||||||
|
|
||||||
# Uninstall removed dependencies with Pip.
|
# Uninstall removed dependencies with Pip.
|
||||||
|
let start=$(nowms)
|
||||||
source $BIN_DIR/steps/pip-uninstall
|
source $BIN_DIR/steps/pip-uninstall
|
||||||
|
mtime "pip.uninstall.time" "${start}"
|
||||||
|
|
||||||
# Support for NLTK corpora.
|
# Support for NLTK corpora.
|
||||||
|
let start=$(nowms)
|
||||||
sub-env $BIN_DIR/steps/nltk
|
sub-env $BIN_DIR/steps/nltk
|
||||||
|
mtime "nltk.download.time" "${start}"
|
||||||
|
|
||||||
# Support for pip install -e.
|
# Support for pip install -e.
|
||||||
rm -fr $BUILD_DIR/.heroku/src
|
rm -fr $BUILD_DIR/.heroku/src
|
||||||
deep-cp /app/.heroku/src $BUILD_DIR/.heroku/src
|
deep-cp /app/.heroku/src $BUILD_DIR/.heroku/src
|
||||||
|
|
||||||
# Django collectstatic support.
|
# Django collectstatic support.
|
||||||
|
let start=$(nowms)
|
||||||
sub-env $BIN_DIR/steps/collectstatic
|
sub-env $BIN_DIR/steps/collectstatic
|
||||||
|
mtime "collectstatic.time" "${start}"
|
||||||
|
|
||||||
# Create .profile script for application runtime environment variables.
|
# Create .profile script for application runtime environment variables.
|
||||||
set-env PATH '$HOME/.heroku/python/bin:$PATH'
|
set-env PATH '$HOME/.heroku/python/bin:$PATH'
|
||||||
@@ -219,3 +235,6 @@ cp -R .heroku/vendor $CACHE_DIR/.heroku/ &> /dev/null || true
|
|||||||
if [[ -d .heroku/src ]]; then
|
if [[ -d .heroku/src ]]; then
|
||||||
cp -R .heroku/src $CACHE_DIR/.heroku/ &> /dev/null || true
|
cp -R .heroku/src $CACHE_DIR/.heroku/ &> /dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Measure the size of the Python installation.
|
||||||
|
mmeasure 'python.size' "$(measure-size)"
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ pip-grep -s requirements.txt django Django && DJANGO_INSTALLED=1
|
|||||||
if [ ! "$DISABLE_COLLECTSTATIC" ] && [ -f "$MANAGE_FILE" ] && [ "$DJANGO_INSTALLED" ]; then
|
if [ ! "$DISABLE_COLLECTSTATIC" ] && [ -f "$MANAGE_FILE" ] && [ "$DJANGO_INSTALLED" ]; then
|
||||||
set +e
|
set +e
|
||||||
|
|
||||||
puts-cmd "python $MANAGE_FILE collectstatic --noinput"
|
puts-step "$ python $MANAGE_FILE collectstatic --noinput"
|
||||||
|
|
||||||
# Run collectstatic, cleanup some of the noisy output.
|
# Run collectstatic, cleanup some of the noisy output.
|
||||||
python $MANAGE_FILE collectstatic --noinput --traceback 2>&1 | sed '/^Post-processed/d;/^Copying/d;/^$/d' | indent
|
python $MANAGE_FILE collectstatic --noinput --traceback 2>&1 | sed '/^Post-processed/d;/^Copying/d;/^$/d' | indent
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ if [ ! "$SKIP_INSTALL" ]; then
|
|||||||
mkdir -p .heroku/python
|
mkdir -p .heroku/python
|
||||||
|
|
||||||
curl https://lang-python.s3.amazonaws.com/$STACK/runtimes/$PYTHON_VERSION.tar.gz -s | tar zxv -C .heroku/python &> /dev/null
|
curl https://lang-python.s3.amazonaws.com/$STACK/runtimes/$PYTHON_VERSION.tar.gz -s | tar zxv -C .heroku/python &> /dev/null
|
||||||
|
mcount "version.python.$PYTHON_VERSION"
|
||||||
|
|
||||||
if [[ $? != 0 ]] ; then
|
if [[ $? != 0 ]] ; then
|
||||||
puts-warn "Requested runtime ($PYTHON_VERSION) is not available for this stack ($STACK)."
|
puts-warn "Requested runtime ($PYTHON_VERSION) is not available for this stack ($STACK)."
|
||||||
puts-warn "Aborting. More info: https://devcenter.heroku.com/articles/python-support"
|
puts-warn "Aborting. More info: https://devcenter.heroku.com/articles/python-support"
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
shopt -s extglob
|
shopt -s extglob
|
||||||
|
|
||||||
|
# The standard library.
|
||||||
|
if [[ ! -f /tmp/stdlib.sh ]]; then
|
||||||
|
curl --retry 3 -s https://raw.githubusercontent.com/heroku/buildpack-stdlib/v2/stdlib.sh > /tmp/stdlib.sh
|
||||||
|
fi
|
||||||
|
source /tmp/stdlib.sh
|
||||||
|
|
||||||
if [ $(uname) == Darwin ]; then
|
if [ $(uname) == Darwin ]; then
|
||||||
sed() { command sed -l "$@"; }
|
sed() { command sed -l "$@"; }
|
||||||
else
|
else
|
||||||
@@ -11,16 +18,12 @@ indent() {
|
|||||||
sed "s/^/ /"
|
sed "s/^/ /"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Clean up pip output
|
# Clean up pip output
|
||||||
cleanup() {
|
cleanup() {
|
||||||
sed -e 's/\.\.\.\+/.../g' | sed -e '/already satisfied/Id' | sed -e '/No files were found to uninstall/Id' | sed -e '/Overwriting/Id' | sed -e '/python executable/Id' | sed -e '/no previously-included files/Id'
|
sed -e 's/\.\.\.\+/.../g' | sed -e '/already satisfied/Id' | sed -e '/No files were found to uninstall/Id' | sed -e '/Overwriting/Id' | sed -e '/python executable/Id' | sed -e '/no previously-included files/Id'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Buildpack Indented line.
|
|
||||||
puts-line() {
|
|
||||||
echo " $@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Buildpack Steps.
|
# Buildpack Steps.
|
||||||
puts-step() {
|
puts-step() {
|
||||||
echo "-----> $@"
|
echo "-----> $@"
|
||||||
@@ -31,28 +34,6 @@ puts-warn() {
|
|||||||
echo " ! $@"
|
echo " ! $@"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Buildpack Commands.
|
|
||||||
puts-cmd() {
|
|
||||||
echo " $ $@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Usage: $ set-env key value
|
|
||||||
set-env() {
|
|
||||||
echo "export $1=$2" >> $PROFILE_PATH
|
|
||||||
echo "export $1=$2" >> $EXPORT_PATH
|
|
||||||
}
|
|
||||||
|
|
||||||
# Usage: $ set-default-env key value
|
|
||||||
set-default-env() {
|
|
||||||
echo "export $1=\${$1:-$2}" >> $PROFILE_PATH
|
|
||||||
echo "export $1=\${$1:-$2}" >> $EXPORT_PATH
|
|
||||||
}
|
|
||||||
|
|
||||||
# Usage: $ un-set-env key
|
|
||||||
un-set-env() {
|
|
||||||
echo "unset $1" >> $PROFILE_PATH
|
|
||||||
}
|
|
||||||
|
|
||||||
# Does some serious copying.
|
# Does some serious copying.
|
||||||
deep-cp() {
|
deep-cp() {
|
||||||
declare source="$1" target="$2"
|
declare source="$1" target="$2"
|
||||||
@@ -69,26 +50,11 @@ deep-cp() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Does some serious moving.
|
|
||||||
deep-mv() {
|
|
||||||
deep-cp "$1" "$2"
|
|
||||||
deep-rm "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Does some serious deleting.
|
|
||||||
deep-rm() {
|
|
||||||
# subshell to avoid surprising caller with shopts.
|
|
||||||
(
|
|
||||||
shopt -s dotglob
|
|
||||||
rm -rf "$1"/!(.curlrc|.netrc|tmp|.|..)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub-env() {
|
sub-env() {
|
||||||
|
|
||||||
WHITELIST=${2:-''}
|
WHITELIST=${2:-''}
|
||||||
BLACKLIST=${3:-'^(GIT_DIR|PYTHONHOME|LD_LIBRARY_PATH|LIBRARY_PATH|PATH)$'}
|
BLACKLIST=${3:-'^(GIT_DIR|STACK|PYTHONHOME|LD_LIBRARY_PATH|LIBRARY_PATH|PATH)$'}
|
||||||
|
|
||||||
# Python-specific variables.
|
# Python-specific variables.
|
||||||
export PYHONHOME=$BUILD_DIR/.heroku/python
|
export PYHONHOME=$BUILD_DIR/.heroku/python
|
||||||
@@ -108,3 +74,8 @@ sub-env() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Measure the size of the Python installation.
|
||||||
|
measure-size() {
|
||||||
|
echo "$((du -s .heroku/python 2>/dev/null || echo 0) | awk '{print $1}')"
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ old-platform() {
|
|||||||
puts-warn "This caused the security warning you saw above during the 'pip install' step."
|
puts-warn "This caused the security warning you saw above during the 'pip install' step."
|
||||||
puts-warn "We recommend '$RECOMMENDED_PYTHON_VERSION', which you can specify in a 'runtime.txt' file."
|
puts-warn "We recommend '$RECOMMENDED_PYTHON_VERSION', which you can specify in a 'runtime.txt' file."
|
||||||
puts-warn " -- Much Love, Heroku."
|
puts-warn " -- Much Love, Heroku."
|
||||||
|
mcount 'warnings.python.old'
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@ pylibmc-missing() {
|
|||||||
puts-warn "Hello! There was a problem with your build related to libmemcache."
|
puts-warn "Hello! There was a problem with your build related to libmemcache."
|
||||||
puts-warn "The Python library 'pylibmc' must be explicitly specified in 'requirements.txt' in order to build correctly."
|
puts-warn "The Python library 'pylibmc' must be explicitly specified in 'requirements.txt' in order to build correctly."
|
||||||
puts-warn "Once you do that, everything should work as expected. -- Much Love, Heroku."
|
puts-warn "Once you do that, everything should work as expected. -- Much Love, Heroku."
|
||||||
|
mcount 'warnings.libmemcache'
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,6 +29,7 @@ scipy-included() {
|
|||||||
puts-warn "There is, however, a buildpack available that makes it possible to use it on Heroku."
|
puts-warn "There is, however, a buildpack available that makes it possible to use it on Heroku."
|
||||||
puts-warn "You can learn more here: https://devcenter.heroku.com/articles/python-c-deps"
|
puts-warn "You can learn more here: https://devcenter.heroku.com/articles/python-c-deps"
|
||||||
puts-warn "Sorry for the inconvenience. -- Much Love, Heroku."
|
puts-warn "Sorry for the inconvenience. -- Much Love, Heroku."
|
||||||
|
mcount 'warnings.scipy'
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +40,18 @@ distribute-included() {
|
|||||||
puts-warn "This library is automatically installed by Heroku and shouldn't be in"
|
puts-warn "This library is automatically installed by Heroku and shouldn't be in"
|
||||||
puts-warn "Your requirements.txt file. This can cause unexpected behavior."
|
puts-warn "Your requirements.txt file. This can cause unexpected behavior."
|
||||||
puts-warn " -- Much Love, Heroku."
|
puts-warn " -- Much Love, Heroku."
|
||||||
|
mcount 'warnings.distribute'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
six-included() {
|
||||||
|
if grep -qi 'Running setup.py install for six' "$WARNINGS_LOG"; then
|
||||||
|
echo
|
||||||
|
puts-warn "Hello! Your requirements.txt file contains the six package."
|
||||||
|
puts-warn "This library is automatically installed by Heroku and shouldn't be in"
|
||||||
|
puts-warn "Your requirements.txt file. This can cause unexpected behavior."
|
||||||
|
puts-warn " -- Much Love, Heroku."
|
||||||
|
mcount 'warnings.six'
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,5 +60,6 @@ show-warnings() {
|
|||||||
pylibmc-missing
|
pylibmc-missing
|
||||||
scipy-included
|
scipy-included
|
||||||
distribute-included
|
distribute-included
|
||||||
|
six-included
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Executable
+14
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build Path: /app/.heroku/python/
|
||||||
|
# Build Deps: libraries/sqlite
|
||||||
|
|
||||||
|
# NOTICE: This formula only works for the cedar-14 and heroku-16 stacks, not cedar.
|
||||||
|
|
||||||
|
OUT_PREFIX=$1
|
||||||
|
|
||||||
|
echo "Building PyPy..."
|
||||||
|
SOURCE_TARBALL='https://bitbucket.org/pypy/pypy/downloads/pypy2-v5.7.0-linux64.tar.bz2'
|
||||||
|
curl -L $SOURCE_TARBALL | tar jx
|
||||||
|
cp -R pypy2-v5.7.0-linux64/* $OUT_PREFIX
|
||||||
|
|
||||||
|
ln $OUT_PREFIX/bin/pypy $OUT_PREFIX/bin/python
|
||||||
Executable
+18
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build Path: /app/.heroku/python/
|
||||||
|
# Build Deps: libraries/sqlite
|
||||||
|
|
||||||
|
OUT_PREFIX=$1
|
||||||
|
|
||||||
|
echo "Building Python..."
|
||||||
|
SOURCE_TARBALL='https://python.org/ftp/python/3.6.1/Python-3.6.1.tgz'
|
||||||
|
curl -L $SOURCE_TARBALL | tar xz
|
||||||
|
mv Python-3.6.1 src
|
||||||
|
cd src
|
||||||
|
|
||||||
|
./configure --prefix=$OUT_PREFIX --with-ensurepip=no
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
ln $OUT_PREFIX/bin/python3 $OUT_PREFIX/bin/python
|
||||||
|
|
||||||
Reference in New Issue
Block a user