A Python OAuth 1.0 library providing comprehensive authentication, signing, and client capabilities.
—
Protocol-specific OAuth clients for SMTP and IMAP that provide XOAUTH authentication support. These extensions allow OAuth-authenticated access to email services that support the XOAUTH SASL mechanism.
OAuth-enabled IMAP client that extends Python's standard imaplib.IMAP4_SSL to support XOAUTH authentication for accessing IMAP email servers with OAuth credentials.
from oauth2.clients.imap import IMAP4_SSL
class IMAP4_SSL:
def authenticate(self, url: str, consumer, token):
"""
Authenticate IMAP connection using XOAUTH.
Args:
url (str): IMAP service URL for XOAUTH string generation
consumer: OAuth consumer credentials
token: OAuth token credentials
Raises:
ValueError: If consumer or token is invalid
"""OAuth-enabled SMTP client that extends Python's standard smtplib.SMTP to support XOAUTH authentication for sending email through OAuth-protected SMTP servers.
from oauth2.clients.smtp import SMTP
class SMTP:
def authenticate(self, url: str, consumer, token):
"""
Authenticate SMTP connection using XOAUTH.
Args:
url (str): SMTP service URL for XOAUTH string generation
consumer: OAuth consumer credentials
token: OAuth token credentials
Raises:
ValueError: If consumer or token is invalid
"""import oauth2
from oauth2.clients.imap import IMAP4_SSL
# OAuth credentials (obtain through Google OAuth flow)
consumer = oauth2.Consumer('your_consumer_key', 'your_consumer_secret')
token = oauth2.Token('user_access_token', 'user_access_token_secret')
# Connect to Gmail IMAP
imap_client = IMAP4_SSL('imap.gmail.com', 993)
# Authenticate using XOAUTH
gmail_url = 'https://mail.google.com/mail/b/user@gmail.com/imap/'
imap_client.authenticate(gmail_url, consumer, token)
# Use standard IMAP commands
imap_client.select('INBOX')
typ, data = imap_client.search(None, 'ALL')
# Get message IDs
message_ids = data[0].split()
print(f"Found {len(message_ids)} messages")
# Fetch first message
if message_ids:
typ, msg_data = imap_client.fetch(message_ids[0], '(RFC822)')
email_body = msg_data[0][1]
print(f"First message: {email_body[:200]}...")
# Close connection
imap_client.close()
imap_client.logout()import oauth2
from oauth2.clients.imap import IMAP4_SSL
# Yahoo OAuth credentials
consumer = oauth2.Consumer('yahoo_consumer_key', 'yahoo_consumer_secret')
token = oauth2.Token('yahoo_access_token', 'yahoo_access_token_secret')
# Connect to Yahoo IMAP
imap_client = IMAP4_SSL('imap.mail.yahoo.com', 993)
# Authenticate with Yahoo IMAP
yahoo_url = 'https://mail.yahoo.com/ws/mail/v1.1/soap'
imap_client.authenticate(yahoo_url, consumer, token)
# List available folders
typ, folders = imap_client.list()
for folder in folders:
print(f"Folder: {folder}")
# Select inbox and get message count
imap_client.select('INBOX')
typ, data = imap_client.search(None, 'UNSEEN')
unseen_count = len(data[0].split()) if data[0] else 0
print(f"Unseen messages: {unseen_count}")
imap_client.logout()import oauth2
from oauth2.clients.smtp import SMTP
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# OAuth credentials
consumer = oauth2.Consumer('gmail_consumer_key', 'gmail_consumer_secret')
token = oauth2.Token('user_access_token', 'user_access_token_secret')
# Connect to Gmail SMTP
smtp_client = SMTP('smtp.gmail.com', 587)
smtp_client.starttls()
# Authenticate using XOAUTH
gmail_url = 'https://mail.google.com/mail/b/user@gmail.com/smtp/'
smtp_client.authenticate(gmail_url, consumer, token)
# Create message
msg = MIMEMultipart()
msg['From'] = 'user@gmail.com'
msg['To'] = 'recipient@example.com'
msg['Subject'] = 'OAuth Test Email'
body = 'This email was sent using OAuth authentication!'
msg.attach(MIMEText(body, 'plain'))
# Send message
text = msg.as_string()
smtp_client.sendmail('user@gmail.com', 'recipient@example.com', text)
# Close connection
smtp_client.quit()import oauth2
from oauth2.clients.imap import IMAP4_SSL
import imaplib
import socket
consumer = oauth2.Consumer('consumer_key', 'consumer_secret')
token = oauth2.Token('token_key', 'token_secret')
try:
# Connect to IMAP server
imap_client = IMAP4_SSL('imap.gmail.com', 993)
# Authenticate
gmail_url = 'https://mail.google.com/mail/b/user@gmail.com/imap/'
imap_client.authenticate(gmail_url, consumer, token)
print("Authentication successful!")
except ValueError as e:
print(f"Invalid credentials: {e}")
except imaplib.IMAP4.abort as e:
print(f"IMAP connection aborted: {e}")
except imaplib.IMAP4.error as e:
print(f"IMAP error: {e}")
# Common errors:
# - Invalid credentials
# - Authentication failure
# - Server rejected XOAUTH
except socket.error as e:
print(f"Network error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
finally:
try:
imap_client.logout()
except:
passimport oauth2
from oauth2.clients.imap import IMAP4_SSL
import email
from datetime import datetime, timedelta
consumer = oauth2.Consumer('consumer_key', 'consumer_secret')
token = oauth2.Token('token_key', 'token_secret')
imap_client = IMAP4_SSL('imap.gmail.com', 993)
gmail_url = 'https://mail.google.com/mail/b/user@gmail.com/imap/'
imap_client.authenticate(gmail_url, consumer, token)
# Select inbox
imap_client.select('INBOX')
# Search for messages from last week
week_ago = (datetime.now() - timedelta(days=7)).strftime('%d-%b-%Y')
typ, data = imap_client.search(None, f'SINCE {week_ago}')
message_ids = data[0].split()
print(f"Found {len(message_ids)} messages from last week")
# Process each message
for msg_id in message_ids[:5]: # Process first 5 messages
typ, msg_data = imap_client.fetch(msg_id, '(RFC822)')
# Parse email
email_message = email.message_from_bytes(msg_data[0][1])
print(f"From: {email_message['From']}")
print(f"Subject: {email_message['Subject']}")
print(f"Date: {email_message['Date']}")
# Get email body
if email_message.is_multipart():
for part in email_message.walk():
if part.get_content_type() == "text/plain":
body = part.get_payload(decode=True).decode('utf-8')
print(f"Body preview: {body[:100]}...")
break
else:
body = email_message.get_payload(decode=True).decode('utf-8')
print(f"Body preview: {body[:100]}...")
print("-" * 50)
imap_client.close()
imap_client.logout()import oauth2
from oauth2.clients.smtp import SMTP
from email.mime.text import MIMEText
import time
consumer = oauth2.Consumer('consumer_key', 'consumer_secret')
token = oauth2.Token('token_key', 'token_secret')
# Connect once for multiple sends
smtp_client = SMTP('smtp.gmail.com', 587)
smtp_client.starttls()
gmail_url = 'https://mail.google.com/mail/b/user@gmail.com/smtp/'
smtp_client.authenticate(gmail_url, consumer, token)
# Send multiple emails
recipients = ['user1@example.com', 'user2@example.com', 'user3@example.com']
for recipient in recipients:
msg = MIMEText(f'Hello {recipient}! This is a personalized message.')
msg['From'] = 'sender@gmail.com'
msg['To'] = recipient
msg['Subject'] = 'Bulk Email Test'
try:
smtp_client.sendmail('sender@gmail.com', recipient, msg.as_string())
print(f"Email sent to {recipient}")
# Rate limiting
time.sleep(1)
except Exception as e:
print(f"Failed to send to {recipient}: {e}")
smtp_client.quit()https://mail.google.com/mail/b/{email}/imap/https://mail.google.com/mail/b/{email}/smtp/https://mail.yahoo.com/ws/mail/v1.1/soaphttps://mail.yahoo.com/The XOAUTH mechanism works with any email provider that supports it. Check provider documentation for:
The clients use oauth2.build_xoauth_string() to generate XOAUTH authentication strings in the format:
GET {url} oauth_consumer_key="{key}",oauth_nonce="{nonce}",oauth_signature="{signature}",oauth_signature_method="HMAC-SHA1",oauth_timestamp="{timestamp}",oauth_token="{token}",oauth_version="1.0"SMTP client automatically base64-encodes the XOAUTH string as required by the SMTP AUTH command, while IMAP passes the string directly to the IMAP AUTHENTICATE command.
Install with Tessl CLI
npx tessl i tessl/pypi-oauth2