python-social-auth failure on Google App Engine - django

I am attempting to follow Tutorial: Adding Facebook/Twitter/Google Authentication to a Django Application. The only thing I am doing differently is that I am running DjangoAppEngine on the Google App Engine development server, otherwise everything is exactly as per the tutorial.
When I get to Step 4 and actually try to authenticate with Facebook, I am getting a runtime error:
error('illegal IP address string passed to inet_pton',)
Request Method: GET
Request URL: http://localtest.com:8080/o/complete/facebook/?redirect_state=FG4K...UG1k
Django Version: 1.6.11
Exception Type: RuntimeError
Exception Location: /Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py in _MakeRealSyncCall, line 235
Python Executable: /usr/local/opt/python/bin/python2.7
Python Version: 2.7.11
Obviously FB is passing an approval back to my app, as the request URL includes the callback path.
It appears that something in the GoogleAppEngineLauncher is trying to look up an address and is not receiving the right data in? I'm not really sure.
In trying to resolve this, I've come across a single comment somewhere suggesting to a user that SimpleAuth might be a better way to go, but I don't understand why and I'm not really sure I want to start over if I am just missing something obvious.
Does anyone know why I am getting this error and what I can do to correct it?

It happens because the Facebook SDK depends on the awesome requests library. However, requests doesn't work on Google App Engine since the platform has some restrictions. You have to use their urlfetch APIs to fetch external contents on Google App Engine.
So yes, the official Facebook SDK won't work. You have to roll your own solution or find one that works. SimpleAuth is one of the solution that is known to have worked.

UPDATE: the original answer (starting with 'HOWEVER') is no longer necessary, just use requests 2.10.0 or above, urllib3 1.15.1 or above, and requests_toolbelt 0.6.2 or above and perform the following in your main():
from requests_toolbelt.adapters import appengine
appengine.monkeypatch()
HOWEVER if you're using older versions of requests and/or urllib3, then you need the patches below:
This can be accomplished using a patched version of requests along with the requests-toolbelt package. Threads that apply:
HTTPS not working on Google App Engine #1905
urllib3 / Contrib Modules / Google App Engine
Fixes the AppEngineManager to work within the requests framework #763
Add AppEngineAdapter for GAE users #114
Adds a monkeypatch() function that ensures all Sessions use the AppEngineAdapter compatibility class. #119
I've applied all of this and now have python-social-auth and facebook-sdk working in both local test (the dev server) and production (full App Engine).

In your vendored libraries, ensure that you have requests_toolbelt. (pip install -t lib requests_toolbelt). Then "monkeypatch" appengine support before python-social-auth ever calls requests. In my project/wsgi.py, I added the following lines:
from requests_toolbelt.adapters import appengine
appengine.monkeypatch()
python-social-auth depends on requests, so it should also exist in your vendor directory.
You must also ensure you are using requests version >= 2.10.0. This has not been released yet, so you can fake it. Edit lib/requests/__init__.py so that __build__ = 0x021000. You also must upgrade the packaged version of urllib3 in the lib/requests/packages/ directory to the latest version.
This is what worked for me.

Related

Deploying Django on IIS and ngrok

I am trying to deploy Django on local host and "tunnel" using ngrok. The ngrok works but the IIS (Internet Information Manager) gives 500 Error <handler> scriptProcessor could not be found in <fastCGI> application configuration. Reference into fastcgi shows that this feature is deprecated but what is the replacement for serving Django using local server and ngrok. I also pip installed pyngrok. Can you suggest a clear solution?
FastCGI was deprecated in Django 6+ years ago, their docs say WSGI is the preferred alternative, and they provide a tutorial for types of WSGI deployments to get you started.
But you wouldn't use ngrok in this case, you'd serve it up with something like nginx or apache using a wsgi mod (also shown in their tutorial). Where you'd use ngrok is in development with Django's built-in dev server, and that's the full example provided in pyngrok's documentation.
Usually I'd provide actual sample code here, but what you're asking about are full end-to-end solutions, which is why I'm providing links. Without the full context and examples of what you've built, it's hard to tell you where it's going wrong—hard to provide specific solutions without specific examples of the problem. But these tutorials tutorials are for exactly what you're doing, so hopefully they can help you debug your own solution.

web2py error: requires web2py 2.15.5 or newer

