OAuthlib authentication support for Requests.
—
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.
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)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())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"""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 urldecodeThe library supports all OAuth 1.0a signature methods:
OAuth parameters can be included in different parts of the request:
Install with Tessl CLI
npx tessl i tessl/pypi-requests-oauthlib