├── .env.test ├── .gitignore ├── app.py ├── app ├── __init__.py ├── config.py ├── mailer.py └── main.py └── requirements.txt /.env.test: -------------------------------------------------------------------------------- 1 | MAIL_HOST = 2 | MAIL_USERNAME = 3 | MAIL_PASSWORD = 4 | MAIL_PORT = -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | venv 3 | __pycache__ 4 | .vscode 5 | .idea -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | import uvicorn 2 | 3 | if __name__ == "__main__": 4 | uvicorn.run("app.main:app", host="127.0.0.1", reload=True) 5 | -------------------------------------------------------------------------------- /app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amoprocedures/fastapi-send-email/3dedb97c1ce4937a311e4a403806b698cd223137/app/__init__.py -------------------------------------------------------------------------------- /app/config.py: -------------------------------------------------------------------------------- 1 | import os 2 | from dotenv import load_dotenv 3 | from typing import List 4 | from pydantic import BaseModel 5 | 6 | load_dotenv() 7 | 8 | HOST = os.environ.get("MAIL_HOST") 9 | USERNAME = os.environ.get("MAIL_USERNAME") 10 | PASSWORD = os.environ.get("MAIL_PASSWORD") 11 | PORT = os.environ.get("MAIL_PORT", 465) 12 | 13 | 14 | class MailBody(BaseModel): 15 | to: List[str] 16 | subject: str 17 | body: str 18 | -------------------------------------------------------------------------------- /app/mailer.py: -------------------------------------------------------------------------------- 1 | from app.config import HOST, USERNAME, PASSWORD, PORT, MailBody 2 | from ssl import create_default_context 3 | from email.mime.text import MIMEText 4 | from smtplib import SMTP 5 | 6 | 7 | def send_mail(data: dict | None = None): 8 | msg = MailBody(**data) 9 | message = MIMEText(msg.body, "html") 10 | message["From"] = USERNAME 11 | message["To"] = ",".join(msg.to) 12 | message["Subject"] = msg.subject 13 | 14 | ctx = create_default_context() 15 | 16 | try: 17 | with SMTP(HOST, PORT) as server: 18 | server.ehlo() 19 | server.starttls(context=ctx) 20 | server.ehlo() 21 | server.login(USERNAME, PASSWORD) 22 | server.send_message(message) 23 | server.quit() 24 | return {"status": 200, "errors": None} 25 | except Exception as e: 26 | return {"status": 500, "errors": e} 27 | -------------------------------------------------------------------------------- /app/main.py: -------------------------------------------------------------------------------- 1 | from fastapi import FastAPI, BackgroundTasks 2 | from app.config import MailBody 3 | from app.mailer import send_mail 4 | 5 | app = FastAPI() 6 | 7 | 8 | @app.get("/") 9 | def index(): 10 | return {"status": "fastapi mailserver is running."} 11 | 12 | 13 | @app.post("/send-email") 14 | def schedule_mail(req: MailBody, tasks: BackgroundTasks): 15 | data = req.dict() 16 | tasks.add_task(send_mail, data) 17 | return {"status": 200, "message": "email has been scheduled"} 18 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi 2 | uvicorn 3 | python-dotenv --------------------------------------------------------------------------------