CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-social-auth-core

Python social authentication framework with 195+ backend providers for OAuth, OpenID Connect, and SAML integration.

Pending
Overview
Eval results
Files

strategy-interface.mddocs/

Strategy Interface

The strategy interface provides a framework-agnostic layer that adapts social-auth-core to work with any Python web framework. By implementing the strategy pattern, the library can integrate with Django, Flask, Pyramid, FastAPI, or any other web framework while maintaining consistent authentication behavior.

Capabilities

Base Strategy Class

The foundational strategy class that defines the interface for framework integration and provides common functionality.

class BaseStrategy:
    """
    Base strategy class for framework integration.
    
    The strategy pattern enables social-auth-core to work with any web framework
    by abstracting request/response handling, session management, and storage operations.
    """
    
    # Class constants
    ALLOWED_CHARS: str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    DEFAULT_TEMPLATE_STRATEGY: type = None  # Template strategy class
    SESSION_SAVE_KEY: str = "psa_session_id"  # Session key for saving state
    
    def __init__(self, storage=None, tpl=None):
        """
        Initialize strategy with storage and template handler.
        
        Parameters:
        - storage: Storage backend instance for data persistence
        - tpl: Template strategy instance for rendering (optional)
        """
        
    def setting(self, name: str, default=None, backend=None):
        """
        Get configuration setting value.
        
        Retrieves setting values with proper prefixing and backend-specific
        overrides, following the SOCIAL_AUTH_<BACKEND>_<SETTING> pattern.
        
        Parameters:
        - name: Setting name without prefix
        - default: Default value if setting not found
        - backend: Backend instance for backend-specific settings
        
        Returns:
        Setting value or default
        """
        
    def get_setting(self, name: str):
        """
        Get raw setting value without defaults.
        
        Parameters:
        - name: Full setting name
        
        Returns:
        Setting value or None if not found
        
        Raises:
        NotImplementedError: Must be implemented by subclasses
        """
        
    def request_data(self, merge=True):
        """
        Get request data (GET and POST parameters).
        
        Extracts data from the current HTTP request, typically combining
        query parameters and form data into a single dictionary.
        
        Parameters:
        - merge: Whether to merge GET and POST data (default: True)
        
        Returns:
        Dictionary of request parameters
        
        Raises:
        NotImplementedError: Must be implemented by subclasses
        """
        
    def request_host(self):
        """
        Get current request host.
        
        Returns:
        Host string from current request
        
        Raises:
        NotImplementedError: Must be implemented by subclasses
        """
        
    def redirect(self, url: str):
        """
        Create redirect response.
        
        Generates a framework-specific redirect response to the specified URL.
        
        Parameters:
        - url: URL to redirect to
        
        Returns:
        Framework-specific redirect response
        
        Raises:
        NotImplementedError: Must be implemented by subclasses
        """
        
    def html(self, content: str):
        """
        Create HTML response.
        
        Generates a framework-specific HTML response with the provided content.
        
        Parameters:
        - content: HTML content string
        
        Returns:
        Framework-specific HTML response
        
        Raises:
        NotImplementedError: Must be implemented by subclasses
        """
        
    def render_html(self, tpl=None, html=None, context=None):
        """
        Render HTML using template system.
        
        Parameters:
        - tpl: Template name/path (optional)
        - html: Raw HTML string (optional)
        - context: Template context dictionary (optional)
        
        Returns:
        Rendered HTML string
        """
        
    def build_absolute_uri(self, path=None):
        """
        Build absolute URI from relative path.
        
        Parameters:
        - path: Relative path (optional)
        
        Returns:
        Absolute URI string
        
        Raises:
        NotImplementedError: Must be implemented by subclasses
        """
        
    def absolute_uri(self, path=None):
        """
        Alias for build_absolute_uri.
        
        Parameters:
        - path: Relative path (optional)
        
        Returns:
        Absolute URI string
        """
        
    def get_pipeline(self, backend):
        """
        Get authentication pipeline configuration.
        
        Returns the list of pipeline functions to execute for authentication,
        allowing per-backend customization of the authentication flow.
        
        Parameters:
        - backend: Authentication backend instance
        
        Returns:
        Tuple of pipeline function names
        """
        
    def authenticate(self, *args, **kwargs):
        """
        Authenticate user with backend.
        
        Executes the authentication process using the specified backend,
        handling the complete pipeline execution and user creation/retrieval.
        
        Parameters:
        - backend: Authentication backend instance
        - Additional arguments for authentication pipeline
        
        Returns:
        Authenticated user instance or None
        """
        
    def clean_authenticate_args(self, *args, **kwargs):
        """
        Clean and validate authentication arguments.
        
        Processes authentication arguments to ensure they are in the correct
        format for the pipeline execution.
        
        Parameters:
        - Arguments and keyword arguments for authentication
        
        Returns:
        Tuple of (cleaned_args, cleaned_kwargs)
        """
        
    def continue_pipeline(self, partial):
        """
        Continue interrupted authentication pipeline.
        
        Resumes authentication flow from a partial pipeline state,
        typically after user input or email validation.
        
        Parameters:
        - partial: Partial pipeline data object
        
        Returns:
        Authentication result or further partial state
        """
        
    def session_get(self, name, default=None):
        """
        Get value from session.
        
        Parameters:
        - name: Session key name
        - default: Default value if key not found
        
        Returns:
        Session value or default
        
        Raises:
        NotImplementedError: Must be implemented by subclasses
        """
        
    def session_set(self, name, value):
        """
        Set value in session.
        
        Parameters:
        - name: Session key name
        - value: Value to store
        
        Raises:
        NotImplementedError: Must be implemented by subclasses
        """
        
    def session_pop(self, name, default=None):
        """
        Remove and return value from session.
        
        Parameters:
        - name: Session key name
        - default: Default value if key not found
        
        Returns:
        Session value or default
        
        Raises:
        NotImplementedError: Must be implemented by subclasses
        """
        
    def session_setdefault(self, name, value):
        """
        Set session value if key doesn't exist.
        
        Parameters:
        - name: Session key name
        - value: Default value to set
        
        Returns:
        Existing value or newly set value
        """
        
    def clean_partial_pipeline(self, token):
        """
        Clean partial pipeline data.
        
        Removes stored partial pipeline data after completion or cancellation.
        
        Parameters:
        - token: Partial pipeline token to clean
        """
        
    def random_string(self, length=12, allowed_chars=None):
        """
        Generate random string.
        
        Creates a random string for tokens, nonces, or other security purposes.
        
        Parameters:
        - length: String length (default: 12)
        - allowed_chars: Characters to use (default: ALLOWED_CHARS)
        
        Returns:
        Random string of specified length
        """
        
    def create_user(self, *args, **kwargs):
        """
        Create new user account.
        
        Delegates to storage backend to create a new user with provided details.
        
        Parameters:
        - User creation arguments
        
        Returns:
        New user instance
        """
        
    def get_user(self, user_id):
        """
        Get user by ID.
        
        Parameters:
        - user_id: User primary key
        
        Returns:
        User instance or None if not found
        """

