CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-requests-oauthlib

OAuthlib authentication support for Requests.

Pending
Overview
Eval results
Files

oauth1.mddocs/

OAuth 1.0a Implementation

OAuth 1.0a authentication support with complete workflow management, request signing, and token handling. Supports all signature methods and provides both low-level authentication and high-level session-based workflows.

Capabilities

OAuth1 Authentication Class

Low-level authentication handler that signs individual requests using OAuth 1.0a protocol. Implements the requests.auth.AuthBase interface for seamless integration with existing request code.

class OAuth1(requests.auth.AuthBase):
    def __init__(
        self,
        client_key: str,
        client_secret: str = None,
        resource_owner_key: str = None,
        resource_owner_secret: str = None,
        callback_uri: str = None,
        signature_method: str = SIGNATURE_HMAC,
        signature_type: str = SIGNATURE_TYPE_AUTH_HEADER,
        rsa_key: str = None,
        verifier: str = None,
        decoding: str = "utf-8",
        client_class = None,
        force_include_body: bool = False,
        **kwargs
    ):
        """
        Create OAuth 1.0a authentication handler.

        Args:
            client_key (str): Client identifier from OAuth provider
            client_secret (str, optional): Client secret for HMAC/plaintext signatures
            resource_owner_key (str, optional): Request token or access token
            resource_owner_secret (str, optional): Token secret from provider
            callback_uri (str, optional): Callback URL for authorization
            signature_method (str): Signature method (SIGNATURE_HMAC, SIGNATURE_RSA, SIGNATURE_PLAIN)
            signature_type (str): Parameter placement (SIGNATURE_TYPE_AUTH_HEADER, SIGNATURE_TYPE_QUERY, SIGNATURE_TYPE_BODY)
            rsa_key (str, optional): RSA private key for RSA-SHA1 signing
            verifier (str, optional): Verifier from authorization step
            decoding (str): Character encoding (default: "utf-8")
            client_class: Custom oauthlib.oauth1.Client subclass
            force_include_body (bool): Include request body in non-form requests
        """

Usage Example:

import requests
from requests_oauthlib import OAuth1

# Create auth handler
auth = OAuth1(
    'client_key',
    client_secret='client_secret',
    resource_owner_key='access_token',
    resource_owner_secret='token_secret'
)

# Use with requests
response = requests.get('https://api.example.com/protected', auth=auth)

OAuth1Session Workflow Class

High-level session class that extends requests.Session with OAuth 1.0a workflow methods. Handles the complete three-legged OAuth dance including request token fetching, authorization, and access token exchange.

class OAuth1Session(requests.Session):
    def __init__(
        self,
        client_key: str,
        client_secret: str = None,
        resource_owner_key: str = None,
        resource_owner_secret: str = None,
        callback_uri: str = None,
        signature_method: str = SIGNATURE_HMAC,
        signature_type: str = SIGNATURE_TYPE_AUTH_HEADER,
        rsa_key: str = None,
        verifier: str = None,
        client_class = None,
        force_include_body: bool = False,
        **kwargs
    ):
        """
        Create OAuth 1.0a session for complete workflow management.

        Args:
            client_key (str): Client identifier from OAuth provider
            client_secret (str, optional): Client secret
            resource_owner_key (str, optional): Request token or access token
            resource_owner_secret (str, optional): Token secret
            callback_uri (str, optional): Callback URL for authorization
            signature_method (str): Signature method
            signature_type (str): Parameter placement method
            rsa_key (str, optional): RSA private key for RSA-SHA1
            verifier (str, optional): Authorization verifier
            client_class: Custom client class
            force_include_body (bool): Include body in signature
        """

Properties:

@property
def token(self) -> dict:
    """Token dictionary with oauth_token, oauth_token_secret, oauth_verifier"""

@token.setter
def token(self, value: dict):
    """Set token from dictionary"""

@property
def authorized(self) -> bool:
    """True if session has valid OAuth credentials"""

Methods:

def authorization_url(
    self,
    url: str,
    request_token: str = None,
    **kwargs
) -> str:
    """
    Create authorization URL for user consent.

    Args:
        url (str): Authorization endpoint URL
        request_token (str, optional): Request token to include
        **kwargs: Additional parameters for URL

    Returns:
        str: Complete authorization URL
    """

