2
votes

I'm trying to use the SDK from http://github.com/pythonforfacebook in a new appengine project, but dev-appserver says that no module name facebook could be found.

Here is the code:

import facebook
import webapp2
import os
import jinja2
import urllib2

from google.appengine.ext import db
from webapp2_extras import sessions


FACEBOOK_APP_ID = "xxxxx"
FACEBOOK_APP_SECRET = "xxxxx"

config = {}
config['webapp2_extras.sessions'] = dict(secret_key='')

class User(db.Model):
    id = db.StringProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    name = db.StringProperty(required=True)
    profile_url = db.StringProperty(required=True)
    access_token = db.StringProperty(required=True)


class BaseHandler(webapp2.RequestHandler):
    """Provides access to the active Facebook user in self.current_user
    The property is lazy-loaded on first access, using the cookie saved
    by the Facebook JavaScript SDK to determine the user ID of the active
    user. See http://developers.facebook.com/docs/authentication/ for
    more information.
    """
    @property
    def current_user(self):
        if self.session.get("user"):
            # User is logged in
            return self.session.get("user")
        else:
            # Either used just logged in or just saw the first page
            # We'll see here
            cookie = facebook.get_user_from_cookie(self.request.cookies,
                                                   FACEBOOK_APP_ID,
                                                   FACEBOOK_APP_SECRET)
            if cookie:
                # Okay so user logged in.
                # Now, check to see if existing user
                user = User.get_by_key_name(cookie["uid"])
                if not user:
                    # Not an existing user so get user info
                    graph = facebook.GraphAPI(cookie["access_token"])
                    profile = graph.get_object("me")
                    user = User(
                        key_name=str(profile["id"]),
                        id=str(profile["id"]),
                        name=profile["name"],
                        profile_url=profile["link"],
                        access_token=cookie["access_token"]
                    )
                    user.put()
                elif user.access_token != cookie["access_token"]:
                    user.access_token = cookie["access_token"]
                    user.put()
                # User is now logged in
                self.session["user"] = dict(
                    name=user.name,
                    profile_url=user.profile_url,
                    id=user.id,
                    access_token=user.access_token
                )
                return self.session.get("user")
        return None

    def dispatch(self):
        """
        This snippet of code is taken from the webapp2 framework documentation.
        See more at
        http://webapp-improved.appspot.com/api/webapp2_extras/sessions.html
        """
        self.session_store = sessions.get_store(request=self.request)
        try:
            webapp2.RequestHandler.dispatch(self)
        finally:
            self.session_store.save_sessions(self.response)

    @webapp2.cached_property
    def session(self):
        """
        This snippet of code is taken from the webapp2 framework documentation.
        See more at
        http://webapp-improved.appspot.com/api/webapp2_extras/sessions.html
        """
        return self.session_store.get_session()


class HomeHandler(BaseHandler):
    def get(self):
        template = jinja_environment.get_template('example.html')
        self.response.out.write(template.render(dict(
            facebook_app_id=FACEBOOK_APP_ID,
            current_user=self.current_user
        )))

    def post(self):
        url = self.request.get('url')
        file = urllib2.urlopen(url)
        graph = facebook.GraphAPI(self.current_user['access_token'])
        response = graph.put_photo(file, "Test Image")
        photo_url = ("http://www.facebook.com/"
                     "photo.php?fbid={0}".format(response['id']))
        self.redirect(str(photo_url))


class LogoutHandler(BaseHandler):
    def get(self):
        if self.current_user is not None:
            self.session['user'] = None

        self.redirect('/')

jinja_environment = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__))
)

app = webapp2.WSGIApplication(
    [('/', HomeHandler), ('/logout', LogoutHandler)],
    debug=True,
    config=config
)

And here is the error:

INFO 2015-03-29 22:18:30,182 module.py:737] default: "GET / HTTP/1.1" 500 - ERROR 2015-03-29 22:19:07,986 wsgi.py:263] Traceback (most recent call last): File "/opt/google_appengine/google/appengine/runtime/wsgi.py", line 240, in Handle handler = config_handle.add_wsgi_middleware(self.LoadHandler()) File "/opt/google_appengine/google/appengine/runtime/wsgi.py", line 299, in _LoadHandler handler, path, err = LoadObject(self._handler) File "/opt/google_appengine/google/appengine/runtime/wsgi.py", line 85, in LoadObject obj = __import(path[0]) File "/home/juliano/Documents/Projetos/Fb2/fb.py", line 1, in import facebook ImportError: No module named facebook INFO 2015-03-29 22:19:08,003 module.py:737] default: "GET / HTTP/1.1" 500 -

I'm using these commands to add facebook python sdk:

virtualenv facebookenv
source facebookenv/bin/activate
pip install facebook-sdk
1

1 Answers

5
votes

You're not telling us how are you importing the library, so I assume you're treating it like other libraries, doing some sort of global install.

In GAE, you must have all the libraries you need in the same directory as your project, so they get uploaded alongside your code and can be accessed. Remember you run inside a sandbox and thus must take everything you need with you.

This means you need to download the facebook directory of the sdk and place it in the same directory where you have your app.yaml, and your import will be successful.