Template Strategy Base Class

Base class for template rendering strategies that handle HTML output generation.

class BaseTemplateStrategy:
    """
    Base template strategy for rendering HTML content.
    
    Provides abstraction for template rendering that can be adapted
    to different template engines like Jinja2, Django templates, etc.
    """
    
    def __init__(self, strategy):
        """
        Initialize template strategy.
        
        Parameters:
        - strategy: Parent strategy instance
        """
        
    def render(self, tpl=None, html=None, context=None):
        """
        Render template or HTML string.
        
        Parameters:
        - tpl: Template name/path (optional)
        - html: Raw HTML string (optional)  
        - context: Template context dictionary (optional)
        
        Returns:
        Rendered HTML string
        
        Raises:
        ValueError: If neither tpl nor html provided
        """
        
    def render_template(self, tpl: str, context: dict | None):
        """
        Render template file.
        
        Parameters:
        - tpl: Template name/path
        - context: Template context dictionary
        
        Returns:
        Rendered HTML string
        
        Raises:
        NotImplementedError: Must be implemented by subclasses
        """
        
    def render_string(self, html: str, context: dict | None):
        """
        Render HTML string with context.
        
        Parameters:
        - html: Raw HTML string with template syntax
        - context: Template context dictionary
        
        Returns:
        Rendered HTML string
        
        Raises:
        NotImplementedError: Must be implemented by subclasses
        """

Framework Implementation Examples

Django Strategy Implementation

from django.conf import settings
from django.shortcuts import redirect
from django.http import HttpResponse
from social_core.strategy import BaseStrategy

