Fastapi mail system sending mails(individual, bulk) attachments(individual, bulk)

Overview

Fastapi-mail

The fastapi-mail simple lightweight mail system, sending emails and attachments(individual && bulk)

MIT licensed GitHub stars GitHub forks GitHub issues Downloads

🔨 Installation

 $ pip install fastapi-mail

Documentation: FastApi-MAIL

The key feature are:

  • sending emails with either with FastApi or using asyncio module
  • sending emails using FastApi backroung task managment
  • sending files either from form-data or files from server
  • Using Jinja2 HTML Templates
  • email utils (utility allows you to check temporary email addresses, you can block any email or domain)
  • email utils has two avalibale class DefaultChecker and WhoIsXmlApi
  • Unittests using FastapiMail

More information on Getting-Started

Guide

from fastapi import FastAPI, BackgroundTasks, UploadFile, File, Form
from starlette.responses import JSONResponse
from starlette.requests import Request
from fastapi_mail import FastMail, MessageSchema,ConnectionConfig
from pydantic import BaseModel, EmailStr
from typing import List



class EmailSchema(BaseModel):
    email: List[EmailStr]


conf = ConnectionConfig(
    MAIL_USERNAME = "YourUsername",
    MAIL_PASSWORD = "strong_password",
    MAIL_FROM = "[email protected]",
    MAIL_PORT = 587,
    MAIL_SERVER = "your mail server",
    MAIL_TLS = True,
    MAIL_SSL = False,
    USE_CREDENTIALS = True
)

app = FastAPI()


template = """
<p>Thanks for using Fastapi-mail</p> 
"""


@app.post("/email")
async def simple_send(email: EmailSchema) -> JSONResponse:

    message = MessageSchema(
        subject="Fastapi-Mail module",
        recipients=email.dict().get("email"),  # List of recipients, as many as you can pass 
        body=html,
        subtype="html"
        )

    fm = FastMail(conf)
    await fm.send_message(message)
    return JSONResponse(status_code=200, content={"message": "email has been sent"})     

List of Examples

for more examples of using fastapi-mail please check example section

Contributing

Fell free to open issue and send pull request.

Contributors

Thanks goes to these wonderful people ( 🚧 ):


Sabuhi Shukurov

💬 👀 🚧

Tural Muradov

📖 👀 🔧

Hasan Aliyev

📖 🚧 👀

Ashwani

🚧

Leon Xu

🚧

Gabriel Oliveira

📖 🚧

Onothoja Marho

📖 🚧 🔧

Tim Kiely

🚧

Dmitriy Solodkiy

🚧

Peter Boers

🚧

This project follows the all-contributors specification. Contributions of any kind are welcome!

Before you start please read CONTRIBUTING

LICENSE

MIT

