blog.dbrgn.ch

Migrating from django-social-auth to python-social-auth

written on Thursday, October 30, 2014 by

I recently ported an app with Google OAuth2 integration from django-social-auth to python-social-auth. Here are some things I noticed that were not mentioned in the porting docs.

(Note: In the following text I will refer to django-social-auth and python-social-auth as DSA and PSA in order to keep my typing sanity.)

Migrating Database

Last week I migrated the application to Django 1.7. Now that I also switched from DSA to PSA, I wanted to run the migrations but discovered a problem...

$ ./manage.py migrate default
Operations to perform:
  Target specific migration: 0001_initial, from default
Running migrations:
  Applying default.0001_initial...Traceback (most recent call last):

(...)

django.db.utils.ProgrammingError: relation "social_auth_association" already exists

(Note that default is the short name of the PSA Django app, because the full path is social.apps.django_app.default.)

The problem is that PSA tried to create the initial models, but failed because they already existed back from DSA.

The porting docs mention that "the models table names were defined to be compatible with those used on django-social-auth, so data is not needed to be migrated". Therefore we can safely skip the initial migration by faking it:

$ ./manage.py migrate default 0001 --fake
Operations to perform:
  Target specific migration: 0001_initial, from default
Running migrations:
  Applying default.0001_initial... FAKED

Now we're at a valid state and can run all other migrations:

$ ./manage.py migrate

Refreshing an Access Token

The old way to refresh an access token was the following line of code:

user.social_auth.get().refresh_token()

This fails with an exception though:

TypeError: refresh_token() takes at least 2 arguments (1 given)

The reason is that the refresh_token method now expects a strategy instance as argument. The Django strategy can be loaded using the following code snippet:

from social.apps.django_app.utils import load_strategy

django_stategy = load_strategy()
user.social_auth.get().refresh_token(django_stategy)

UserSocialAuth.tokens

In DSA, the tokens property of a UserSocialAuth instance used to return a dictionary of tokens, containing keys like access_token. Now it returns the access token directly. I created an issue in the PSA issue tracker, because I find the naming a bit confusing.

Simplified Pipeline Extension

If you want to extend the default pipeline, the old way was to copy-paste the code from the DSA sourcecode and add your custom pipeline entries to it. In PSA, you now have a DEFAULT_AUTH_PIPELINE tuple that can be used in your definition.

from social.pipeline import DEFAULT_AUTH_PIPELINE

SOCIAL_AUTH_PIPELINE = DEFAULT_AUTH_PIPELINE + (
    'config.social_auth.fetch_account_access',
)

This entry was tagged django and python