class DjangoStrategy(BaseStrategy):
    """Django framework strategy implementation."""
    
    def __init__(self, storage, request=None, tpl=None):
        self.request = request
        super().__init__(storage, tpl)
    
    def get_setting(self, name):
        return getattr(settings, name, None)
    
    def request_data(self, merge=True):
        if not self.request:
            return {}
        if merge:
            data = self.request.GET.copy()
            data.update(self.request.POST)
            return data
        return self.request.GET if self.request.method == 'GET' else self.request.POST
    
    def request_host(self):
        return self.request.get_host() if self.request else ''
    
    def redirect(self, url):
        return redirect(url)
    
    def html(self, content):
        return HttpResponse(content, content_type='text/html')
    
    def build_absolute_uri(self, path=None):
        return self.request.build_absolute_uri(path) if self.request else path
    
    def session_get(self, name, default=None):
        return self.request.session.get(name, default) if self.request else default
    
    def session_set(self, name, value):
        if self.request:
            self.request.session[name] = value
    
    def session_pop(self, name, default=None):
        return self.request.session.pop(name, default) if self.request else default

Flask Strategy Implementation

from flask import request, session, redirect as flask_redirect, g
from social_core.strategy import BaseStrategy

class FlaskStrategy(BaseStrategy):
    """Flask framework strategy implementation."""
    
    def __init__(self, storage, tpl=None):
        super().__init__(storage, tpl)
    
    def get_setting(self, name):
        from flask import current_app
        return current_app.config.get(name)
    
    def request_data(self, merge=True):
        if merge:
            data = request.args.to_dict()
            data.update(request.form.to_dict())
            return data
        return request.args if request.method == 'GET' else request.form
    
    def request_host(self):
        return request.host
    
    def redirect(self, url):
        return flask_redirect(url)
    
    def html(self, content):
        from flask import Response
        return Response(content, content_type='text/html')
    
    def build_absolute_uri(self, path=None):
        return request.url_root.rstrip('/') + (path or '')
    
    def session_get(self, name, default=None):
        return session.get(name, default)
    
    def session_set(self, name, value):
        session[name] = value
    
    def session_pop(self, name, default=None):
        return session.pop(name, default)

FastAPI Strategy Implementation

from fastapi import Request
from fastapi.responses import RedirectResponse, HTMLResponse
from social_core.strategy import BaseStrategy

class FastAPIStrategy(BaseStrategy):
    """FastAPI framework strategy implementation."""
    
    def __init__(self, storage, request: Request = None, tpl=None):
        self.request = request
        super().__init__(storage, tpl)
    
    def get_setting(self, name):
        # Implement settings retrieval for FastAPI
        return getattr(settings, name, None)
    
    def request_data(self, merge=True):
        if not self.request:
            return {}
        # FastAPI request data handling
        return dict(self.request.query_params)
    
    def request_host(self):
        return self.request.client.host if self.request else ''
    
    def redirect(self, url):
        return RedirectResponse(url=url)
    
    def html(self, content):
        return HTMLResponse(content=content)
    
    def build_absolute_uri(self, path=None):
        if not self.request:
            return path
        base_url = f"{self.request.url.scheme}://{self.request.url.netloc}"
        return base_url + (path or '')
    
    def session_get(self, name, default=None):
        # Implement session handling for FastAPI
        return getattr(self.request.session, 'get', lambda k, d: d)(name, default)
    
    def session_set(self, name, value):
        # Implement session handling for FastAPI
        if hasattr(self.request, 'session'):
            self.request.session[name] = value
    
    def session_pop(self, name, default=None):
        # Implement session handling for FastAPI
        if hasattr(self.request, 'session'):
            return self.request.session.pop(name, default)
        return default

Configuration Integration

The strategy interface integrates with framework-specific configuration systems:

# Django settings.py
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = 'your-client-id'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = 'your-client-secret'
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/'
SOCIAL_AUTH_PIPELINE = (
    'social_core.pipeline.social_auth.social_details',
    # ... additional pipeline steps
)

# Flask config
class Config:
    SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = 'your-client-id'
    SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = 'your-client-secret'
    SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/'

# FastAPI settings
from pydantic import BaseSettings

class Settings(BaseSettings):
    SOCIAL_AUTH_GOOGLE_OAUTH2_KEY: str
    SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET: str
    SOCIAL_AUTH_LOGIN_REDIRECT_URL: str = '/'

The strategy interface enables social-auth-core to maintain consistent behavior across different web frameworks while adapting to each framework's specific patterns for request handling, response generation, session management, and configuration.

Install with Tessl CLI

npx tessl i tessl/pypi-social-auth-core

docs

authentication-actions.md

authentication-backends.md

exception-handling.md

index.md

pipeline-system.md

storage-models.md

strategy-interface.md

utilities-helpers.md

tile.json