Skip to content

Instantly share code, notes, and snippets.

@lost-theory
Last active April 2, 2016 20:10
Show Gist options
  • Save lost-theory/9c676fb82521a6111907b02a3b22f407 to your computer and use it in GitHub Desktop.
Save lost-theory/9c676fb82521a6111907b02a3b22f407 to your computer and use it in GitHub Desktop.
Conda app local development on OSX and deploying to Heroku

Downloaded Miniconda installer from here:

http://conda.pydata.org/miniconda.html

In a terminal:

$ sh ./Downloads/Miniconda-latest-MacOSX-x86_64.sh
Enter (read license agreement)
yes (accept license agreement)
Enter (use default installation location)
no (for "prepend install location to PATH", because I'd rather manage the
    default python version myself and keep conda completely separate from
    my other python installs)

Then I cloned this example conda+flask app:

$ cd ~/src/
$ git clone https://github.com/arose13/HerokuCondaScipyFlaskApp

I modified the conda-requirements.txt to use python=2.7.10 instead of python=3.5.1 then created a conda env:

$ ~/miniconda2/bin/conda create --name demo_conda_env --file ~/src/HerokuCondaScipyFlaskApp/
Fetching packages ...
mkl-11.3.1-0.t 100% |##################################| Time: 0:10:31 164.50 kB/s
openssl-1.0.2g 100% |##################################| Time: 0:00:13 242.30 kB/s
sqlite-3.9.2-0 100% |##################################| Time: 0:00:28  44.13 kB/s
python-2.7.10- 100% |##################################| Time: 0:02:15  76.23 kB/s
itsdangerous-0 100% |##################################| Time: 0:00:00 178.30 kB/s
markupsafe-0.2 100% |##################################| Time: 0:00:00 202.41 kB/s
numpy-1.10.1-p 100% |##################################| Time: 0:00:09 315.54 kB/s
setuptools-19. 100% |##################################| Time: 0:00:00 519.12 kB/s
werkzeug-0.11. 100% |##################################| Time: 0:00:21  18.27 kB/s
jinja2-2.8-py2 100% |##################################| Time: 0:00:00 487.80 kB/s
pip-8.0.1-py27 100% |##################################| Time: 0:00:10 154.37 kB/s
scipy-0.16.0-n 100% |##################################| Time: 0:02:02 100.95 kB/s
flask-0.10.1-p 100% |##################################| Time: 0:00:00 343.70 kB/s
scikit-learn-0 100% |##################################| Time: 0:00:14 270.99 kB/s
Extracting packages ...
[      COMPLETE      ]|################################| 100%
Linking packages ...
[      COMPLETE      ]|################################| 100%
#
# To activate this environment, use:
# $ source activate demo_conda_env
#
# To deactivate this environment, use:
# $ source deactivate

I also made some changes to app.py to actually run some demo numpy/scipy/sklearn code (see patch below), then made a commit:

$ git commit
$ git log -1 -p
(see patch below)

Ran the app:

$ cd ~/src/HerokuCondaScipyFlaskApp/
$ ~/miniconda2/envs/demo_conda_env/bin/python Web/app.py

Verified that it worked when I went to http://127.0.0.1:5000/ in my browser.

Then I downloaded the Heroku toolbelt for OSX:

https://s3.amazonaws.com/assets.heroku.com/heroku-toolbelt/heroku-toolbelt.pkg

Double clicked the .pkg in Finder and let it install. Then ran this to set up the Heroku app with the conda buildpack:

$ heroku
heroku-cli: Installing core plugins... done

$ heroku login
Enter your Heroku credentials.
Email: [email protected]
Password (typing will be hidden):
Logged in as [email protected]

$ cd ~/src/HerokuCondaScipyFlaskApp/
$ heroku apps:create --buildpack https://github.com/kennethreitz/conda-buildpack.git
Creating app... done, stack is cedar-14
Setting buildpack to https://github.com/kennethreitz/conda-buildpack.git... done
https://still-forest-30747.herokuapp.com/ | https://git.heroku.com/still-forest-30747.git

Creating an app inside a git repo adds a new remote for heroku:

$ git remote -v
heroku  https://git.heroku.com/vast-fjord-75721.git (fetch)
heroku  https://git.heroku.com/vast-fjord-75721.git (push)
origin  https://github.com/arose13/HerokuCondaScipyFlaskApp (fetch)
origin  https://github.com/arose13/HerokuCondaScipyFlaskApp (push)

I can then push to that remote to deploy the app:

$ git push heroku master

Note: Heroku compiles your app down to a single "slug" file which contains all the dependencies and code necessary to run it. The maximum slug size is 300MB. The first time I tried pushing the slug size was just over 300MB, so the push was rejected. The second time I tried it was over 400MB. I then ran these commands to clear some space (recommended here):

$ heroku plugins:install https://github.com/heroku/heroku-repo.git
$ heroku repo:gc -a vast-fjord-75721
$ heroku repo:purge_cache -a vast-fjord-75721
(also note that both commands gave some gzip error, but it didn't seem to matter?)

Then I tried pushing a third time it was just under 300MB:

$ git push heroku master
...
remote: -----> Compressing...
remote:        Done: 299.1M
remote: -----> Launching...
remote:        Released v4
remote:        https://vast-fjord-75721.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy.... done.

Then I checked out the app in my browser:

https://vast-fjord-75721.herokuapp.com/ (note that I destroyed it after this, so this URL no longer works)

And it worked (screenshot):

http://i.imgur.com/ckjvRqv.png

$ git log -1 -p
commit 32a9d7f95d8417b22d254dd26685ff4185617327
Author: Steven Kryskalla <[email protected]>
Date: Sat Apr 2 12:33:09 2016 -0700
py3 -> py2 and run some demo code
diff --git a/Web/app.py b/Web/app.py
index a9ddabb..77f43a4 100644
--- a/Web/app.py
+++ b/Web/app.py
@@ -1,15 +1,24 @@
import numpy
-import scipy
-import sklearn
+import scipy, scipy.stats
+import sklearn, sklearn.datasets
+
from flask import Flask
app = Flask(__name__)
-
@app.route('/')
def home():
- return 'Home from Anaconda'
-
+ return '''
+ <h1>Hello from Anaconda</h1>
+ <p>I have the follow packages installed:</p>
+ <h2>Numpy {}</h2><p>Here's a numpy array:</p><pre>{}</pre>
+ <h2>Scipy {}</h2><p>Here's scipy.stats.describe on an array:</p><pre>{}</pre>
+ <h2>scikit-learn {}</h2><p>Here's a sample dataset from sklearn.datasets:</p><pre>{}</pre>
+ '''.format(
+ numpy.__version__, numpy.arange(15),
+ scipy.__version__, scipy.stats.describe(numpy.arange(15)),
+ sklearn.__version__, sklearn.datasets.load_boston(),
+ )
if __name__ == '__main__':
# Use this port=33507 when you want to Flask to work on Heroku....
diff --git a/conda-requirements.txt b/conda-requirements.txt
index b8d5c07..2c4a4ab 100644
--- a/conda-requirements.txt
+++ b/conda-requirements.txt
@@ -1,4 +1,4 @@
-python=3.5.1
+python=2.7.10
flask=0.10.1
itsdangerous=0.24
jinja2=2.8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment