Repository: great-expectations/great_expectations

Issue:
Use cleaner solution for non-truncating division in python 2
Prefer `from __future__ import division` to `1.*x/y`
Slack Webhook Exposed in Log
It seems that the slack webhook url is exposed when there's any error. Relevant code seems to be [here](https://github.com/great-expectations/great_expectations/blob/ee792823df549f58cc86c649a4c66bcc30817790/great_expectations/checkpoint/util.py#L47). 

Is this intended? Even though a webhook would only be exposed when problems are encountered, it still feel very insecure... Would it be better to set the log level as DEBUG? Am I missing anything here? 


Discussion:
Done inline during improve_partitions push.
Hey @sherrywang31 ! Thank you for raising this; we'll review internally and be in touch.


Resolving patch:
diff --git a/great_expectations/checkpoint/util.py b/great_expectations/checkpoint/util.py
--- a/great_expectations/checkpoint/util.py
+++ b/great_expectations/checkpoint/util.py
@@ -36,20 +36,14 @@ def send_slack_notification(
     try:
         response = session.post(url=url, headers=headers, json=query)
     except requests.ConnectionError:
-        logger.warning(
-            f"Failed to connect to Slack webhook at {slack_webhook} after {10} retries."
-        )
+        logger.warning(f"Failed to connect to Slack webhook after {10} retries.")
     except Exception as e:
         logger.error(str(e))
     else:
         if response.status_code != 200:
             logger.warning(
-                "Request to Slack webhook at {url} "
-                "returned error {status_code}: {text}".format(
-                    url=slack_webhook,
-                    status_code=response.status_code,
-                    text=response.text,
-                )
+                "Request to Slack webhook "
+                f"returned error {response.status_code}: {response.text}"
             )
 
         else:
@@ -60,9 +54,7 @@ def send_slack_notification(
 def send_opsgenie_alert(query, suite_name, settings):
     """Creates an alert in Opsgenie."""
     if settings["region"] is not None:
-        url = "https://api.{region}.opsgenie.com/v2/alerts".format(
-            region=settings["region"]
-        )  # accommodate for Europeans
+        url = f"https://api.{settings['region']}.opsgenie.com/v2/alerts"  # accommodate for Europeans
     else:
         url = "https://api.opsgenie.com/v2/alerts"
 
@@ -84,12 +76,8 @@ def send_opsgenie_alert(query, suite_name, settings):
     else:
         if response.status_code != 202:
             logger.warning(
-                "Request to Opsgenie API at {url} "
-                "returned error {status_code}: {text}".format(
-                    url=url,
-                    status_code=response.status_code,
-                    text=response.text,
-                )
+                "Request to Opsgenie API "
+                f"returned error {response.status_code}: {response.text}"
             )
         else:
             return "success"
@@ -101,23 +89,15 @@ def send_microsoft_teams_notifications(query, microsoft_teams_webhook):
     try:
         response = session.post(url=microsoft_teams_webhook, json=query)
     except requests.ConnectionError:
-        logger.warning(
-            "Failed to connect to Microsoft Teams webhook at {url} "
-            "after {max_retries} retries.".format(
-                url=microsoft_teams_webhook, max_retries=10
-            )
-        )
+        logger.warning("Failed to connect to Microsoft Teams webhook after 10 retries.")
+
     except Exception as e:
         logger.error(str(e))
     else:
         if response.status_code != 200:
             logger.warning(
-                "Request to Microsoft Teams webhook at {url} "
-                "returned error {status_code}: {text}".format(
-                    url=microsoft_teams_webhook,
-                    status_code=response.status_code,
-                    text=response.text,
-                )
+                "Request to Microsoft Teams webhook "
+                f"returned error {response.status_code}: {response.text}"
             )
             return
         else:
@@ -130,25 +110,15 @@ def send_webhook_notifications(query, webhook, target_platform):
         response = session.post(url=webhook, json=query)
     except requests.ConnectionError:
         logger.warning(
-            "Failed to connect to {target_platform} webhook at {url} "
-            "after {max_retries} retries.".format(
-                url=webhook,
-                max_retries=10,
-                target_platform=target_platform,
-            )
+            f"Failed to connect to {target_platform} webhook after 10 retries."
         )
     except Exception as e:
         logger.error(str(e))
     else:
         if response.status_code != 200:
             logger.warning(
-                "Request to {target_platform} webhook at {url} "
-                "returned error {status_code}: {text}".format(
-                    url=webhook,
-                    status_code=response.status_code,
-                    target_platform=target_platform,
-                    text=response.text,
-                )
+                f"Request to {target_platform} webhook "
+                f"returned error {response.status_code}: {response.text}"
             )
         else:
             return f"{target_platform} notification succeeded."
@@ -500,14 +470,12 @@ def send_cloud_notification(url: str, headers: dict):
     try:
         response = session.post(url=url, headers=headers)
     except requests.ConnectionError:
-        logger.error(
-            f"Failed to connect to Cloud backend at {url} " f"after {10} retries."
-        )
+        logger.error(f"Failed to connect to Cloud backend after {10} retries.")
     except Exception as e:
         logger.error(str(e))
     else:
         if response.status_code != 200:
-            message = f"Cloud Notification request at {url} returned error {response.status_code}: {response.text}"
+            message = f"Cloud Notification request returned error {response.status_code}: {response.text}"
             logger.error(message)
             return {"cloud_notification_result": message}
         else:


Test patch:
diff --git a/tests/actions/test_core_actions.py b/tests/actions/test_core_actions.py
--- a/tests/actions/test_core_actions.py
+++ b/tests/actions/test_core_actions.py
@@ -443,10 +443,7 @@ def test_MicrosoftTeamsNotificationAction_bad_request(
         data_asset=None,
     ) == {"microsoft_teams_notification_result": None}
 
-    assert (
-        "Request to Microsoft Teams webhook at http://testing returned error 400"
-        in caplog.text
-    )
+    assert "Request to Microsoft Teams webhook returned error 400" in caplog.text
 
 
 class MockSMTPServer:
@@ -675,9 +672,7 @@ def test_cloud_notification_action_bad_response(
         "Authorization": f"Bearer {ge_cloud_access_token}",
     }
     expected_result = {
-        "cloud_notification_result": "Cloud Notification request at "
-        "https://app.test.greatexpectations.io/organizations/bd20fead-2c31-4392-bcd1-f1e87ad5a79c/contracts/bfe7dc64-5320-49b0-91c1-2e8029e06c4d/suite-validation-results/bfe7dc64-5320-49b0-91c1-2e8029e06c4d/notification-actions "
-        "returned error 418: test_text"
+        "cloud_notification_result": "Cloud Notification request returned error 418: test_text"
     }
 
     assert (