Google Cloud Platform - Datastore - Python ndb API
<p>I recently started working with the Google Cloud Platform, more precisely, with the ndb-Datastore-API. I tried to use following tutorial (<a href="https://github.com/GoogleCloudPlatform/appengine-guestbook-python.git" rel="nofollow">https://github.com/GoogleCloudPlatform/appengine-guestbook-python.git</a>) to get used to the API. </p>

<p>Unfortunately, I cannot figure out how to import the third party library tweepy into tweet.py. Google Cloud does not support tweepy so that I had to include the library manually in a folder /lib. But how do I now import the installed tweepy (pip install -t lib tweepy)? </p>

<p>I basically just try to put an Entity in the Google Datastore but I cannot figure out what I did wrong. </p>

<p>tweet.py: </p>

<pre><code>    # [START imports]
from __future__ import absolute_import, print_function
import os
import urllib
from time import *
import jinja2
import webapp2
from google.appengine.api import users
from google.appengine.ext import ndb

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True)
# [END imports]

# [START globalvar]
# Go to http://apps.twitter.com and create an app.
# The consumer key and secret will be generated for you after
consumer_key="KEY"
consumer_secret="SECRET"
# After the step above, you will be redirected to your app's page.
# Create an access token under the the "Your access token" section
access_token="TOKEN"
access_token_secret="SECRET"
# [END globalvar]

USERNAME = "@Seeed"

def getDate():
    # local Time
    lt = localtime()
    # get Date
    year, month, day = lt[0:3]
    date = "%02i.%02i.%04i" % (day,month,year)
    return date

# [START tweet_count_entity]
class TweetCount(ndb.Model):
    """A main model for representing an individual TweetCount entry."""
    date = ndb.DateProperty(auto_now_add=True)
    tweets = ndb.IntegerProperty(indexed=False)
    user_name = ndb.StringProperty(indexed=False)

# [END tweet_count_entity]

# [START tweet_counter]
class TweetCounter(webapp2.RequestHandler):
    """
    # Create a key for the Entity
    def tweetCount_key(date):
        date = getDate()
        return ndb.Key('TweetCount', date)"""

    # Get TweetCount for actor "user_name"
    def getTweetCount(self, user_name):
        auth = OAuthHandler(consumer_key, consumer_secret)
        auth.set_access_token(access_token, access_token_secret)
        api = tweepy.API(auth)
        user = api.get_user(user_name)
        return user.followers_count

    def get(self):
        count = self.getTweetCount(USERNAME)
        tweet_count_user_name = USERNAME
        tweet_count_tweets = count
        tweet_count = TweetCount(tweets=tweet_count_tweets, user_name=tweet_count_user_name)
        tweet_count.put()
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.write("" + USERNAME + " TweetCount: " + str(count))

# [END tweet_counter]

# [START app]
app = webapp2.WSGIApplication([
    ('/', TweetCounter),
], debug=True)
# [END app]
</code></pre>

<p>app.yaml:</p>

<pre><code>runtime: python27
api_version: 1
threadsafe: true

# [START handlers]
handlers:
- url: /.*
  script: tweet.app
# [END handlers]

# [START libraries]
libraries:
- name: webapp2
  version: latest
- name: jinja2
  version: latest
# [END libraries]
</code></pre>

<p>index.yaml:</p>

<pre><code>indexes:
- kind: TweetCount
  properties:
  - name: date
  - name: tweets
  - name: user_name
</code></pre>

<p>appengine_config.py: </p>

<pre><code>from google.appengine.ext import vendor

# Add any libraries installed in the "lib" folder.
vendor.add('lib')
</code></pre>

<p>Thank you very much for your help. I appreciate any help and an explanation about what I did wrong. </p>

<p>Based on your <code>tweet.py</code> and <code>app.yaml</code>, I can see the 2 things that may be the reason you cannot yet use <strong>tweepy</strong> in your Python application.  For the sake of being through, I'll document the complete process.</p>

<h2>Acquire tweepy library</h2>

<p>As <strong>Tweepy</strong> is a <a href="https://cloud.google.com/appengine/docs/python/tools/using-libraries-python-27" rel="nofollow">third party library</a> and not a library that ships with Google App Engine, we have to package it with our Python application as you've already suggested with <a href="https://packaging.python.org/installing/#use-pip-for-installing" rel="nofollow"><code>pip install --target lib tweepy</code></a>.  The directory specified after the <code>--target</code> option is where the third party library will be downloaded.</p>

<h2>Vendor in the third-party directory</h2>

<p>Now that we've downloaded the third party library, Python must be made to search this <code>lib</code> directory when attempting to import modules.  This can be done as you've shown, using an <code>appengine_config.py</code> file in your application directory as indicated in <a href="https://cloud.google.com/appengine/docs/python/tools/using-libraries-python-27#installing_a_library" rel="nofollow">Installing a library</a> like so:</p>

<pre class="lang-python prettyprint-override"><code>from google.appengine.ext import vendor
vendor.add('lib')
</code></pre>

<h2>Import third-party module in the application</h2>

<p>Python will now look in the <code>lib</code> directory when attempting to import modules.  Thus, we add our import statement where appropriate in our application code (e.g.: <code>tweet.py</code>):</p>

<pre class="lang-python prettyprint-override"><code>import tweepy
</code></pre>

<p><strong><em>This import is not currently found in your <code>tweet.py</code> example.</em></strong></p>

<h2>Ensure tweepy's dependencies are also imported</h2>

<p>Note that <strong>tweepy</strong> when imported will attempt to import the <strong>ssl</strong> module so it must be included in the <code>libraries</code> section of your <code>app.yaml</code> like so:</p>

<pre class="lang-yaml prettyprint-override"><code>libraries:
- name: ssl
  version: latest
</code></pre>

<p><strong><em>This too, was not in your example <code>app.yaml</code>.</em></strong></p>

<p>With the above, one should be able to successfully deploy a python GAE application which properly imports <strong>tweepy</strong>.  Note that I've not actively tested any of <strong>tweepy</strong>'s features, but merely imported it successfully.  Should you be seeing any errors with the above examples, I would suggested also including the following in your question:  </p>

<ul>
<li>App Engine SDK version</li>
<li>Python version</li>
<li>pip version</li>
<li>Stack trace of the error you are receiving when deploying or serving a HTTP response</li>
</ul>

python google-app-engine google-cloud-platform google-cloud-datastore