




import inspect
import unittest

from transformers import SegformerConfig, is_torch_available, is_vision_available
from transformers.models.auto import get_values
from transformers.testing_utils import require_torch, slow, torch_device

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
					import torch

					from transformers import (
					    MODEL_MAPPING,
					    SegformerForImageClassification,
					    SegformerForSemanticSegmentation,
					    SegformerModel,
					)
					from transformers.models.segformer.modeling_segformer import SEGFORMER_PRETRAINED_MODEL_ARCHIVE_LIST


if is_vision_available():
					from PIL import Image

					from transformers import SegformerImageProcessor


class    lowerCamelCase    (		__UpperCAmelCase						):






			'''simple docstring'''





			def 							UpperCAmelCase__       ( self			:   Any  )						->   Any:
								__magic_name__							:	Any    							=							self.config_class(**self.inputs_dict  )
								self.parent.assertTrue(hasattr(lowerCamelCase_       ,						'''hidden_sizes'''  )  )
								self.parent.assertTrue(hasattr(lowerCamelCase_       ,						'''num_attention_heads'''  )  )
								self.parent.assertTrue(hasattr(lowerCamelCase_       ,						'''num_encoder_blocks'''  )  )






class    lowerCamelCase    :






			'''simple docstring'''





			def __init__( self			:   int       ,						lowerCamelCase_			:   Dict       ,						lowerCamelCase_			:   Optional[Any]=13       ,						lowerCamelCase_			:   Optional[int]=64       ,						lowerCamelCase_			:   List[Any]=3       ,						lowerCamelCase_			:   str=4       ,						lowerCamelCase_			:   Optional[Any]=[2, 2, 2, 2]       ,						lowerCamelCase_			:   Dict=[8, 4, 2, 1]       ,						lowerCamelCase_			:   List[str]=[16, 32, 64, 128]       ,						lowerCamelCase_			:   Optional[int]=[1, 4, 8, 16]       ,						lowerCamelCase_			:   int=[1, 2, 4, 8]       ,						lowerCamelCase_			:   int=True       ,						lowerCamelCase_			:   int=True       ,						lowerCamelCase_			:   Optional[Any]="gelu"       ,						lowerCamelCase_			:   List[Any]=0.1       ,						lowerCamelCase_			:   Any=0.1       ,						lowerCamelCase_			:   Dict=0.0_2       ,						lowerCamelCase_			:   int=3       ,						lowerCamelCase_			:   int=None       ,						)						->   Any:
								__magic_name__							:	List[Any]    							=							parent
								__magic_name__							:	Optional[Any]    							=							batch_size
								__magic_name__							:	Union[str, Any]    							=							image_size
								__magic_name__							:	Dict    							=							num_channels
								__magic_name__							:	Union[str, Any]    							=							num_encoder_blocks
								__magic_name__							:	List[Any]    							=							sr_ratios
								__magic_name__							:	Tuple    							=							depths
								__magic_name__							:	Union[str, Any]    							=							hidden_sizes
								__magic_name__							:	Union[str, Any]    							=							downsampling_rates
								__magic_name__							:	Optional[Any]    							=							num_attention_heads
								__magic_name__							:	Union[str, Any]    							=							is_training
								__magic_name__							:	Union[str, Any]    							=							use_labels
								__magic_name__							:	Dict    							=							hidden_act
								__magic_name__							:	Dict    							=							hidden_dropout_prob
								__magic_name__							:	Union[str, Any]    							=							attention_probs_dropout_prob
								__magic_name__							:	Optional[Any]    							=							initializer_range
								__magic_name__							:	Tuple    							=							num_labels
								__magic_name__							:	List[str]    							=							scope

			def 							UpperCAmelCase__       ( self			:   Tuple  )						->   Any:
								__magic_name__							:	List[Any]    							=							floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]  )

								__magic_name__							:	Dict    							=							None
								if self.use_labels:
													__magic_name__							:	Optional[int]    							=							ids_tensor([self.batch_size, self.image_size, self.image_size]       ,						self.num_labels  )

								__magic_name__							:	Dict    							=							self.get_config()
								return config, pixel_values, labels

			def 							UpperCAmelCase__       ( self			:   List[Any]  )						->   int:
								return SegformerConfig(
								    image_size=self.image_size       ,						num_channels=self.num_channels       ,						num_encoder_blocks=self.num_encoder_blocks       ,						depths=self.depths       ,						hidden_sizes=self.hidden_sizes       ,						num_attention_heads=self.num_attention_heads       ,						hidden_act=self.hidden_act       ,						hidden_dropout_prob=self.hidden_dropout_prob       ,						attention_probs_dropout_prob=self.attention_probs_dropout_prob       ,						initializer_range=self.initializer_range       ,						)

			def 							UpperCAmelCase__       ( self			:   Optional[int]       ,						lowerCamelCase_			:   Dict       ,						lowerCamelCase_			:   int       ,						lowerCamelCase_			:   Union[str, Any]  )						->   int:
								__magic_name__							:	Optional[int]    							=							SegformerModel(config=lowerCamelCase_  )
								model.to(lowerCamelCase_  )
								model.eval()
								__magic_name__							:	Optional[Any]    							=							model(lowerCamelCase_  )
								__magic_name__							:	Dict    							=							self.image_size // (self.downsampling_rates[-1] * 2)
								self.parent.assertEqual(
								    result.last_hidden_state.shape       ,						(self.batch_size, self.hidden_sizes[-1], expected_height, expected_width)  )

			def 							UpperCAmelCase__       ( self			:   Optional[Any]       ,						lowerCamelCase_			:   str       ,						lowerCamelCase_			:   Optional[int]       ,						lowerCamelCase_			:   Any  )						->   Optional[Any]:
								__magic_name__							:	str    							=							self.num_labels
								__magic_name__							:	str    							=							SegformerForSemanticSegmentation(lowerCamelCase_  )
								model.to(lowerCamelCase_  )
								model.eval()
								__magic_name__							:	Optional[Any]    							=							model(lowerCamelCase_  )
								self.parent.assertEqual(
								    result.logits.shape       ,						(self.batch_size, self.num_labels, self.image_size // 4, self.image_size // 4)  )
								__magic_name__							:	int    							=							model(lowerCamelCase_       ,						labels=lowerCamelCase_  )
								self.parent.assertEqual(
								    result.logits.shape       ,						(self.batch_size, self.num_labels, self.image_size // 4, self.image_size // 4)  )
								self.parent.assertGreater(result.loss       ,						0.0  )

			def 							UpperCAmelCase__       ( self			:   Tuple       ,						lowerCamelCase_			:   Optional[int]       ,						lowerCamelCase_			:   Dict       ,						lowerCamelCase_			:   List[str]  )						->   List[str]:
								__magic_name__							:	Tuple    							=							1
								__magic_name__							:	int    							=							SegformerForSemanticSegmentation(config=lowerCamelCase_  )
								model.to(lowerCamelCase_  )
								model.eval()
								__magic_name__							:	Dict    							=							torch.randint(0       ,						1       ,						(self.batch_size, self.image_size, self.image_size)  ).to(lowerCamelCase_  )
								__magic_name__							:	List[Any]    							=							model(lowerCamelCase_       ,						labels=lowerCamelCase_  )
								self.parent.assertGreater(result.loss       ,						0.0  )


			def 							UpperCAmelCase__       ( self			:   Dict  )						->   List[str]:
								__magic_name__							:	Optional[Any]    							=							self.prepare_config_and_inputs()
								__magic_name__							,    __magic_name__							,    __magic_name__							:	Dict    							=							config_and_inputs
								__magic_name__							:	List[Any]    							=							{'''pixel_values''': pixel_values}
								return config, inputs_dict






@require_torch
class    lowerCamelCase    (		__UpperCAmelCase				,__UpperCAmelCase				,unittest.TestCase						):






			'''simple docstring'''





			UpperCamelCase__								=(
			    (
			        SegformerModel,
			        SegformerForSemanticSegmentation,
			        SegformerForImageClassification,
			    )
			    if is_torch_available()
			    else ()
			)
			UpperCamelCase__								=(
			    {
			        '''feature-extraction''': SegformerModel,
			        '''image-classification''': SegformerForImageClassification,
			        '''image-segmentation''': SegformerForSemanticSegmentation,
			    }
			    if is_torch_available()
			    else {}
			)

			UpperCamelCase__								=True
			UpperCamelCase__								=False
			UpperCamelCase__								=False
			UpperCamelCase__								=False

			def 							UpperCAmelCase__       ( self			:   Optional[Any]  )						->   Optional[Any]:
								__magic_name__							:	Union[str, Any]    							=							SegformerModelTester(self  )
								__magic_name__							:	Dict    							=							SegformerConfigTester(self       ,						config_class=lowerCamelCase_  )

			def 							UpperCAmelCase__       ( self			:   str  )						->   str:
								self.config_tester.run_common_tests()

			def 							UpperCAmelCase__       ( self			:   Union[str, Any]  )						->   Dict:
								__magic_name__							:	int    							=							self.model_tester.prepare_config_and_inputs()
								self.model_tester.create_and_check_model(*lowerCamelCase_  )

			def 							UpperCAmelCase__       ( self			:   Optional[Any]  )						->   List[Any]:
								__magic_name__							:	Dict    							=							self.model_tester.prepare_config_and_inputs()
								self.model_tester.create_and_check_for_binary_image_segmentation(*lowerCamelCase_  )

			def 							UpperCAmelCase__       ( self			:   Tuple  )						->   Optional[Any]:
								__magic_name__							:	Any    							=							self.model_tester.prepare_config_and_inputs()
								self.model_tester.create_and_check_for_image_segmentation(*lowerCamelCase_  )

			@unittest.skip('''SegFormer does not use inputs_embeds'''  )
			def 							UpperCAmelCase__       ( self			:   Tuple  )						->   List[Any]:
								pass

			@unittest.skip('''SegFormer does not have get_input_embeddings method and get_output_embeddings methods'''  )
			def 							UpperCAmelCase__       ( self			:   Dict  )						->   Optional[Any]:
								pass

			def 							UpperCAmelCase__       ( self			:   Dict  )						->   Optional[int]:
								__magic_name__							,    __magic_name__							:	int    							=							self.model_tester.prepare_config_and_inputs_for_common()

								for model_class in self.all_model_classes:
													__magic_name__							:	int    							=							model_class(lowerCamelCase_  )
													__magic_name__							:	Optional[Any]    							=							inspect.signature(model.forward  )
													# signature.parameters is an OrderedDict => so arg_names order is deterministic
													__magic_name__							:	Union[str, Any]    							=							[*signature.parameters.keys()]

													__magic_name__							:	Optional[int]    							=							['''pixel_values''']
													self.assertListEqual(arg_names[:1]       ,						lowerCamelCase_  )

			def 							UpperCAmelCase__       ( self			:   Union[str, Any]  )						->   Any:
								__magic_name__							,    __magic_name__							:	Union[str, Any]    							=							self.model_tester.prepare_config_and_inputs_for_common()
								__magic_name__							:	List[Any]    							=							True

								for model_class in self.all_model_classes:
													__magic_name__							:	Optional[Any]    							=							True
													__magic_name__							:	Any    							=							False
													__magic_name__							:	int    							=							True
													__magic_name__							:	Optional[Any]    							=							model_class(lowerCamelCase_  )
													model.to(lowerCamelCase_  )
													model.eval()
													with torch.no_grad():
																		__magic_name__							:	Optional[Any]    							=							model(**self._prepare_for_class(lowerCamelCase_       ,						lowerCamelCase_  )  )
													__magic_name__							:	Tuple    							=							outputs.attentions

													__magic_name__							:	List[str]    							=							sum(self.model_tester.depths  )
													self.assertEqual(len(lowerCamelCase_  )       ,						lowerCamelCase_  )

													# check that output_attentions also work using config
													del inputs_dict["output_attentions"]
													__magic_name__							:	Union[str, Any]    							=							True
													__magic_name__							:	Optional[int]    							=							model_class(lowerCamelCase_  )
													model.to(lowerCamelCase_  )
													model.eval()
													with torch.no_grad():
																		__magic_name__							:	List[str]    							=							model(**self._prepare_for_class(lowerCamelCase_       ,						lowerCamelCase_  )  )
													__magic_name__							:	Optional[Any]    							=							outputs.attentions

													self.assertEqual(len(lowerCamelCase_  )       ,						lowerCamelCase_  )

													# verify the first attentions (first block, first layer)
													__magic_name__							:	Optional[Any]    							=							(self.model_tester.image_size // 4) ** 2
													__magic_name__							:	Optional[int]    							=							(self.model_tester.image_size // (4 * self.model_tester.sr_ratios[0])) ** 2
													self.assertListEqual(
													    list(attentions[0].shape[-3:]  )       ,						[self.model_tester.num_attention_heads[0], expected_seq_len, expected_reduced_seq_len]       ,						)

													# verify the last attentions (last block, last layer)
													__magic_name__							:	Tuple    							=							(self.model_tester.image_size // 32) ** 2
													__magic_name__							:	Optional[Any]    							=							(self.model_tester.image_size // (32 * self.model_tester.sr_ratios[-1])) ** 2
													self.assertListEqual(
													    list(attentions[-1].shape[-3:]  )       ,						[self.model_tester.num_attention_heads[-1], expected_seq_len, expected_reduced_seq_len]       ,						)
													__magic_name__							:	List[Any]    							=							len(lowerCamelCase_  )

													# Check attention is always last and order is fine
													__magic_name__							:	Dict    							=							True
													__magic_name__							:	Any    							=							True
													__magic_name__							:	List[Any]    							=							model_class(lowerCamelCase_  )
													model.to(lowerCamelCase_  )
													model.eval()
													with torch.no_grad():
																		__magic_name__							:	Optional[int]    							=							model(**self._prepare_for_class(lowerCamelCase_       ,						lowerCamelCase_  )  )

													self.assertEqual(out_len + 1       ,						len(lowerCamelCase_  )  )

													__magic_name__							:	List[Any]    							=							outputs.attentions

													self.assertEqual(len(lowerCamelCase_  )       ,						lowerCamelCase_  )
													# verify the first attentions (first block, first layer)
													__magic_name__							:	Optional[int]    							=							(self.model_tester.image_size // 4) ** 2
													__magic_name__							:	int    							=							(self.model_tester.image_size // (4 * self.model_tester.sr_ratios[0])) ** 2
													self.assertListEqual(
													    list(self_attentions[0].shape[-3:]  )       ,						[self.model_tester.num_attention_heads[0], expected_seq_len, expected_reduced_seq_len]       ,						)

			def 							UpperCAmelCase__       ( self			:   Optional[int]  )						->   Union[str, Any]:

								def check_hidden_states_output(lowerCamelCase_			:   Any       ,						lowerCamelCase_			:   List[Any]       ,						lowerCamelCase_			:   Union[str, Any]  ):
													__magic_name__							:	Optional[Any]    							=							model_class(lowerCamelCase_  )
													model.to(lowerCamelCase_  )
													model.eval()

													with torch.no_grad():
																		__magic_name__							:	List[str]    							=							model(**self._prepare_for_class(lowerCamelCase_       ,						lowerCamelCase_  )  )

													__magic_name__							:	int    							=							outputs.hidden_states

													__magic_name__							:	Dict    							=							self.model_tester.num_encoder_blocks
													self.assertEqual(len(lowerCamelCase_  )       ,						lowerCamelCase_  )

													# verify the first hidden states (first block)
													self.assertListEqual(
													    list(hidden_states[0].shape[-3:]  )       ,						[
													        self.model_tester.hidden_sizes[0],
													        self.model_tester.image_size // 4,
													        self.model_tester.image_size // 4,
													    ]       ,						)

								__magic_name__							,    __magic_name__							:	int    							=							self.model_tester.prepare_config_and_inputs_for_common()

								for model_class in self.all_model_classes:
													__magic_name__							:	List[Any]    							=							True
													check_hidden_states_output(lowerCamelCase_       ,						lowerCamelCase_       ,						lowerCamelCase_  )

													# check that output_hidden_states also work using config
													del inputs_dict["output_hidden_states"]
													__magic_name__							:	Dict    							=							True

													check_hidden_states_output(lowerCamelCase_       ,						lowerCamelCase_       ,						lowerCamelCase_  )

			def 							UpperCAmelCase__       ( self			:   Any  )						->   int:

								if not self.model_tester.is_training:
													return

								__magic_name__							,    __magic_name__							:	Optional[int]    							=							self.model_tester.prepare_config_and_inputs_for_common()
								__magic_name__							:	Tuple    							=							True

								for model_class in self.all_model_classes:
													if model_class in get_values(lowerCamelCase_  ):
																		continue

													__magic_name__							:	str    							=							model_class(lowerCamelCase_  )
													model.to(lowerCamelCase_  )
													model.train()
													__magic_name__							:	Union[str, Any]    							=							self._prepare_for_class(lowerCamelCase_       ,						lowerCamelCase_       ,						return_labels=lowerCamelCase_  )
													__magic_name__							:	List[str]    							=							model(**lowerCamelCase_  ).loss
													loss.backward()

			@unittest.skip('''Will be fixed soon by reducing the size of the model used for common tests.'''  )
			def 							UpperCAmelCase__       ( self			:   Optional[int]  )						->   Union[str, Any]:
								pass


			@slow
			def 							UpperCAmelCase__       ( self			:   Optional[int]  )						->   Any:

								for model_name in SEGFORMER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
													__magic_name__							:	Any    							=							SegformerModel.from_pretrained(lowerCamelCase_  )
													self.assertIsNotNone(lowerCamelCase_  )







def 		lowercase__   (		):





					'''simple docstring'''






					__magic_name__							:	Dict    							=							Image.open('''./tests/fixtures/tests_samples/COCO/000000039769.png'''				)
					return image


@require_torch
class    lowerCamelCase    (		unittest.TestCase						):






			'''simple docstring'''





			@slow
			def 							UpperCAmelCase__       ( self			:   int  )						->   Any:
								__magic_name__							:	str    							=							SegformerImageProcessor(
								    image_scale=(512, 512)       ,						keep_ratio=lowerCamelCase_       ,						align=lowerCamelCase_       ,						do_random_crop=lowerCamelCase_  )
								__magic_name__							:	List[str]    							=							SegformerForSemanticSegmentation.from_pretrained('''nvidia/segformer-b0-finetuned-ade-512-512'''  ).to(
								    lowerCamelCase_  )

								__magic_name__							:	Tuple    							=							prepare_img()
								__magic_name__							:	Dict    							=							image_processor(images=lowerCamelCase_       ,						return_tensors='''pt'''  )
								__magic_name__							:	Any    							=							encoded_inputs.pixel_values.to(lowerCamelCase_  )

								with torch.no_grad():
													__magic_name__							:	List[str]    							=							model(lowerCamelCase_  )

								__magic_name__							:	Optional[Any]    							=							torch.Size((1, model.config.num_labels, 128, 128)  )
								self.assertEqual(outputs.logits.shape       ,						lowerCamelCase_  )

								__magic_name__							:	Tuple    							=							torch.tensor(
								    [
								        [[-4.6_3_1_0, -5.5_2_3_2, -6.2_3_5_6], [-5.1_9_2_1, -6.1_4_4_4, -6.5_9_9_6], [-5.4_4_2_4, -6.2_7_9_0, -6.7_5_7_4]],
								        [[-1_2.1_3_9_1, -1_3.3_1_2_2, -1_3.9_5_5_4], [-1_2.8_7_3_2, -1_3.9_3_5_2, -1_4.3_5_6_3], [-1_2.9_4_3_8, -1_3.8_2_2_6, -1_4.2_5_1_3]],
								        [[-1_2.5_1_3_4, -1_3.4_6_8_6, -1_4.4_9_1_5], [-1_2.8_6_6_9, -1_4.4_3_4_3, -1_4.7_7_5_8], [-1_3.2_5_2_3, -1_4.5_8_1_9, -1_5.0_6_9_4]],
								    ]  ).to(lowerCamelCase_  )
								self.assertTrue(torch.allclose(outputs.logits[0, :3, :3, :3]       ,						lowerCamelCase_       ,						atol=1E-4  )  )

			@slow
			def 							UpperCAmelCase__       ( self			:   Any  )						->   Dict:
								__magic_name__							:	Union[str, Any]    							=							SegformerImageProcessor(
								    image_scale=(512, 512)       ,						keep_ratio=lowerCamelCase_       ,						align=lowerCamelCase_       ,						do_random_crop=lowerCamelCase_  )
								__magic_name__							:	int    							=							SegformerForSemanticSegmentation.from_pretrained(
								    '''nvidia/segformer-b1-finetuned-cityscapes-1024-1024'''  ).to(lowerCamelCase_  )

								__magic_name__							:	Any    							=							prepare_img()
								__magic_name__							:	Union[str, Any]    							=							image_processor(images=lowerCamelCase_       ,						return_tensors='''pt'''  )
								__magic_name__							:	Dict    							=							encoded_inputs.pixel_values.to(lowerCamelCase_  )

								with torch.no_grad():
													__magic_name__							:	int    							=							model(lowerCamelCase_  )

								__magic_name__							:	Optional[Any]    							=							torch.Size((1, model.config.num_labels, 128, 128)  )
								self.assertEqual(outputs.logits.shape       ,						lowerCamelCase_  )

								__magic_name__							:	Optional[Any]    							=							torch.tensor(
								    [
								        [[-1_3.5_7_4_8, -1_3.9_1_1_1, -1_2.6_5_0_0], [-1_4.3_5_0_0, -1_5.3_6_8_3, -1_4.2_3_2_8], [-1_4.7_5_3_2, -1_6.0_4_2_4, -1_5.6_0_8_7]],
								        [[-1_7.1_6_5_1, -1_5.8_7_2_5, -1_2.9_6_5_3], [-1_7.2_5_8_0, -1_7.3_7_1_8, -1_4.8_2_2_3], [-1_6.6_0_5_8, -1_6.8_7_8_3, -1_6.7_4_5_2]],
								        [[-3.6_4_5_6, -3.0_2_0_9, -1.4_2_0_3], [-3.0_7_9_7, -3.1_9_5_9, -2.0_0_0_0], [-1.8_7_5_7, -1.9_2_1_7, -1.6_9_9_7]],
								    ]  ).to(lowerCamelCase_  )
								self.assertTrue(torch.allclose(outputs.logits[0, :3, :3, :3]       ,						lowerCamelCase_       ,						atol=1E-1  )  )


			@slow
			def 							UpperCAmelCase__       ( self			:   Tuple  )						->   Any:
								__magic_name__							:	str    							=							SegformerImageProcessor(
								    image_scale=(512, 512)       ,						keep_ratio=lowerCamelCase_       ,						align=lowerCamelCase_       ,						do_random_crop=lowerCamelCase_  )
								__magic_name__							:	str    							=							SegformerForSemanticSegmentation.from_pretrained('''nvidia/segformer-b0-finetuned-ade-512-512'''  ).to(
								    lowerCamelCase_  )

								__magic_name__							:	Any    							=							prepare_img()
								__magic_name__							:	Dict    							=							image_processor(images=lowerCamelCase_       ,						return_tensors='''pt'''  )
								__magic_name__							:	Dict    							=							encoded_inputs.pixel_values.to(lowerCamelCase_  )

								with torch.no_grad():
													__magic_name__							:	Any    							=							model(lowerCamelCase_  )

								__magic_name__							:	int    							=							outputs.logits.detach().cpu()

								__magic_name__							:	Any    							=							image_processor.post_process_semantic_segmentation(outputs=lowerCamelCase_       ,						target_sizes=[(500, 300)]  )
								__magic_name__							:	Optional[int]    							=							torch.Size((500, 300)  )
								self.assertEqual(segmentation[0].shape       ,						lowerCamelCase_  )

								__magic_name__							:	int    							=							image_processor.post_process_semantic_segmentation(outputs=lowerCamelCase_  )
								__magic_name__							:	str    							=							torch.Size((128, 128)  )
								self.assertEqual(segmentation[0].shape       ,						lowerCamelCase_  )









import requests







def 		lowercase__   (		__A:	str							,__A:	str				):





					'''simple docstring'''






					__magic_name__							:	Tuple    							=							{'''Content-Type''': '''application/json'''}
					__magic_name__							:	Union[str, Any]    							=							requests.post(__A							,json={'''text''': message_body}							,headers=__A				)
					if response.status_code != 2_0_0:
										__magic_name__							:	int    							=							(
										    '''Request to slack returned an error '''
										    F'''{response.status_code}, the response is:\n{response.text}'''
										)
										raise ValueError(__A				)


if __name__ == "__main__":
	# Set the slack url to the one provided by Slack when you create the webhook at
	# https://my.slack.com/services/new/incoming-webhook/
	send_slack_message('''<YOUR MESSAGE BODY>''', '''<SLACK CHANNEL URL>''')



