8

I'm trying to upload my Dash app to Heroku. I've been following the documentation, however, when I go to push I get the following error:

  ERROR: Could not find a version that satisfies the requirement numpy==1.20.1
  remote:        ERROR: No matching distribution found for numpy==1.20.1 (from -r      /    t     tmp/build_32b7cf97/requirements.txt (line 19))
  remote:  !     Push rejected, failed to compile Python app.

My version of Python is 3.8 and pip is 21.0.1. Oddly enough, I saw this in the output log as well:

remote: Building source:
remote: 
remote: -----> Building on the Heroku-20 stack
remote: -----> Python app detected
remote: -----> Installing python-3.6.12
remote: -----> Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2
remote: -----> Installing SQLite3
remote: -----> Installing requirements with pip

Heroku installed python 3.6 and pip 20.1.1. Could that be related to the problem? I've looked for similar problems by other users and they recommended deleting the offending dependency from the requirements.txt. But in this case, I need it for my program.

Any suggestions would be greatly appreciated as I have hit a wall.

2
  • Did you provide Heroku with a runtime.txt? Heroku does not care about the Python you use on your local environment. It has its own env, and if you want it to use a specific Python version, you have to specifically tell it which one to use. See devcenter.heroku.com/articles/python-runtimes. Commented Feb 13, 2021 at 7:51
  • When I add a runtime.txt I get the following error. Requested runtime (Python 3.8.2) is not available for this stack (heroku-20). So I need change my Python version to an acceptable stack? Commented Feb 13, 2021 at 8:02

2 Answers 2

20

Starting with the NumPy installation error:

remote:      ERROR: Could not find a version that satisfies the requirement numpy==1.20.1  
remote:      ERROR: No matching distribution found for numpy==1.20.1 (from -r /tmp/build_32b7cf97/requirements.txt (line 19))  
remote:  !     Push rejected, failed to compile Python app.  

That usually means that the NumPy version does not exist or the Python version you are using is not supported by that NumPy version. Checking NumPy's PyPi releases page, 1.20.1 is indeed a valid version. However, checking the NumPy 1.20.0 release notes has this info,

The Python versions supported for this release are 3.7-3.9, support for Python 3.6 has been dropped.

So your guess was correct that it's related to the Python version.

My version of python is 3.8 and pip is 21.0.1
...
Heroku installed python 3.6 and pip 20.1.1

Heroku has its own Python runtime environment and it does not know or care about the Python version you are using on your local env. It will use the default Python version for the chosen stack ("Heroku-20" in your case), and if you want it to use a specific Python version, you have to explicitly tell it which version to use.

From its list of supported runtimes:

By default, newly created Python apps use the python-3.6.13 runtime. You can also specify a different supported Python version.

Supported runtimes

  • python-3.9.2 on all supported stacks
  • python-3.8.8 on all supported stacks
  • python-3.7.10 on all supported stacks
  • python-3.6.13 on all supported stacks
  • python-2.7.18 on Heroku-16 and Heroku-18 only

If you didn't tell it to use Python 3.8, then it will use the default version of your Heroku stack, which is currently Python 3.6.x. As mentioned above, 3.6 isn't compatible with NumPy 1.20.1.

The fix is simple: specify the runtime:

To specify a Python runtime, add a runtime.txt file to your app’s root directory that declares the exact version number to use:

$ cat runtime.txt  
python-3.9.0  

So, you need to add a runtime.txt file, and put in a version that is on the list of supported runtimes (see link above) and is supported by your version of numpy:

python-3.8.8

Lastly, it's good practice to keep your local env's Python version consistent with your deployment env's Python version. Basically, make sure to update your 3.8.2 to match what you specified on runtime.txt for Heroku's.

Sign up to request clarification or add additional context in comments.

Comments

0

In my case, we wanted to get pip modules installed from a requirement*.txt file(s), which had locked-in module's versions defined in the file and resolved from ONLY an internal Artifactory server (rather than going to online i.e. pypi.org)

Ex: requirements.txt file(s)

numpy==1.16.2
pandas==1.0.3
..
...

To fix the issue: I had to use NO_PROXY=<value> available as an environment variable.

Let's say, if you artifactory server is: my-artifactory.company.local or my-artifactory.company.com, then all we need to ensure is that NO_PROXY variable has that hostname's "domain" part listed in its value.

i.e. for my-artifactory.company.com or my-artifactory.company.local, value inside

NO_PROXY variable must have: ,.company.com,.company.local,... in it.

Sample exported variable (at command line $ prompt):

export NO_PROXY=localhost,127.0.0.1,169.254.169.254,169.254.169.123,.somecompany.com,.company.com,.company.local,pki.company.com,s3-us-gov-west-1.amazonaws.com,s3-fips-us-gov-west-1.amazonaws.com,rds.amazonaws.com,10.201.12.244,10.201.44.62,10.201.32.261

====

If you are using a Dockerfile, then, ensure you have ARG/ENV variable are set correctly. ARG is used during build time (can be overridden at command line using --build-arg option sent to docker build -t tag . where it'll search current directory for a Dockerfile and create an image. ENV is used at run time (docker run) and can be overridden as well.

Sample Dockerfile is:

FROM python:3.7

MAINTAINER [email protected]

ARG PYTHONBUFFERED=0
ARG HTTPS_PROXY=http://proxy.ext.company.com:80
ARG HTTP_PROXY=http://proxy.ext.company.com:80
ARG NO_PROXY=localhost,127.0.0.1,169.254.169.254,.company.com,.company.local,pki.company.com,s3-us-gov-west-1.amazonaws.com,s3-fips-us-gov-west-1.amazonaws.com,rds.amazonaws.com

ENV PYTHONBUFFERED=${PYTHONBUFFERED}
ENV HTTPS_PROXY=${HTTPS_PROXY}
ENV HTTP_PROXY=${HTTP_PROXY}
ENV NO_PROXY=${NO_PROXY}

# If there are 3 requirements files in source control, I'm copy all for pip install, you don't have to. Use what modules you want / file you want.    
RUN mkdir -p code
COPY requirements.txt /code
COPY requirements-test.txt /code
COPY requirements-dev.txt /code

WORKDIR /code

# You can fetch from pypi.org but in my case, this was a security issue.
# RUN pip install --trusted-host pypi.org -r requirements.txt

RUN pip install --no-cache-dir --trusted-host my-artifactory.company.local -r requirements.txt -r requirements-test.txt -r requirements-dev.txt --index-url http://my-artifactory.company.local:8081/artifactory/api/pypi/pypi-local-deps/simple --disable-pip-version-check

The main line, which solved the issue in my case, was using the NO_PROXY (as listed above).

Any issues related to pip module not found, or module version not found, or any SSL errors SSLError(SSLCertVerificationError like errors, went away after applying the above NO_PROXY at cmd line or in Dockerfile:

WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1091)'))': /simple/requests/

or

ERROR: Could not find a version that satisfies the requirement requests
ERROR: No matching distribution found for requests

or

ERROR: Could not find a version that satisfies the requirement numpy==1.16.2
ERROR: No matching distribution found for numpy==1.16.2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.