-
Notifications
You must be signed in to change notification settings - Fork 14.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add header_data into emails #20903
feat: add header_data into emails #20903
Conversation
Codecov Report
@@ Coverage Diff @@
## master #20903 +/- ##
===========================================
- Coverage 66.38% 54.85% -11.53%
===========================================
Files 1766 1772 +6
Lines 67225 67647 +422
Branches 7137 7204 +67
===========================================
- Hits 44625 37111 -7514
- Misses 20774 28694 +7920
- Partials 1826 1842 +16
Flags with carried forward coverage won't be shown. Click here to find out more.
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
9a8d670
to
2faa388
Compare
1130f1d
to
d2dce2b
Compare
superset/reports/commands/execute.py
Outdated
@@ -342,23 +343,34 @@ def _get_notification_content(self) -> NotificationContent: | |||
): | |||
embedded_data = self._get_embedded_data() | |||
|
|||
notification_source = None | |||
notification_source_id = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, but can you declare these two at the beginning of the method with the others? It read at first as if you were reassigning the values rather than declaring and I had to check the top of the method to be sure which one it was.
superset/utils/core.py
Outdated
@@ -917,6 +918,9 @@ def send_email_smtp( # pylint: disable=invalid-name,too-many-arguments,too-many | |||
msg["Subject"] = subject | |||
msg["From"] = smtp_mail_from | |||
msg["To"] = ", ".join(smtp_mail_to) | |||
|
|||
api_object = {"metadata": log_data} | |||
msg["X-MSYS-API"] = json.dumps(api_object) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are you moving these two lines and the _get_log_data
method to the config?
superset/reports/models.py
Outdated
@@ -82,6 +82,11 @@ class ReportCreationMethod(str, enum.Enum): | |||
ALERTS_REPORTS = "alerts_reports" | |||
|
|||
|
|||
class ReportSourceFormat(str, enum.Enum): | |||
CHART = "chart" | |||
DASHBOARDS = "dashboard" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, plural/singular consistency
superset/reports/commands/execute.py
Outdated
notification_type=self._report_schedule.type, | ||
notification_source=notification_source, | ||
notification_source_id=notification_source_id, | ||
notification_format=self._report_schedule.report_format, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest grouping all of this new content together into either log_data or header_data since it all serves the same function and doesn't need to be passed in separately. It also makes it clear with that naming what it's going to be used for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also we can be more flexible about the shape of the data that way, and if it changes, we don't have to update it in many places. The only thing that really relies on the shape is the config method which is optional.
c7b9572
to
2a1aed1
Compare
2a1aed1
to
048f72d
Compare
superset/config.py
Outdated
@@ -1066,6 +1066,12 @@ def SQL_QUERY_MUTATOR( # pylint: disable=invalid-name,unused-argument | |||
return sql | |||
|
|||
|
|||
def NOTIFICATION_EMAIL_HEADER_MUTATOR( # pylint: disable=invalid-name,unused-argument | |||
header: Dict[str, Any], **kwargs: Any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is message, right? Rather than header? And is there a class type for the message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, sorry. Will change but will wait for the rest of your review first
superset/reports/commands/execute.py
Outdated
def _get_log_data(self) -> Dict[str, Any]: | ||
chart_id = None | ||
dashboard_id = None | ||
owners = json.loads(self._report_schedule.owners) or None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will self._report_schedule.owners
be a string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should be an array
superset/reports/commands/execute.py
Outdated
report_source = ReportSourceFormat.DASHBOARD | ||
dashboard_id = self._report_schedule.dashboard_id | ||
log_data = { | ||
"notification_type": self._report_schedule.type or None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is a "notification" in this sense? I see that term used below, but I wonder if it has the same meaning outside of this context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
either an alert or a report.
048f72d
to
f5c9c09
Compare
@@ -66,3 +67,47 @@ def test_report_for_dashboard_with_tabs( | |||
assert digest == dashboard.digest | |||
assert send_email_smtp_mock.call_count == 1 | |||
assert len(send_email_smtp_mock.call_args.kwargs["images"]) == 1 | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider adding unit tests for send_email_smtp
with the actual use of NOTIFICATION_EMAIL_HEADER_MUTATOR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would that exist in this repo or in one with an actual NOTIFICATION_EMAIL_HEADER_MUTATOR
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can mock an example NOTIFICATION_EMAIL_HEADER_MUTATOR
and test it in this repo
68d9c72
to
c0e1e53
Compare
c0e1e53
to
141bd50
Compare
superset/reports/commands/execute.py
Outdated
@@ -73,6 +74,8 @@ | |||
from superset.utils.urls import get_url_path | |||
from superset.utils.webdriver import DashboardStandaloneMode | |||
|
|||
from ...utils.core import HeaderDataType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you make this import absolute instead of relative?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I keep on doing this and the black reformats it. So annoying.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 please fix this format
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah latest commit fixes it.
notification_type: str | ||
notification_source: Optional[str] | ||
chart_id: Optional[int] | ||
dashboard_id: Optional[int] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all of these are optional, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type and format shouldn't be since they are required in order to make a report. I can make all of them optional however.
|
||
|
||
@dataclass | ||
class NotificationContent: | ||
name: str | ||
header_data: Optional[ | ||
HeaderDataType | ||
] = None # this is optional to account for error states |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you explain why this is optional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we also create notification_content when there is an error, should we be pushing header data into those cases as well? I assumed we wouldn't be but happy to make it not optional, and create header data in those instances as well.
ac023c8
to
9a4d32e
Compare
9a4d32e
to
821e662
Compare
|
||
|
||
@dataclass | ||
class NotificationContent: | ||
name: str | ||
header_data: HeaderDataType # this is optional to account for error states |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AAfghahi your comment doesn't seem to reflect the actual type and default, i.e., header_data
is required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AAfghahi it looks like this value is always being passed into the class. Can we just remove the comment or is there some other intention here?
SUMMARY
This adds a new config mutator that adds logging data into a notification email should a user desire that.
The mutator works similarly to the SQL mutator that is already in position, accepting kwargs so that the logging data can be customized.
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
TESTING INSTRUCTIONS
ADDITIONAL INFORMATION