Pass data from the pipeline to views in Django Python Social Auth

Question:

I was reading the documentation of Python Social Auth and got curious about the section of Interrupting the Pipeline (and communicating with views).

In there, we see the following pipeline code

In our pipeline code, we would have:

from django.shortcuts import redirect
from django.contrib.auth.models import User
from social_core.pipeline.partial import partial

# partial says "we may interrupt, but we will come back here again"
@partial
def collect_password(strategy, backend, request, details, *args, **kwargs):
    # session 'local_password' is set by the pipeline infrastructure
    # because it exists in FIELDS_STORED_IN_SESSION
    local_password = strategy.session_get('local_password', None)
    if not local_password:
        # if we return something besides a dict or None, then that is
        # returned to the user -- in this case we will redirect to a
        # view that can be used to get a password
        return redirect("myapp.views.collect_password")

    # grab the user object from the database (remember that they may
    # not be logged in yet) and set their password.  (Assumes that the
    # email address was captured in an earlier step.)
    user = User.objects.get(email=kwargs['email'])
    user.set_password(local_password)
    user.save()

    # continue the pipeline
    return

and the following view

def get_user_password(request):
    if request.method == 'POST':
        form = PasswordForm(request.POST)
        if form.is_valid():
            # because of FIELDS_STORED_IN_SESSION, this will get copied
            # to the request dictionary when the pipeline is resumed
            request.session['local_password'] = form.cleaned_data['secret_word']

            # once we have the password stashed in the session, we can
            # tell the pipeline to resume by using the "complete" endpoint
            return redirect(reverse('social:complete', args=("backend_name,")))
    else:
        form = PasswordForm()

    return render(request, "password_form.html")

Specially interested in the line

return redirect(reverse('social:complete', args=("backend_name,")))

which is used to redirect the user back to the pipeline using an already stablished backend.

We can see earlier in that page a condition that’s used to check which backend is being used.

def my_custom_step(strategy, backend, request, details, *args, **kwargs):
    if backend.name != 'my_custom_backend':
        return
    # otherwise, do the special steps for your custom backend

The question is, instead of manually adding it in the args=("backend_name,"), how can the pipeline communicate the correct backend to the view?

Answers:

One can simply add in the pipeline

request.session['backend'] = backend.name

and then the view becomes

backend_name = request.session['backend']
return redirect(reverse('social:complete', args=(backend_name)))
Answered By: Tiago Martins Peres