Coverage for /home/ubuntu/Documents/Research/mut_p6/sacred/sacred/observers/slack.py: 27%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/env python
2# coding=utf-8
4from sacred.observers.base import RunObserver, td_format
5from sacred.config.config_files import load_config_file
6import json
9DEFAULT_SLACK_PRIORITY = 10
12class SlackObserver(RunObserver):
13 """Sends a message to Slack upon completion/failing of an experiment."""
15 @classmethod
16 def from_config(cls, filename):
17 """
18 Create a SlackObserver from a given configuration file.
20 The file can be in any format supported by Sacred
21 (.json, .pickle, [.yaml]).
22 It has to specify a ``webhook_url`` and can optionally set
23 ``bot_name``, ``icon``, ``completed_text``, ``interrupted_text``, and
24 ``failed_text``.
25 """
26 return cls(**load_config_file(filename))
28 def __init__(
29 self,
30 webhook_url,
31 bot_name="sacred-bot",
32 icon=":angel:",
33 priority=DEFAULT_SLACK_PRIORITY,
34 completed_text=None,
35 interrupted_text=None,
36 failed_text=None,
37 ):
38 self.webhook_url = webhook_url
39 self.bot_name = bot_name
40 self.icon = icon
41 self.completed_text = completed_text or (
42 ":white_check_mark: *{experiment[name]}* "
43 "completed after _{elapsed_time}_ with result=`{result}`"
44 )
45 self.interrupted_text = interrupted_text or (
46 ":warning: *{experiment[name]}* " "interrupted after _{elapsed_time}_"
47 )
48 self.failed_text = failed_text or (
49 ":x: *{experiment[name]}* failed after " "_{elapsed_time}_ with `{error}`"
50 )
51 self.run = None
52 self.priority = priority
54 def started_event(
55 self, ex_info, command, host_info, start_time, config, meta_info, _id
56 ):
57 self.run = {
58 "_id": _id,
59 "config": config,
60 "start_time": start_time,
61 "experiment": ex_info,
62 "command": command,
63 "host_info": host_info,
64 }
66 def get_completed_text(self):
67 return self.completed_text.format(**self.run)
69 def get_interrupted_text(self):
70 return self.interrupted_text.format(**self.run)
72 def get_failed_text(self):
73 return self.failed_text.format(**self.run)
75 def completed_event(self, stop_time, result):
76 import requests
78 if self.completed_text is None:
79 return
81 self.run["result"] = result
82 self.run["stop_time"] = stop_time
83 self.run["elapsed_time"] = td_format(stop_time - self.run["start_time"])
85 data = {
86 "username": self.bot_name,
87 "icon_emoji": self.icon,
88 "text": self.get_completed_text(),
89 }
90 headers = {"Content-type": "application/json", "Accept": "text/plain"}
91 requests.post(self.webhook_url, data=json.dumps(data), headers=headers)
93 def interrupted_event(self, interrupt_time, status):
94 import requests
96 if self.interrupted_text is None:
97 return
99 self.run["status"] = status
100 self.run["interrupt_time"] = interrupt_time
101 self.run["elapsed_time"] = td_format(interrupt_time - self.run["start_time"])
103 data = {
104 "username": self.bot_name,
105 "icon_emoji": self.icon,
106 "text": self.get_interrupted_text(),
107 }
108 headers = {"Content-type": "application/json", "Accept": "text/plain"}
109 requests.post(self.webhook_url, data=json.dumps(data), headers=headers)
111 def failed_event(self, fail_time, fail_trace):
112 import requests
114 if self.failed_text is None:
115 return
117 self.run["fail_trace"] = fail_trace
118 self.run["error"] = fail_trace[-1].strip()
119 self.run["fail_time"] = fail_time
120 self.run["elapsed_time"] = td_format(fail_time - self.run["start_time"])
122 data = {
123 "username": self.bot_name,
124 "icon_emoji": self.icon,
125 "text": self.get_failed_text(),
126 }
127 headers = {"Content-type": "application/json", "Accept": "text/plain"}
128 requests.post(self.webhook_url, data=json.dumps(data), headers=headers)