2026-07-15

How to send an email using python after Google's policy update on not allowing just username and password?

Stefan Bogdanescu

Stefan Bogdanescu

Founder & Senior Architect

How to send an email using python after Google's policy update on not allowing just username and password?

Sending Emails with Python After Google's Security Overhaul: A Developer's Guide

The world of email security is constantly evolving. As developers who rely on external services to communicate—whether it’s internal notifications or customer communications—we often run into roadblocks when those services tighten their security protocols. The recent policy update by Google, which restricts access via simple username and password for third-party applications, has created a significant hurdle for developers attempting to automate email sending using standard Python libraries like smtplib.

If you are trying to send emails via Gmail programmatically and encountering authentication errors, this post will guide you beyond the failed attempt and show you the modern, secure, and scalable solutions available.

The Authentication Dilemma: Why Simple Login Fails

The issue you are facing with the smtplib.SMTPAuthenticationError is a direct result of Google enforcing stricter security measures. When Google deprecated the ability for third-party apps to use standard account passwords for access, relying on the old method simply won't work anymore. The system now demands more robust authentication methods, typically involving OAuth 2.0 or dedicated application credentials (like App Passwords).

Attempting to log in directly with your personal Gmail password through an SMTP server is no longer supported by Google’s infrastructure for external applications. This means that trying to brute-force the solution by changing the SMTP server address (smtp.gmail.com) will not resolve the core authentication failure; it only changes where you are attempting to log in, which still requires valid credentials recognized by the server.

The Developer Solution: Moving Beyond Personal Accounts

For any serious application development—especially when dealing with external accounts or high-volume messaging—relying on personal email accounts as a dedicated SMTP relay is fundamentally insecure and unreliable. As a senior developer, we must prioritize security and scalability.

Instead of fighting the restrictions of personal accounts, the correct architectural approach is to utilize professional, dedicated Transactional Email Services. These services are built specifically to handle high-volume sending reliably, manage deliverability, and comply with modern security standards like OAuth.

Recommended Approach: Using Transactional Email APIs

Services like SendGrid, Mailgun, or Amazon SES provide robust Application Programming Interfaces (APIs) that allow you to send emails directly without needing to manage SMTP credentials for a personal inbox. This shifts the responsibility of secure authentication and delivery management to an expert service.

When using these services with Python, you move away from managing complex smtplib configurations and instead use simple HTTP requests to their endpoints. This is cleaner, more secure, and infinitely more scalable. For building robust backend systems, adopting microservice principles and leveraging managed APIs aligns perfectly with modern architectural patterns, much like those emphasized in frameworks such as Laravel, where external services are integrated seamlessly into the application flow.

Python Implementation Example (Conceptual)

While we won't use live API keys here, this illustrates the concept of using a dedicated service instead of relying on direct SMTP login:

import requests
import json

def send_email_via_api(api_key, sender_email, recipient_email, subject, body):
    """
    Sends an email using a hypothetical transactional email API.
    This bypasses the need to manage personal SMTP credentials.
    """
    api_url = "https://api.transactionalmailservice.com/send" # Placeholder URL
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    payload = {
        "from": sender_email,
        "to": recipient_email,
        "subject": subject,
        "body": body
    }

    try:
        response = requests.post(api_url, headers=headers, data=json.dumps(payload))
        response.raise_for_status()  # Raise an exception for bad status codes (4xx or 5xx)
        print("Email sent successfully!")
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"Error sending email: {e}")
        return None

# Example usage would involve securely loading your API key
# send_email_via_api("YOUR_SECURE_API_KEY", "sender@example.com", "recipient@test.com", "Test Subject", "This is the body content.")

Conclusion

The lesson here is that when dealing with external communication protocols, always prioritize security and scalability over convenience. Trying to force personal email accounts into a third-party application role is an outdated and fragile approach. By migrating to dedicated transactional email APIs, you secure your data, ensure reliable delivery, and build systems that are resilient enough for production environments. Embrace these services; they are the future of robust application development.

Note: Blog content is currently available in English.

Tags:

Enhance your marketing setup with your own email marketing platform.

Join the growing number of SaaS platforms using Laravel Mail to offer email marketing solutions to their customers.