import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import os from fastapi import FastAPI, HTTPException from pydantic import BaseModel, EmailStr # --- Configuration --- class SMTPSettings: # Use os.getenv for all settings, with default values for non-sensitive ones SMTP_HOST: str = os.getenv('SMTP_HOST', 'smtp.gmail.com') SMTP_PORT: int = int(os.getenv('SMTP_PORT', 587)) SMTP_USER: str = os.getenv('SMTP_USER') SMTP_PASS: str = os.getenv('SMTP_PASS') RECIPIENT_EMAIL: str = os.getenv('RECIPIENT_EMAIL') SENDER_NAME: str = os.getenv('SENDER_NAME', 'FastAPI Mailer') SENDER_EMAIL: str = os.getenv('SENDER_EMAIL') # Basic validation to ensure required fields are set if not all([SMTP_USER, SMTP_PASS, RECIPIENT_EMAIL, SENDER_EMAIL]): raise EnvironmentError("Missing one or more required environment variables: SMTP_USER, SMTP_PASS, RECIPIENT_EMAIL, SENDER_EMAIL") settings = SMTPSettings() # --- Pydantic Models --- class EmailRequest(BaseModel): subject: str body: str recipient_email: EmailStr = settings.RECIPIENT_EMAIL # Default to the configured recipient # --- Email Utility Function --- def send_email(subject: str, body: str, recipient_email: str): try: # Create a multipart message and set headers message = MIMEMultipart() message['From'] = f"{settings.SENDER_NAME} <{settings.SENDER_EMAIL}>" message['To'] = recipient_email message['Subject'] = subject # Add body to email message.attach(MIMEText(body, 'plain')) # Connect to the SMTP server with smtplib.SMTP(settings.SMTP_HOST, settings.SMTP_PORT) as server: server.starttls() # Secure the connection server.login(settings.SMTP_USER, settings.SMTP_PASS) server.sendmail(settings.SENDER_EMAIL, recipient_email, message.as_string()) return {"message": "Email sent successfully"} except Exception as e: print(f"Error sending email: {e}") raise HTTPException(status_code=500, detail=f"Failed to send email: {e}") # --- FastAPI Application --- app = FastAPI(title="FastAPI SMTP Server") @app.get("/") def read_root(): return {"message": "FastAPI SMTP Server is running."} @app.post("/send-test-email") def send_test_email_endpoint(): subject = "FastAPI SMTP Test Email" body = "This is a test email sent from the FastAPI server using the configured SMTP settings." try: send_email(subject, body, settings.RECIPIENT_EMAIL) return {"status": "success", "message": f"Test email sent to {settings.RECIPIENT_EMAIL}"} except HTTPException as e: raise e @app.post("/send-email") def send_email_endpoint(email_request: EmailRequest): try: send_email(email_request.subject, email_request.body, email_request.recipient_email) return {"status": "success", "message": f"Email sent to {email_request.recipient_email}"} except HTTPException as e: raise e if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)