API - add typing
This commit is contained in:
		@@ -3,7 +3,9 @@ import smtplib
 | 
			
		||||
import ssl
 | 
			
		||||
from email.mime.multipart import MIMEMultipart
 | 
			
		||||
from email.mime.text import MIMEText
 | 
			
		||||
from typing import Dict, Optional, Type, Union
 | 
			
		||||
 | 
			
		||||
from flask import Flask
 | 
			
		||||
from jinja2 import Environment, FileSystemLoader
 | 
			
		||||
 | 
			
		||||
from .utils_email import parse_email_url
 | 
			
		||||
@@ -13,14 +15,16 @@ email_log.setLevel(logging.DEBUG)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class EmailMessage:
 | 
			
		||||
    def __init__(self, sender, recipient, subject, html, text):
 | 
			
		||||
    def __init__(
 | 
			
		||||
        self, sender: str, recipient: str, subject: str, html: str, text: str
 | 
			
		||||
    ) -> None:
 | 
			
		||||
        self.sender = sender
 | 
			
		||||
        self.recipient = recipient
 | 
			
		||||
        self.subject = subject
 | 
			
		||||
        self.html = html
 | 
			
		||||
        self.text = text
 | 
			
		||||
 | 
			
		||||
    def generate_message(self):
 | 
			
		||||
    def generate_message(self) -> MIMEMultipart:
 | 
			
		||||
        message = MIMEMultipart('alternative')
 | 
			
		||||
        message['Subject'] = self.subject
 | 
			
		||||
        message['From'] = self.sender
 | 
			
		||||
@@ -33,20 +37,24 @@ class EmailMessage:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class EmailTemplate:
 | 
			
		||||
    def __init__(self, template_directory):
 | 
			
		||||
    def __init__(self, template_directory: str) -> None:
 | 
			
		||||
        self._env = Environment(loader=FileSystemLoader(template_directory))
 | 
			
		||||
 | 
			
		||||
    def get_content(self, template, lang, part, data):
 | 
			
		||||
        template = self._env.get_template(f'{template}/{lang}/{part}')
 | 
			
		||||
    def get_content(
 | 
			
		||||
        self, template_name: str, lang: str, part: str, data: Dict
 | 
			
		||||
    ) -> str:
 | 
			
		||||
        template = self._env.get_template(f'{template_name}/{lang}/{part}')
 | 
			
		||||
        return template.render(data)
 | 
			
		||||
 | 
			
		||||
    def get_all_contents(self, template, lang, data):
 | 
			
		||||
    def get_all_contents(self, template: str, lang: str, data: Dict) -> Dict:
 | 
			
		||||
        output = {}
 | 
			
		||||
        for part in ['subject.txt', 'body.txt', 'body.html']:
 | 
			
		||||
            output[part] = self.get_content(template, lang, part, data)
 | 
			
		||||
        return output
 | 
			
		||||
 | 
			
		||||
    def get_message(self, template, lang, sender, recipient, data):
 | 
			
		||||
    def get_message(
 | 
			
		||||
        self, template: str, lang: str, sender: str, recipient: str, data: Dict
 | 
			
		||||
    ) -> MIMEMultipart:
 | 
			
		||||
        output = self.get_all_contents(template, lang, data)
 | 
			
		||||
        message = EmailMessage(
 | 
			
		||||
            sender,
 | 
			
		||||
@@ -59,7 +67,7 @@ class EmailTemplate:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Email:
 | 
			
		||||
    def __init__(self, app=None):
 | 
			
		||||
    def __init__(self, app: Optional[Flask] = None) -> None:
 | 
			
		||||
        self.host = 'localhost'
 | 
			
		||||
        self.port = 1025
 | 
			
		||||
        self.use_tls = False
 | 
			
		||||
@@ -67,26 +75,30 @@ class Email:
 | 
			
		||||
        self.username = None
 | 
			
		||||
        self.password = None
 | 
			
		||||
        self.sender_email = 'no-reply@example.com'
 | 
			
		||||
        self.email_template = None
 | 
			
		||||
        self.email_template: Optional[EmailTemplate] = None
 | 
			
		||||
        if app is not None:
 | 
			
		||||
            self.init_email(app)
 | 
			
		||||
 | 
			
		||||
    def init_email(self, app):
 | 
			
		||||
        parsed_url = parse_email_url(app.config.get('EMAIL_URL'))
 | 
			
		||||
    def init_email(self, app: Flask) -> None:
 | 
			
		||||
        parsed_url = parse_email_url(app.config['EMAIL_URL'])
 | 
			
		||||
        self.host = parsed_url['host']
 | 
			
		||||
        self.port = parsed_url['port']
 | 
			
		||||
        self.use_tls = parsed_url['use_tls']
 | 
			
		||||
        self.use_ssl = parsed_url['use_ssl']
 | 
			
		||||
        self.username = parsed_url['username']
 | 
			
		||||
        self.password = parsed_url['password']
 | 
			
		||||
        self.sender_email = app.config.get('SENDER_EMAIL')
 | 
			
		||||
        self.email_template = EmailTemplate(app.config.get('TEMPLATES_FOLDER'))
 | 
			
		||||
        self.sender_email = app.config['SENDER_EMAIL']
 | 
			
		||||
        self.email_template = EmailTemplate(app.config['TEMPLATES_FOLDER'])
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def smtp(self):
 | 
			
		||||
    def smtp(self) -> Type[Union[smtplib.SMTP_SSL, smtplib.SMTP]]:
 | 
			
		||||
        return smtplib.SMTP_SSL if self.use_ssl else smtplib.SMTP
 | 
			
		||||
 | 
			
		||||
    def send(self, template, lang, recipient, data):
 | 
			
		||||
    def send(
 | 
			
		||||
        self, template: str, lang: str, recipient: str, data: Dict
 | 
			
		||||
    ) -> None:
 | 
			
		||||
        if not self.email_template:
 | 
			
		||||
            raise Exception('No email template defined.')
 | 
			
		||||
        message = self.email_template.get_message(
 | 
			
		||||
            template, lang, self.sender_email, recipient, data
 | 
			
		||||
        )
 | 
			
		||||
@@ -95,8 +107,10 @@ class Email:
 | 
			
		||||
            context = ssl.create_default_context()
 | 
			
		||||
        if self.use_ssl:
 | 
			
		||||
            connection_params.update({'context': context})
 | 
			
		||||
        with self.smtp(self.host, self.port, **connection_params) as smtp:
 | 
			
		||||
            smtp.login(self.username, self.password)
 | 
			
		||||
        with self.smtp(
 | 
			
		||||
            self.host, self.port, **connection_params  # type: ignore
 | 
			
		||||
        ) as smtp:
 | 
			
		||||
            smtp.login(self.username, self.password)  # type: ignore
 | 
			
		||||
            if self.use_tls:
 | 
			
		||||
                smtp.starttls(context=context)
 | 
			
		||||
            smtp.sendmail(self.sender_email, recipient, message.as_string())
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
from typing import Dict
 | 
			
		||||
 | 
			
		||||
from urllib3.util import parse_url
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -5,7 +7,7 @@ class InvalidEmailUrlScheme(Exception):
 | 
			
		||||
    ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def parse_email_url(email_url):
 | 
			
		||||
def parse_email_url(email_url: str) -> Dict:
 | 
			
		||||
    parsed_url = parse_url(email_url)
 | 
			
		||||
    if parsed_url.scheme != 'smtp':
 | 
			
		||||
        raise InvalidEmailUrlScheme()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user