Python code to send emails with Gmail or another SMTP server
The idea is straightforward: the following snippet shows how email delivery works in Python through the smtplib library. If you prefer a video tutorial, visit the following URL: https://www.youtube.com/watch?v=vCFioQizM4w
You can download the full code from the following URL https://github.com/al118345/envio_email
As you can see, the code is simple. In gmail_user you provide the email address that will send the message and on line 12 you include the password in plain text format. Then line 19 defines the subject and line 20 defines the message body.
Finally, from line 26 onwards we establish the connection with the Gmail SMTP server. An SMTP server is the machine responsible for email delivery, acting as an electronic mail carrier over the Internet.
If you do not use Gmail, you can replace line 26 with the configuration of another provider. For example, Hotmail uses smtp.live.com.
Enable email sending with Gmail
By default, Gmail does not allow sending emails from third-party style applications like the one implemented in this article. To allow it, follow these steps.



A safer version for real projects
The original example is useful to understand SMTP, but in a real project you should not write the password directly in the source code. Use environment variables or a secret manager, and if you use Gmail, create an application password after enabling two-step verification.
The EmailMessage class also makes the code clearer because it separates subject, sender, recipient and body without manually building the raw message string.
Sending an attachment
If you need to send invoices, reports or generated PDFs, build the message with EmailMessage and attach the file as bytes. This keeps the code readable and avoids many encoding errors.
SMTP settings by provider
- Gmail: smtp.gmail.com, SSL port 465 or STARTTLS port 587.
- Outlook or Hotmail: smtp.office365.com, usually STARTTLS port 587.
- Custom hosting: check the SMTP server, port and encryption mode in the hosting control panel.
Common errors
- Authentication failed: verify the user, application password and two-step verification.
- Connection timeout: check port, firewall and whether your hosting provider blocks SMTP.
- Accents or special characters appear broken: use EmailMessage and UTF-8 content.
Production checklist
For a real application, email sending should normally live in the backend instead of the browser. The backend can protect SMTP credentials, validate recipients, apply rate limits and store delivery errors for later review.
If the email is triggered from Angular, expose a small API endpoint and let Python handle the SMTP connection. That architecture is safer than sending credentials to the frontend.
Deliverability and operational details
Sending an email successfully from Python does not guarantee that the message will reach the inbox. For a real domain, configure SPF, DKIM and DMARC records, use a recognizable sender and avoid changing the From address dynamically. Those DNS records help mailbox providers verify that the server is allowed to send on behalf of the domain.
It is also useful to store a delivery log with timestamp, recipient, provider response and internal identifier. Do not store the full message body unless the business case requires it. A small log makes it possible to retry temporary failures, detect blocked accounts and explain what happened when a user says they did not receive a notification.
Recommended architecture with Angular
In an Angular application, the browser should only send a request such as “send invoice” or “notify user”. The backend validates permissions, builds the message, reads templates, attaches files and talks to SMTP. This separation protects credentials and keeps email rules in one testable place.
Templates and retries
For maintainable projects, keep message templates outside the sending function and pass explicit variables such as user name, invoice number or confirmation link. Add retry rules only for temporary provider errors, never for invalid addresses or authentication failures. That keeps automation predictable and prevents accidental spam loops.
Related reading: secure Angular API with Nginx and FastAPI. proteger API Angular, Nginx y FastAPI.