Comments
  • send_message as background task is not working

    send_message as background task is not working

    Mails are not going out in background.

    We have backgrounds tasks working well in other endpoints. Any idea of what could be the issue?

    We tried without a template (exactly like your example) and it does not work either.

    class SigninEmailSchema(BaseModel):
        recipient: EmailStr
        a: str
        b: str
    
    
    @router.post('/email/signin')
    async def send_signin_email(
            bg: BackgroundTasks,
            contents: SigninEmailSchema,
        ) -> JSONResponse:
    
        message = MessageSchema(
            subject = ' subject ',
            recipients = [contents.recipient],
            template_body = {
                'a': contents.a,
                'b': contents.b,
            },
        )
    
        fm = FastMail(conf)
    
        #await fm.send_message(message, template_name='signin.html') # WORKS
        bg.add_task(fm.send_message, message, template_name='signin.html') # DOES NOT WORK
    
        return JSONResponse(
            status_code=200,
            content = {'message': 'email was sent'},
    )
    
    opened by pepegc 21
  • remove TEMPLATE_FOLDER validation because Pydantic DirectoryPath already does that…

    remove TEMPLATE_FOLDER validation because Pydantic DirectoryPath already does that…

    fastapi-mail ConnectionConfig does not need to check for a valid TEMPLATE_FOLDER value since pydantic's DirectoryPath already does that: https://pydantic-docs.helpmanual.io/usage/types/#pydantic-types

    opened by andredias 16
  • fastapi 0.70.0

    fastapi 0.70.0

    fastapi 0.70.0

    Because fastapi-mail (1.0.1) depends on fastapi (>=0.68.1,<0.69.0) and no versions of fastapi-mail match >1.0.1,<2.0.0, fastapi-mail (>=1.0.1,<2.0.0) requires fastapi (>=0.68.1,<0.69.0). So, because hashjump co api depends on both fastapi (^0.70.0) and fastapi-mail (^1.0.1), version solving failed.

    opened by clerkzhang 9
  • [Question] Gmail

    [Question] Gmail "MAIL_USERNAME" ConnectionConfig

    How do i use gmail alias with "MAIL_USERNAME"? Using gmail, i keep getting bad credential error.

    What i'm trying to achieve is SportJom [email protected]

    but that was not possible if my "MAIL_USERNAME" is not the email address.

    For "MAIL_USERNAME" I have to use my full email address as the username. Is this just gmail issue?

    opened by ihsanmohamad 9
  • path_traversal with venv

    path_traversal with venv

    Hello!

    I'm using poetry and got an issue with TEMPLATE_FOLDER option with exception TemplateFolderDoesNotExist because it not pass path_traversal check.

    After debug I found out that:

    • base = Path(__file__).parent.parent inside path_traversal equals to PosixPath('/Users/netstuff/Sites/mailout/api/.venv/lib/python3.9/site-packages')
    • passed to TEMPLATE_FOLDER path equals to PosixPath('/Users/netstuff/Sites/mailout/api/src/mailout/templates/mail')

    What can I do with it? Thank you.

    opened by netstuff 8
  • Feature adding reply to support

    Feature adding reply to support

    Please let me know what changes you'd like. I went back to RFC 2822 to check what I've done is correct, and I've tested with this version as a local package in my own project. It seems to work correctly but I would appreciate your advice.

    I have run the tests but did not create the SMTP endpoint. I'm confident of my changes, though.

    opened by jdvalentine 8
  • Jinja2 templates not getting populated with body

    Jinja2 templates not getting populated with body

    I'm trying to send an HTML rendered email with Jinja2 templates, but no context is being send.

    Here's an example of the message I'm sending...

    message = MessageSchema(
        subject="Grove Password Reset",
        recipients=[form.email],
        body={"email": email, "other": "some random string"},
        subtype="html",
    )
    
    fast_mail = FastMail(settings.EMAIL_CONFIG)
    
    background_tasks.add_task(fast_mail.send_message, message, template_name="template.html")
    

    The email is sent correctly, and the template shows up as a rendered HTML email, but none of the information from the body parameter gets rendered.

    opened by fletcheaston 7
  • Send local attachments

    Send local attachments

    Hello, How can i send files from local directory? when i give a "./app/files/file.pdf" path, I receive this error:

    AttributeError: 'bytes' object has no attribute 'read'

    or

    attachments field type incorrect, must be UploadFile or path

    opened by UtopiaBe 7
  • coroutine was never awaited error

    coroutine was never awaited error

    Hi, I created a function like this

    async def email_simple_send() -> JSONResponse:
        email = EmailSchema(email=['[email protected]'])
        html = """<p>Hi this test mail, thanks for using Fastapi-mail</p> """
        message = MessageSchema(
            subject="Test",
            recipients=email.dict().get("email"),
            body=html,
            subtype=MessageType.html)  # subtype=MessageType.plain
        fm = FastMail(conf)
        # fm.send_message(message, template_name='email.html')
        await fm.send_message(message)
        return JSONResponse(status_code=200, content={"message": "email has been sent"})
    

    How am I supposed to call it ? I tried this

    def main():
        email_simple_send()
        return None
    
    if __name__ == "__main__":
        main()
    

    But I get this error

    RuntimeWarning: coroutine 'email_simple_send' was never awaited  email_simple_send()
    

    Any idea ? Thanks.

    opened by marc-odp 6
  • fastapi_mail.errors.ConnectionErrors on gmail smtp

    fastapi_mail.errors.ConnectionErrors on gmail smtp

    I am getting the following error when trying the first basic example here:

    fastapi_mail.errors.ConnectionErrors: Exception raised (535, '5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials l33-20020a0568302b2100b005cdad9100desm5879477otv.40 - gsmtp'), check your credentials or email service configuration

    MAIL_USERNAME=asd
    MAIL_PASSWORD=<16-digit app password generated in gmail admin, 2step verification enabled>
    MAIL_FROM=<matching email>
    MAIL_PORT=587
    MAIL_SERVER=smtp.gmail.com
    MAILFROM_NAME=asd
    MAIL_TLS=1
    MAIL_SSL=0
    USE_CREDENTIALS=1
    VALIDATE_CERTS=1
    

    I tried with personal mail/pwd for testing and didn't work. Then I tried with validated mail/pwd currently being used in production on another (flask) app and it didn't work.

    opened by pepegc 6
  • intuitive email mocking with fastapi-mail

    intuitive email mocking with fastapi-mail

    A way to allow unit testing of application's email routes withpytestor unittest via mocking by fastapi_mail without actually sending out any emails.

    application.py

    conf = ConnectionConfig(
        MAIL_USERNAME = "YourUsername",
        MAIL_PASSWORD = "strong_password",
        MAIL_FROM = "[email protected]",
        MAIL_PORT = 587,
        MAIL_SERVER = "your mail server",
        MAIL_TLS = True,
        MAIL_SSL = False,
        TEMPLATE_FOLDER='./email templates folder',
        # if no indicated SUPPRESS_SEND defaults to 0 (false) as below
        SUPPRESS_SEND=0
    )
    
    fm = FastMail(conf)
    
    @app.post("/email")
    async def simple_send(email: EmailSchema) -> JSONResponse:
        message = MessageSchema(
            subject="Testing",
            recipients=email.dict().get("email"),  # List of recipients, as many as you can pass 
            body=html,
            subtype="html"
            )
        await fm.send_message(message)
        return JSONResponse(status_code=200, content={"message": "email has been sent"})
    

    test.py

    from application.py import fm
    
    # make this setting available as a fixture through conftest.py if you plan on using pytest
    fm.config.SUPPRESS_SEND = 1
    
    with fm.record_messages() as outbox:
        response = app.test_client.get("/email")
        assert len(outbox) == 1
        assert outbox[0].subject == "Testing"
    

    This will allow for more intuitive application mail testing via mocking and avoids bugging out email servers with dummy emails resulting in a potential block from that server, and this also eliminates the complexity of having to create a personal server to test sending outgoing mails.

    This PR was heavily influenced by the Flask-Mail testing function

    opened by maestro-1 6
  • How to send email as Jinja template with image?

    How to send email as Jinja template with image?

    I use FastAPI-Mail and Celery to send notifications in the background. I want to place the static image in the template and send it to the customer.

    I discovered that a url_for function returns an absolute URL and can be used in img tag as src.

    image

    The problem is that I get such an error, and I don't know how to solve it:

    Traceback (most recent call last):
      File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 451, in trace_task
        R = retval = fun(*args, **kwargs)
      File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 734, in __protected_call__
        return self.run(*args, **kwargs)
      File "/code/app/tasks/worker.py", line 17, in create_task
        send_birthday_reminder(
      File "/usr/local/lib/python3.10/site-packages/asgiref/sync.py", line 218, in __call__
        return call_result.result()
      File "/usr/local/lib/python3.10/concurrent/futures/_base.py", line 451, in result
        return self.__get_result()
      File "/usr/local/lib/python3.10/concurrent/futures/_base.py", line 403, in __get_result
        raise self._exception
      File "/usr/local/lib/python3.10/site-packages/asgiref/sync.py", line 284, in main_wrap
        result = await self.awaitable(*args, **kwargs)
      File "/code/app/email/email.py", line 29, in send_birthday_reminder
        await fm.send_message(
      File "/usr/local/lib/python3.10/site-packages/fastapi_mail/fastmail.py", line 105, in send_message
        msg = await self.__prepare_message(message, template)
      File "/usr/local/lib/python3.10/site-packages/fastapi_mail/fastmail.py", line 71, in __prepare_message
        message.template_body = await self.__template_message_builder(
      File "/usr/local/lib/python3.10/site-packages/fastapi_mail/fastmail.py", line 85, in __template_message_builder
        return template.render(**template_data)
      File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
        self.environment.handle_exception()
      File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
        raise rewrite_traceback_stack(source=source)
      File "/code/app/templates/email/birthday_reminder.html", line 1, in top-level template code
        {% extends './base.html' %}
      File "/code/app/templates/base.html", line 11, in top-level template code
        {% block content %} {% endblock %}
      File "/code/app/templates/email/birthday_reminder.html", line 4, in block 'content'
        <img src="{{ url_for('static', path='img/birthday_alarm.png') }}" />
      File "/usr/local/lib/python3.10/site-packages/jinja2/utils.py", line 83, in from_obj
        if hasattr(obj, "jinja_pass_arg"):
    jinja2.exceptions.UndefinedError: 'url_for' is undefined
    

    How can I solve this issue? Is there a better way to send a template with an image?

    opened by morento101 1
  • How to use a remote folder for TEMPLATE_FOLDER?

    How to use a remote folder for TEMPLATE_FOLDER?

    I want to use templates that are located on a different server, but I can not assign the path of remote folder to TEMPLATE_FOLDER. Here is the example path for a remote template that I wish to use:

    https://raw.githubusercontent.com/smohadjer/slaven/master/app/content/email_templates/camp.html

    Any idea how I can use this template for my email using TEMPLATE_FOLDER?

    opened by smohadjer 1
  • Can't upgrade to fastapi==0.88.0 because

    Can't upgrade to fastapi==0.88.0 because "fastapi-mail 1.2.2 depends on starlette<0.22.0"

    The same problem as in previous issue https://github.com/sabuhish/fastapi-mail/issues/157 but for the next version of the library. Do you consider to make less restrictive version dependency? 🙏🏻

    opened by ilBEastli 6
  • Allow setting of msgid and msgid domain

    Allow setting of msgid and msgid domain

    1. Extra 'msgid domain' ConnectionConfig parameter

    Set your own domain instead of the currently used local hostname.

    MAIL_MSGID_DOMAIN: Optional[str] = None

    1. Extra 'msgid domain' MailMsg parameter

    Dynamically set your own 'msgid domain' together with the MailMsg parameters.

    :param msgid_domain

    Overrides MAIL_MSGID_DOMAIN parameter

    1. Extra 'msgid' MailMsg parameter

    Dynamically set the 'msgid' together with the MailMsg parameters.

    :param msgid

    opened by mybooc 1
  • multipart html and plain text emails

    multipart html and plain text emails

    opened by msb 5
Releases(1.2.4)
Owner
Sabuhi
open science enthusiast loves python, go, and shell. Enjoys Linux environment.
Sabuhi
Mail-Checker is a python script that lets you see your mails directly from the terminal without having to login each time.

Mail-Checker ##Mail-Checker is a python script that lets you see your mails directly from the terminal without having to login each time. ##Before you

Siddharth Pradeep 1 Jan 12, 2022
A SMTP server for use as a pytest fixture that implements encryption and authentication.

SMTPDFix: Test email, locally A simple SMTP server based on aiosmtpd for use as a fixture with pytest that supports encryption and authentication. All

James Warne 11 Sep 03, 2022
This library is helpful when creating accounts, it has everything you need for this

AccountGeneratorHelper Library to facilitate accounts generation. Unofficial API for temp email services. Receive SMS from free services. Parsing and

Denis 52 Jan 07, 2023
Read/sync your IMAP mailboxes (python2)

Upstream status (master branch): Upstream status (next branch): Financial contributors: Links: Official github code repository: offlineimap Website: w

OfflineIMAP 1.7k Dec 29, 2022
A light-weight, modular, message representation and mail delivery framework for Python.

Marrow Mailer A highly efficient and modular mail delivery framework for Python 2.6+ and 3.2+, formerly called TurboMail. © 2006-2019, Alice Bevan-McG

Marrow Open Source Collective 255 Dec 28, 2022
ok-mail-helper是一个基于imap/smtp协议邮件客户端,使用python3.x开发

ok-mail-helper ok-mail-helper是一个基于imap/smtp协议邮件客户端,使用python3.x开发,支持邮件接收并解析、邮件发送,用户可在自己的项目中直接引入、开箱即用,或者结合flask等web框架轻松做成http接口供前端调用、把邮箱管理集成到自己的系统中,亦可通过

xlvchao 1 Feb 08, 2022
Email pass separator

email-pass-separator hii check out our new tool in kali linux use 'filename ' Dont forget to put inverted comma email:password separator Image Command

Hackers Tech 2 Sep 22, 2021
Search email inbox with python and filter with search criteria via IMAP4 and fastapi or console

Search email inbox with python and filter with search criteria via IMAP4 and fastapi or console

Karma Computing 0 Sep 07, 2021
SMTP In some vulnerable configurations, email servers can also be aggregated Use information that gives us information about the host or network Give

SMTP In some vulnerable configurations, email servers can also be aggregated Use information that gives us information about the host or network Give. The SMTP protocol supports some basic commands s

m3hr44n 1 Jan 16, 2022
Convert emails without attachments to pdf and send as email

Email to PDF to email This script will check an imap folder for unread emails. Any unread email that does not have an attachment will be converted to

Robert Luke 21 Nov 22, 2022
A functional demo of the O365 Module to send an email on an authenticated, tokenized account.

O365_email A functional demo of the O365 Module to send an email on an authenticated, tokenized account. Prep Create an app in Azure Developer's porta

2 Oct 14, 2022
This is a bot that interacts with you over voice and sends mail.Uses speech_recognition,pyttsx3 and smtplib

AutoMail This is a bot that interacts with you over voice and sends mail Before you run the bot , go to mail.py and put your respective email address

Aditya Subrahmanya Bhat 2 Nov 04, 2022
Django SMTP Protocol with Gmail

Django SMTP Protocol with Gmail This is the free service from gmail to send and receive emails. What we need for this things done, Python/pip install

Mehedi Hasan 3 Dec 13, 2022
An API to send emails through python3's smtplib module.

An API to send emails through python3's smtplib module. Just configure your SMTP server credentials and you are ready to send a lot of emails through API, designed to be used as a newsletter service.

Adnan Ahmad 15 Nov 24, 2022
Collection of emails sent from the Hungarian gov and Viktor Orbán to the citizens of Hungary

Public list of Hungary and Viktor Orbán's emails since March 2021 Collection of emails sent from the Hungarian government and Viktor Orbán to the citi

Miguel Sozinho Ramalho 1 Mar 28, 2022
This simple python script uses cv2 to create and mail certificates to participants of workshops.

This simple python script uses cv2 to create and mail certificates to participants of workshops. Just collect the names and email ids of participants in a csv file (i used google docs), and place it

Sounder Rajendran 0 Dec 19, 2022
利用阿里的云函数发送电子邮件

alifc_email 主要特性 利用阿里的云函数发送电子邮件 使用场景 hw中的钓鱼邮件发送,一些邮服会解析出邮件的来源ip(此来源ip并不是邮服的ip,而是从客户端发送邮件时,邮服自动带上的客户端ip),对于这些来源ip可能会做一些风控。 本项目利用云函数出口ip较多来绕过这些风控 使用方法 首

19 Dec 01, 2022
This is the mail server that handles responses from the Contact Form

mailserver About This is the mail server that handles responses from the Contact Form Contributors ✨ Thanks goes to these wonderful people (emoji key)

IoLang 3 Jan 03, 2022
EmailAll - a powerful Email Collect tool

EmailAll A powerful Email Collect tool 0x1 介绍 😲 EmailAll is a powerful Email Co

473 Dec 22, 2022
This Python program generates a random email address and password from a 2 big lists and checks the generated email.

This Python program generates a random email address and password from a 2 big lists and checks the generated email.

Killin 13 Dec 04, 2022