Repository: PrefectHQ/prefect

Issue:
Add proxies to slack_notifier
## Current behavior
`prefect.utilities.notifications.slack_notifier` sends requests to the Slack webhook using `requests.post` without allowing  `proxies={"http": "0.123.456.789"}` to be passed, which is problematic when Internet access must be done through a proxy.

 It is possible to go around this by setting HTTP_PROXY / HTTPS_PROXY environment variables, but this is not ideal / possible when running on private infrastructure which by default does not access the Internet and should not have these variables set.



## Proposed behavior
Add an optional `proxies` argument to `prefect.utilities.notifications.slack_notifier` which gets passed to `requests.post`.



## Example
To use Slack notifications from Prefect running on private infrastructure.

Comments:

Patch:
diff --git a/changes/pr5237.yaml b/changes/pr5237.yaml
new file mode 100644
index 0000000000..aab6b48e00
--- /dev/null
+++ b/changes/pr5237.yaml
@@ -0,0 +1,5 @@
+enhancement:
+  - "Allow passing of proxies argument to slack_notifier - [#5237](https://github.com/PrefectHQ/prefect/pull/5237)"
+
+contributor:
+  - "[Vincent Chéry](https://github.com/VincentAntoine)"
diff --git a/docs/orchestration/flow-runs/inspection.md b/docs/orchestration/flow-runs/inspection.md
index 8d410cf50b..d42d3b2f8a 100644
--- a/docs/orchestration/flow-runs/inspection.md
+++ b/docs/orchestration/flow-runs/inspection.md
@@ -66,14 +66,28 @@ flow_run.state.message
 
 ### Getting flow run logs
 
-<!-- TODO after CLI merged -->
+Get a List of `FlowRunLog` from the flow run using `.get_logs()`:
+
+```python
+flow_run.get_logs()
+# [
+#   FlowRunLog(timestamp=DateTime(1978, 03, 08, 22, 30, 00, 000000, tzinfo=Timezone('+00:00')), level=20, message='Submitted for execution: Task XXXXXXX'),
+#   FlowRunLog(timestamp=DateTime(1978, 03, 08, 22, 30, 01, 123456, tzinfo=Timezone('+00:00')), level=20, message="Beginning Flow run for 'radio_show'"),
+#   FlowRunLog(timestamp=DateTime(1978, 03, 08, 22, 30, 02, 234567, tzinfo=Timezone('+00:00')), level=20, message="Task 'series_one': Starting task run..."),
+#   FlowRunLog(timestamp=DateTime(1978, 03, 08, 22, 42, 42, 424242, tzinfo=Timezone('+00:00')), level=20, message='It feels like I just had my brains smashed out by a slice of lemon wrapped round a large gold brick.'),
+#   FlowRunLog(timestamp=DateTime(1978, 04, 12, 22, 59, 59, 987654, tzinfo=Timezone('+00:00')), level=20, message="Task 'series_one': Finished task run for task with final state: 'Success'"),
+#   FlowRunLog(timestamp=DateTime(1978, 04, 12, 23, 00, 00, 000000, tzinfo=Timezone('+00:00')), level=20, message='Flow run SUCCESS: all reference tasks succeeded')
+# ]
+```
+
+Each `FlowRunLog` in the list contains a log message, along with the log level and timestamp.
 
 ### Getting flow metadata
 
 Metadata about the flow that the flow run was created for is accessible using `.get_flow_metadata()`
 
 ```python
-flow_run.get_flow_metdata()
+flow_run.get_flow_metadata()
 # FlowView(
 #   flow_id='8bdcf5b5-7598-49d1-a885-61612ca550de', 
 #   name='hello-world', 
diff --git a/src/prefect/utilities/notifications/notifications.py b/src/prefect/utilities/notifications/notifications.py
index d9d39bfeb7..99be913853 100644
--- a/src/prefect/utilities/notifications/notifications.py
+++ b/src/prefect/utilities/notifications/notifications.py
@@ -252,6 +252,7 @@ def slack_notifier(
     only_states: list = None,
     webhook_secret: str = None,
     backend_info: bool = True,
+    proxies: dict = None,
 ) -> "prefect.engine.state.State":
     """
     Slack state change handler; requires having the Prefect slack app installed.  Works as a
@@ -274,6 +275,9 @@ def slack_notifier(
             webhook URL; defaults to `"SLACK_WEBHOOK_URL"`
         - backend_info (bool, optional): Whether to supply slack notification with urls
             pointing to backend pages; defaults to True
+        - proxies (dict), optional): `dict` with "http" and/or "https" keys, passed to
+         `requests.post` - for situations where a proxy is required to send requests to the
+          Slack webhook
 
     Returns:
         - State: the `new_state` object that was provided
@@ -310,7 +314,7 @@ def slack_notifier(
     import requests
 
     form_data = slack_message_formatter(tracked_obj, new_state, backend_info)
-    r = requests.post(webhook_url, json=form_data)
+    r = requests.post(webhook_url, json=form_data, proxies=proxies)
     if not r.ok:
         raise ValueError("Slack notification for {} failed".format(tracked_obj))
     return new_state


Test patch:
diff --git a/tests/utilities/notifications/test_notifications.py b/tests/utilities/notifications/test_notifications.py
index a2611f6e7b..83e65bff53 100644
--- a/tests/utilities/notifications/test_notifications.py
+++ b/tests/utilities/notifications/test_notifications.py
@@ -260,6 +260,16 @@ def test_slack_notifier_is_curried_and_uses_only_states(monkeypatch, state):
     assert ok.called is isinstance(state, TriggerFailed)
 
 
+def test_slack_notifier_uses_proxies(monkeypatch):
+    post = MagicMock(ok=True)
+    monkeypatch.setattr(requests, "post", post)
+    state = Failed(message="1", result=0)
+    with set_temporary_config({"cloud.use_local_secrets": True}):
+        with prefect.context(secrets=dict(SLACK_WEBHOOK_URL="")):
+            slack_notifier(Task(), "", state, proxies={"http": "some.proxy.I.P"})
+    assert post.call_args[1]["proxies"] == {"http": "some.proxy.I.P"}
+
+
 def test_gmail_notifier_sends_simple_email(monkeypatch):
     smtp = MagicMock()
     sendmail = MagicMock()