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

56 statements  

1#!/usr/bin/env python 

2# coding=utf-8 

3 

4from sacred.observers.base import RunObserver, td_format 

5from sacred.config.config_files import load_config_file 

6import json 

7 

8 

9DEFAULT_SLACK_PRIORITY = 10 

10 

11 

12class SlackObserver(RunObserver): 

13 """Sends a message to Slack upon completion/failing of an experiment.""" 

14 

15 @classmethod 

16 def from_config(cls, filename): 

17 """ 

18 Create a SlackObserver from a given configuration file. 

19 

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)) 

27 

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 

53 

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 } 

65 

66 def get_completed_text(self): 

67 return self.completed_text.format(**self.run) 

68 

69 def get_interrupted_text(self): 

70 return self.interrupted_text.format(**self.run) 

71 

72 def get_failed_text(self): 

73 return self.failed_text.format(**self.run) 

74 

75 def completed_event(self, stop_time, result): 

76 import requests 

77 

78 if self.completed_text is None: 

79 return 

80 

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"]) 

84 

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) 

92 

93 def interrupted_event(self, interrupt_time, status): 

94 import requests 

95 

96 if self.interrupted_text is None: 

97 return 

98 

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"]) 

102 

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) 

110 

111 def failed_event(self, fail_time, fail_trace): 

112 import requests 

113 

114 if self.failed_text is None: 

115 return 

116 

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"]) 

121 

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)