Coverage for testrail_api_reporter/publishers/slack_sender.py: 35%
40 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-29 15:21 +0200
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-29 15:21 +0200
1# -*- coding: utf-8 -*-
2""" Slack sender module """
4import json
6import requests
8from ..utils.logger_config import setup_logger, DEFAULT_LOGGING_LEVEL
9from ..utils.reporter_utils import format_error, check_captions_and_files
12class SlackSender:
13 """Slack sender class, see for details https://api.slack.com/messaging/webhooks"""
15 def __init__(self, hook_url=None, timeout=5, verify=True, logger=None, log_level=DEFAULT_LOGGING_LEVEL):
16 """
17 General init
19 :param hook_url: url for Slack API hook, string, required
20 :param timeout: timeout for message send, integer, optional
21 :param verify: verification required, bool, optional
22 :param logger: logger object, optional
23 :param log_level: logging level, optional, by default, is 'logging.DEBUG'
24 """
25 if not logger:
26 self.___logger = setup_logger(name="SlackSender", log_file="SlackSender.log", level=log_level)
27 else:
28 self.___logger = logger
29 self.___logger.debug("Initializing Slack Sender")
30 if not hook_url:
31 raise ValueError("No Slack hook url provided, aborted!")
32 self.__hook_url = hook_url
33 self.__timeout = timeout
34 self.__verify = verify
36 @staticmethod
37 def __prepare_attachments(files, captions):
38 """
39 Prepares attachments
41 :param files: list of files (images)
42 :param captions: list of captions for files, list of strings, if not provided, no captions will be added
43 :return: list of dict with attachment info
44 """
45 legacy_attachments = []
46 for j, file in enumerate(files):
47 legacy_attachments.append(
48 {
49 "pretext": "----",
50 "text": captions[j] if captions else "",
51 "mrkdwn_in": ["text", "pretext"],
52 "image_url": file,
53 }
54 )
55 return legacy_attachments
57 @staticmethod
58 def __prepare_blocks(title):
59 """
60 Prepares blocks
62 :param title: header message title
63 :return: list of dict with blocks info
64 """
65 return [{"type": "header", "text": {"type": "plain_text", "text": title, "emoji": True}}]
67 def __prepare_payload(self, title, files, captions):
68 """
69 Prepares whole payload
71 :param title: header message title
72 :param files: list of files (images)
73 :param captions: list of captions for files, list of strings, if not provided, no captions will be added to
74 :return: json with payload
75 """
76 return json.dumps(
77 {
78 "attachments": self.__prepare_attachments(files=files, captions=captions),
79 "blocks": self.__prepare_blocks(title=title),
80 }
81 )
83 @staticmethod
84 def __prepare_headers():
85 """
86 Prepares headers for request itself
88 :return: json with headers
89 """
90 return {"Content-type": "application/json", "Accept": "text/plain"}
92 def send_message(self, files=None, captions=None, title="Test development & automation coverage report"):
93 """
94 Send a message to Slack
96 :param files: list of urls of images
97 :param captions: list of captions for files, list of strings, if not provided, no captions will be added
98 :param title: header title of message
99 :return: none
100 """
101 # check params
102 if not isinstance(files, list):
103 raise ValueError("No file list for report provided, aborted!")
104 captions = check_captions_and_files(
105 captions=captions,
106 files=files,
107 debug=self.___logger.level == DEFAULT_LOGGING_LEVEL,
108 logger=self.___logger,
109 )
110 # Send to slack
111 try:
112 response = requests.post(
113 url=self.__hook_url,
114 data=self.__prepare_payload(title=title, files=files, captions=captions),
115 timeout=self.__timeout,
116 verify=self.__verify,
117 headers=self.__prepare_headers(),
118 )
119 if response.status_code != 200:
120 raise ValueError(
121 f"Message can't be sent! Error {response.status_code}: {response.text}: "
122 f"{response.raise_for_status()}"
123 )
124 self.___logger.debug("Message sent!")
125 except Exception as error:
126 raise ValueError(f"Message can't be sent!\nError{format_error(error)}") from error