Search code examples
herokudockeranacondacondaminiconda

"Could not find a version that satisfies the requirement cv2==1.0" when deploy Docker app with Anaconda and OpenCV to Heroku


I am trying to deploy a simple Python app with Conda support to Heroku.

I can deploy this simple example to Heroku without problem: https://github.com/heroku-examples/python-miniconda

But it no longer work when I added a cv2 import:

Original app.py file:

from flask import Flask, jsonify
from sklearn import datasets, svm

app = Flask(__name__)

# Load Dataset from scikit-learn.
digits = datasets.load_digits()

@app.route('/')
def hello():
    clf = svm.SVC(gamma=0.001, C=100.)
    clf.fit(digits.data[:-1], digits.target[:-1])
    prediction = clf.predict(digits.data[-1:])

    return jsonify({'prediction': repr(prediction)})

if __name__ == '__main__':
    app.run(host='0.0.0.0')

Modified app.py file:

from flask import Flask, jsonify, render_template, request, redirect, url_for, send_from_directory
from sklearn import datasets, svm
import os
import json
import requests

# browser the file that the user just uploaded
from werkzeug import secure_filename
from keras.models import Sequential
from keras.layers.core import Flatten, Dense, Dropout
from keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D
from keras.optimizers import SGD
from keras.applications.resnet50 import preprocess_input, decode_predictions
from keras import applications
import cv2, numpy as np

app = Flask(__name__)

# These are the extension that we are accepting to be uploaded
app.config['ALLOWED_EXTENSIONS'] = set(['png', 'jpg', 'jpeg', 'gif'])

# For a given file, return whether it's an allowed type or not
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']

@app.route('/')
def hello_world():
    return 'Hello World!'

# Route that will process the file upload
@app.route('/upload', methods=['POST'])
def upload():
    # Get the name of the uploaded file
    file = request.files['file']
    # Check if the file is one of the allowed types/extensions
    if file and allowed_file(file.filename):
        # Make the filename safe, remove unsupported chars
        # filename = secure_filename(file.filename)
        # Move the file form the temporal folder to
        # the upload folder we setup
        # file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        # Redirect the user to the uploaded_file route, which
        # will basicaly show on the browser the uploaded file
        file.save(file.filename)
        im = cv2.resize(cv2.imread(file.filename), (224, 224)).astype(np.float32)
        im[:,:,0] -= 103.939
        im[:,:,1] -= 116.779
        im[:,:,2] -= 123.68
        im = im.transpose((2,0,1))
        im = np.expand_dims(im, axis=0)
        out = model.predict(im)
        decoded = decode_predictions(out, top=3)[0]
        print('Predicted:', decoded)
        return str(decoded)

if __name__ == '__main__':
    # Test pretrained model
    model = applications.VGG19(include_top=True, weights='imagenet')
    app.run()

I will get this error when pushing this modified app to Heroku:

Could not find a version that satisfies the requirement cv2==1.0 (from -r /tmp/requirements.txt (line 10)) (from versions: )
No matching distribution found for cv2==1.0 (from -r /tmp/requirements.txt (line 10))
The command '/bin/sh -c pip install -qr /tmp/requirements.txt' returned a non-zero code: 1
 !    Error: docker build exited with 1

So it appears that cv2 is missing on the Docker container? I added this line "RUN conda install -c conda-forge opencv" in the Dockerfile template from the example project, but it doesnt help:

FROM heroku/miniconda

# Grab requirements.txt.
ADD ./webapp/requirements.txt /tmp/requirements.txt

# Install dependencies
RUN pip install -qr /tmp/requirements.txt

# Add our code
ADD ./webapp /opt/webapp/
WORKDIR /opt/webapp

RUN conda install scikit-learn
RUN conda install -c conda-forge opencv

CMD gunicorn --bind 0.0.0.0:$PORT wsgi=

Any help please?


Solution

  • The error that you are seeing is related to the fact that pip is not able to install the pip package listed on the pypi index as cv2 with version 1.0. Apparently, that package description is "My Blog Distribution Utilities" and there are no files present at https://pypi.python.org/simple/cv2/, which is why you see an error similar to:

    (test) ubuntu@condaexpts:~$ pip install cv2==1.0
    Collecting cv2==1.0
      Could not find a version that satisfies the requirement cv2==1.0 (from versions: )
    No matching distribution found for cv2==1.0
    

    It seems quite obvious that this is not the package that you want. So please remove cv2==1.0 from the file requirements.txt

    What you are really looking for, is the conda package for opencv, which you should be able to get from:

    RUN conda install -yc conda-forge opencv