I'm trying to launch a web2py app I made using pythonanywhere. I packaged the app and then uploaded it using the admin site, but now when I go to the page it's supposed to be on I get the error "requires web2py 2.15.5 or newer"
What does this mean? And is there a way I can go about solving this without needing to rewrite my webapp?
Thanks!
The error message is coming from these lines in the db.py model file of the scaffolding application:
if request.global_settings.web2py_version < "2.15.5":
raise HTTP(500, "Requires web2py 2.15.5 or newer")
Presumably you are somehow using the scaffolding application from web2py 2.15.5+ with an earlier version of web2py. You can try removing those lines, and everything may work, but there may be some code in the scaffolding app that relies on features available only in version 2.15.5 or later.
Alternatively, use the scaffolding app that comes with you installed version of web2py, or upgrade web2py to the latest version.

Integrating Google Calendar in a Django application running on app engine

I have been trying to integrate Google calendar into a Django application running on App Engine. I have managed to get the google-python-client-api working on my computer and even managed to get a Django app to run on my computer. However, I am unable to get the app compatible with the Django app that is deployed on the appengine. I tried importing all the dependencies - httplib, gdata, gflags but when I run that project it still gives me 500 error. Is there a way to make these 3 things play nice with each other or should I look to deploy Django natively somewhere else?
This is what finally solved my problem. :-
I went into oauth2client/client.py, and there's a conditional before the
CACHED_HTTP = httplib2.Http('.cache')
so I commented out the conditional so it uses the other case:
CACHED_HTTP = httplib2.Http()
automatically, and this one does not call makedirs.
Found on: - https://groups.google.com/forum/?fromgroups#!topic/google-appengine-python/tIwjdy28MzQ

Profiling django app hosted on apache2

I am having a django app which was hosted on apache2. The webapp basically makes a request to a server using thrift and renders the output on the webpage. I notice that webapp is really slow. I am not sure if it is machine problem or the API problem. I verified the API's and they are returning responses in few milliseconds. I am not sure, if django is the problem. Is there a way to profile the webapp. I am using python 2.5.2.
Please help.
Thank you
the simplest thing would be to enable logging, if you are using the latest django 1.3, it is nicely integrated with the python logging module, see:
http://docs.djangoproject.com/en/1.3/topics/logging/
here you can define a Formatter which saves the time each log message is written, see example in django docs:
http://docs.djangoproject.com/en/1.3/topics/logging/#an-example

Django + Google App Engine: app engine helper for django or use_library?

There seem to be 2 ways to use django 1.1 with GAE
Google App Engine helper for django
The new use_library() function
We currently use the first. Should we switch? And what's the difference between the two?
use_library loads an unpatched version of django in the production environment, so many things will not work out of the box on app-engine.
The helper applies a series of patches to the django libraries to enable things like Sessions, test, cache framework, etc. If you do not add your own copy of django into your helper application and you are using the latest release (r100 or higher), the helper first tries to load django 1.1 and if it does not succeed then loads 1.0. You can see this in appengine_django/__init__.py::LoadDjango.
On production GAE, django 1.1 always exists, so it is loaded first.
However, on your development environment the dev server SDK does not distribute Django. Therefore, it uses whatever version of Django it can find, first trying 1.1 and then 1.0 and if it cannot find one then throws UnacceptableVersionError.
You probably want to use the helper and not use_library because then you will need to patch the raw django libraries yourself, thus duplicating the work in the helper. Whether you distribute your own version of django, either as a folder or zip file is up to you. One of the advantages of not distributing your own copy of django is that as google applies security patches you automatically get them without having to redeploy your application.
the replacement is called django-nonrel (and djangoappengine)... you can find it at
http://www.allbuttonspressed.com ... with django-nonrel, you should be able to run pure Django apps on top of App Engine without tweaking your models!
FYI, there is at least one more way to get Django 1.1 in GAE.
Take a look at http://code.google.com/p/app-engine-patch/
It allows use to use most of Django features including Admin.
app-engine-patch seems to have died:
http://code.google.com/p/app-engine-patch/issues/detail?id=253
As of GAE 1.5.0, there's a much simpler way of specifying a Django version.
In appengine_congif.py, include the line
webapp_django_version = '1.2'
This will cause the use_libary() to happen under the covers.