diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 632084a29d..98de2cd1a0 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -70,6 +70,7 @@ from litellm.proxy.utils import ( get_instance_fn, ProxyLogging, _cache_user_row, + send_email, ) from litellm.proxy.secret_managers.google_kms import load_google_kms import pydantic @@ -1742,11 +1743,12 @@ async def user_auth(request: Request): ``` Requirements: - This uses [Resend](https://resend.com/) for sending emails. Needs these 2 keys in your .env: - ```env - RESEND_API_KEY = "my-resend-api-key" - RESEND_API_EMAIL = "my-sending-email" - ``` + SMTP server details saved in .env: + - os.environ["SMTP_HOST"] + - os.environ["SMTP_PORT"] + - os.environ["SMTP_USERNAME"] + - os.environ["SMTP_PASSWORD"] + - os.environ["SMTP_SENDER_EMAIL"] """ global prisma_client @@ -1756,15 +1758,6 @@ async def user_auth(request: Request): if user_email is None: raise HTTPException(status_code=400, detail="User email is none") - import os - - try: - import resend - except ImportError: - raise Exception( - "Resend package missing. Run `pip install litellm[extra_proxy]` to add missing dependencies." - ) - if prisma_client is None: # if no db connected, raise an error raise Exception("No connected db.") @@ -1785,16 +1778,15 @@ async def user_auth(request: Request): base_url = os.getenv("LITELLM_HOSTED_UI", "https://dashboard.litellm.ai/") - resend.api_key = os.getenv("RESEND_API_KEY") - params = { - "from": f"LiteLLM Proxy <{os.getenv('RESEND_API_EMAIL')}>", - "to": [user_email], + "sender_name": "LiteLLM Proxy", + "sender_email": os.getenv("SMTP_SENDER_EMAIL"), + "receiver_email": user_email, "subject": "Your Magic Link", "html": f" Follow this link, to login:\n\n{base_url}user/?token={response['token']}&user_id={response['user_id']}&page={page_params}", } - email = resend.Emails.send(params) + await send_email(**params) return "Email sent!" diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index d8d921a249..5da46ae5b1 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -7,6 +7,9 @@ from litellm.proxy.hooks.parallel_request_limiter import MaxParallelRequestsHand from litellm.proxy.hooks.max_budget_limiter import MaxBudgetLimiter from litellm.integrations.custom_logger import CustomLogger from fastapi import HTTPException, status +import smtplib +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart def print_verbose(print_statement): @@ -548,3 +551,42 @@ async def _cache_user_row(user_id: str, cache: DualCache, db: PrismaClient): key=cache_key, value=cache_value, ttl=600 ) # store for 10 minutes return + + +async def send_email(sender_name, sender_email, receiver_email, subject, html): + """ + smtp_host, + smtp_port, + smtp_username, + smtp_password, + sender_name, + sender_email, + """ + ## SERVER SETUP ## + smtp_host = os.getenv("SMTP_HOST") + smtp_port = os.getenv("SMTP_PORT", 587) # default to port 587 + smtp_username = os.getenv("SMTP_USERNAME") + smtp_password = os.getenv("SMTP_PASSWORD") + ## EMAIL SETUP ## + email_message = MIMEMultipart() + email_message["From"] = f"{sender_name} <{sender_email}>" + email_message["To"] = receiver_email + email_message["Subject"] = subject + + # Attach the body to the email + email_message.attach(MIMEText(html, "html")) + + try: + print_verbose(f"SMTP Connection Init") + # Establish a secure connection with the SMTP server + with smtplib.SMTP(smtp_host, smtp_port) as server: + server.starttls() + + # Login to your email account + server.login(smtp_username, smtp_password) + + # Send the email + server.send_message(email_message) + + except Exception as e: + print_verbose("An error occurred while sending the email:", str(e))