def fetch_request_token(
    self,
    url: str,
    realm: list = None,
    **request_kwargs
) -> dict:
    """
    Fetch request token from provider.

    Args:
        url (str): Request token endpoint URL
        realm (list, optional): List of realms for access
        **request_kwargs: Additional arguments for request

    Returns:
        dict: Token response with oauth_token and oauth_token_secret

    Raises:
        TokenRequestDenied: If request fails
        TokenMissing: If response lacks required token
    """

def fetch_access_token(
    self,
    url: str,
    verifier: str = None,
    **request_kwargs
) -> dict:
    """
    Fetch access token using authorization verifier.

    Args:
        url (str): Access token endpoint URL
        verifier (str, optional): Authorization verifier
        **request_kwargs: Additional arguments for request

    Returns:
        dict: Access token response

    Raises:
        VerifierMissing: If no verifier is set
        TokenRequestDenied: If request fails
    """

def parse_authorization_response(self, url: str) -> dict:
    """
    Extract parameters from authorization callback URL.

    Args:
        url (str): Full callback URL from provider

    Returns:
        dict: Parsed parameters including verifier
    """

def rebuild_auth(self, prepared_request, response):
    """
    Handle redirects by stripping and rebuilding authentication.
    
    When being redirected we should always strip Authorization header,
    since nonce may not be reused as per OAuth spec.

    Args:
        prepared_request: The prepared request object
        response: The response that triggered the redirect
    """

Complete Workflow Example:

from requests_oauthlib import OAuth1Session

# Step 1: Create session
oauth = OAuth1Session(
    'client_key',
    client_secret='client_secret',
    callback_uri='https://example.com/callback'
)

# Step 2: Fetch request token
request_token_url = 'https://api.provider.com/oauth/request_token'
token = oauth.fetch_request_token(request_token_url)
print(f"Request token: {token}")

# Step 3: Get authorization URL
authorization_url = 'https://api.provider.com/oauth/authorize'
auth_url = oauth.authorization_url(authorization_url)
print(f"Go to: {auth_url}")

# Step 4: Parse callback (after user authorization)
callback_url = input("Enter the full callback URL: ")
verifier_data = oauth.parse_authorization_response(callback_url)

# Step 5: Fetch access token
access_token_url = 'https://api.provider.com/oauth/access_token'
access_token = oauth.fetch_access_token(access_token_url)
print(f"Access token: {access_token}")

# Step 6: Make authenticated requests
response = oauth.get('https://api.provider.com/user')
print(response.json())

Exception Classes

class TokenRequestDenied(ValueError):
    """Raised when token request is denied by provider"""
    def __init__(self, message: str, response):
        """
        Args:
            message (str): Error description
            response: HTTP response object
        """
    
    @property
    def status_code(self) -> int:
        """HTTP status code from failed request"""

class TokenMissing(ValueError):
    """Raised when token is missing from provider response"""
    def __init__(self, message: str, response):
        """
        Args:
            message (str): Error description
            response: Response that lacks token
        """

class VerifierMissing(ValueError):
    """Raised when OAuth verifier is missing for access token request"""

Utility Functions

def urldecode(body: str) -> dict:
    """
    Parse URL-encoded or JSON response to Python dictionary.

    Args:
        body (str): Response body to parse

    Returns:
        dict: Parsed parameters
    """

Import:

from requests_oauthlib.oauth1_session import urldecode

Signature Methods

The library supports all OAuth 1.0a signature methods:

  • SIGNATURE_HMAC (default): HMAC-SHA1 signatures using client secret and token secret
  • SIGNATURE_RSA: RSA-SHA1 signatures using RSA private key
  • SIGNATURE_PLAIN: Plain text signatures (not recommended for production)

Signature Types

OAuth parameters can be included in different parts of the request:

  • SIGNATURE_TYPE_AUTH_HEADER (default): Parameters in Authorization header
  • SIGNATURE_TYPE_QUERY: Parameters in URL query string
  • SIGNATURE_TYPE_BODY: Parameters in request body (form-encoded requests only)

Security Considerations

  • Always use HTTPS endpoints in production
  • Store client secrets and tokens securely
  • Use appropriate signature methods (HMAC or RSA recommended)
  • Implement proper token storage and renewal workflows
  • Validate callback URLs to prevent authorization hijacking

Install with Tessl CLI

npx tessl i tessl/pypi-requests-oauthlib

docs

compliance-fixes.md

index.md

oauth1.md

oauth2.md

tile.json