Commit 9a91e868 authored by Mikhail Ivanov's avatar Mikhail Ivanov Committed by Tamika Tannis

Amundsen Notifications functionality improvements (#363)

* Amundsen Notifications functionality improvements:
 - "Request Description" link visibility fix
 - MailClient implementation example
 - API incompatibilities fixes

* Amundsen Notifications functionality improvements:
 - "Request Description" link visibility fix
 - MailClient implementation example
 - API incompatibilities fixes
parent e5044816
......@@ -24,7 +24,6 @@ def feedback() -> Response:
try:
mail_client = get_mail_client()
data = request.form.to_dict()
text_content = '\r\n'.join('{}:\r\n{}\r\n'.format(k, v) for k, v in data.items())
html_content = ''.join('<div><strong>{}:</strong><br/>{}</div><br/>'.format(k, v) for k, v in data.items())
# action logging
......@@ -51,7 +50,7 @@ def feedback() -> Response:
'form_data': data
}
response = mail_client.send_email(subject=subject, text=text_content, html=html_content, optional_data=options)
response = mail_client.send_email(html=html_content, subject=subject, optional_data=options)
status_code = response.status_code
if status_code == HTTPStatus.OK:
......
......@@ -192,13 +192,13 @@ def send_notification(*, notification_type: str, options: Dict, recipients: List
)
response = mail_client.send_email(
recipients=recipients,
sender=sender,
subject=subject,
html=html,
subject=subject,
optional_data={
'email_type': notification_type,
},
recipients=recipients,
sender=sender,
)
status_code = response.status_code
......
......@@ -11,20 +11,18 @@ class BaseMailClient(abc.ABC):
@abc.abstractmethod
def send_email(self,
sender: str,
recipients: List[str],
subject: str,
text: str,
html: str,
optional_data: Dict) -> Response:
subject: str,
optional_data: Dict,
recipients: List[str],
sender: str) -> Response:
"""
Sends an email using the following parameters
:param sender: The sending address associated with the email
:param recipients: A list of receipients for the email
:param subject: The subject of the email
:param text: Plain text email content
:param html: HTML email content
:param subject: The subject of the email
:param optional_data: A dictionary of any values needed for custom implementations
:param recipients: A list of recipients for the email
:param sender: The sending address associated with the email
:return:
"""
raise NotImplementedError # pragma: no cover
import logging
import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from http import HTTPStatus
from typing import Dict, List
from flask import Response, jsonify, make_response
from amundsen_application.base.base_mail_client import BaseMailClient
# based on https://stackoverflow.com/a/6270987
class MailClient(BaseMailClient):
def __init__(self, recipients: List[str]) -> None:
self.recipients = recipients
def send_email(self,
html: str,
subject: str,
optional_data: Dict = None,
recipients: List[str] = None,
sender: str = None) -> Response:
if not sender:
sender = os.environ.get('AMUNDSEN_EMAIL') or '' # set me
if not recipients:
recipients = self.recipients
sender_pass = os.environ.get('AMUNDSEN_EMAIL_PASSWORD') or '' # set me
# Create message container - the correct MIME type
# to combine text and html is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = ', '.join(recipients)
# Record the MIME type of text/html
# and attach parts to message container.
msg.attach(MIMEText(html, 'html'))
s = smtplib.SMTP('smtp.gmail.com')
try:
s.connect('smtp.gmail.com', 587)
s.ehlo()
s.starttls()
s.ehlo()
s.login(sender, sender_pass)
message = s.send_message(msg)
payload = jsonify({'msg': message})
s.quit()
return make_response(payload, HTTPStatus.OK)
except Exception as e:
err_message = 'Encountered exception: ' + str(e)
logging.exception(err_message)
payload = jsonify({'msg': err_message})
s.quit()
return make_response(payload, HTTPStatus.INTERNAL_SERVER_ERROR)
......@@ -158,7 +158,7 @@ class TableDetail extends React.Component<TableDetailProps & RouteComponentProps
editable={ data.is_editable }
/>
</EditableSection>
{ !data.table_description && notificationsEnabled() && <RequestDescriptionText/> }
{ notificationsEnabled() && <RequestDescriptionText/> }
<section className="column-layout-2">
<section className="left-panel">
{
......
......@@ -109,31 +109,6 @@ interface MailClientFeaturesConfig {
feedbackEnabled: boolean;
notificationsEnabled: boolean;
}
/**
* MailClientFeaturesConfig - Enable/disable UI features with a dependency on
* configuring a custom mail client.
*
* feedbackEnabled - Enables the feedback feature UI
* notificationsEnabled - Enables any UI related to sending notifications to users
*/
interface MailClientFeaturesConfig {
feedbackEnabled: boolean;
notificationsEnabled: boolean;
}
/**
* MailClientFeaturesConfig - Enable/disable UI features with a dependency on
* configuring a custom mail client.
*
* feedbackEnabled - Enables the feedback feature UI
* notificationsEnabled - Enables any UI related to sending notifications to users
*/
interface MailClientFeaturesConfig {
feedbackEnabled: boolean;
notificationsEnabled: boolean;
}
/**
* TableProfileConfig - Customize the "Table Profile" section of the "Table Details" page.
*
......
......@@ -372,11 +372,11 @@ class NotificationUtilsTest(unittest.TestCase):
sender=test_sender
)
mock_client.send_email.assert_called_with(
recipients=expected_recipients,
sender=test_sender,
subject=mock_subject,
html=mock_html,
subject=mock_subject,
optional_data={'email_type': test_notification_type},
recipients=expected_recipients,
sender=test_sender
)
def test_no_recipients_for_notification(self) -> None:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment