Search code examples
pythonnode.jsheroku

Python and Node.js on Heroku


I have started to make a Node server which runs on Heroku. It was working fine until I tried to use the (unofficial) Duolingo API. I wrote the following Python script to connect to the API:

import duolingo
import simplejson as json

lingo  = duolingo.Duolingo('harleyrowland')
print json.dumps(lingo.get_user_info())

and my Node server uses it using the following commands:

var python = require('python-shell');

module.exports = {
  getData: function(callback){
    python.run('duoScript.py', function (err, results) { 
      console.log(err);
      console.log(results);
      var res = JSON.parse(results);
      var language = res.language_data.es.language_string;
      var streak = res.language_data.es.streak;
      var level = res.language_data.es.level;
      var levelPerecentage = res.language_data.es.level_percent;
      var fluency = res.language_data.es.fluency_score;
      var nextLesson = res.language_data.es.next_lesson.skill_title;
      return callback({language, streak, level, levelPerecentage, fluency, nextLesson});
    });
  }
}

which all works totally fine locally.

When I pushed this to Heroku, the code didn't work and I started to get the following error in the Heroku logs:

{ [Error: ImportError: No module named duolingo]
     2016-10-06T00:02:32.133315+00:00 app[web.1]:   traceback: 'Traceback (most recent call last):\n  File "duoScript.py", line 1, in <module>\n    import duolingo\nImportError: No module named duolingo\n',
    executable: 'python',
    options: null,
    script: 'duoScript.py',
    args: null,
    exitCode: 1 
}

Because of this, I went on the Heroku API and found that I needed to add a requirements.txt file. So I did:

duolingo-api==0.3
simplejson==3.8.2

which still didn't work. I then found this answer and added a .buildpacks file:

https://github.com/heroku/heroku-buildpack-python.git
https://github.com/heroku/heroku-buildpack-nodejs.git

and I still get the same error.

Any idea what is causing this error?

Update 1

Thought I would show my Procfile too incase this was the problem:

web: node index.js
pipinstall: pip install -r requirements.txt

Update 2

Output of git push heroku master without pipinstall:

$ git push heroku master
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 288 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Node.js app detected
remote: 
remote: -----> Creating runtime environment
remote:        
remote:        NPM_CONFIG_LOGLEVEL=error
remote:        NPM_CONFIG_PRODUCTION=true
remote:        NODE_ENV=production
remote:        NODE_MODULES_CACHE=true
remote: 
remote: -----> Installing binaries
remote:        engines.node (package.json):  5.9.1
remote:        engines.npm (package.json):   unspecified (use default)
remote:        
remote:        Downloading and installing node 5.9.1...
remote:        Using default npm version: 3.7.3
remote: 
remote: -----> Restoring cache
remote:        Loading 2 from cacheDirectories (default):
remote:        - node_modules
remote:        - bower_components (not cached - skipping)
remote: 
remote: -----> Building dependencies
remote:        Installing node modules (package.json)
remote: 
remote: -----> Caching build
remote:        Clearing previous node cache
remote:        Saving 2 cacheDirectories (default):
remote:        - node_modules
remote:        - bower_components (nothing to cache)
remote: 
remote: -----> Build succeeded!
remote:        ├── [email protected] extraneous
remote:        ├── [email protected] extraneous
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        └── [email protected]
remote:        
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote: 
remote: -----> Compressing...
remote:        Done: 13M
remote: -----> Launching...
remote:        Released v25
remote:        https://arcane-anchorage-33274.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy... done.

Solution

  • Try to remove the deprecated heroku-buildpack-multi and use the Heroku buildpacks command:

    $ heroku buildpacks:add --index 1 heroku/nodejs
    $ heroku buildpacks:add --index 2 heroku/python
    $ heroku buildpacks
    === foobar Buildpack URLs
    1. heroku/nodejs
    2. heroku/python
    

    From the docs:

    The buildpack for the primary language of your app should always be the last buildpack in the list. This ensures that defaults for that primary language are applied instead of those for another language, and allows Heroku to correctly detect the primary language of your app.