
import argparse

import gdown
import numpy as np
import torch
from huggingface_hub import hf_hub_download

from transformers import (
    CLIPTokenizer,
    CLIPTokenizerFast,
    VideoMAEImageProcessor,
    XCLIPConfig,
    XCLIPModel,
    XCLIPProcessor,
    XCLIPTextConfig,
    XCLIPVisionConfig,
)






def 							UpperCAmelCase_		(							__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE							):
	lowercase       =    XCLIPTextConfig()

	# derive patch size from model name
	lowercase       =    model_name.find('patch'							)
	lowercase       =    int(model_name[start_idx + len('patch'							) : start_idx + len('patch'							) + 2]							)
	lowercase       =    XCLIPVisionConfig(patch_size=__SCREAMING_SNAKE_CASE ,							num_frames=__SCREAMING_SNAKE_CASE							)

	if "large" in model_name:
		lowercase       =    768
		lowercase       =    3072
		lowercase       =    12

		lowercase       =    1024
		lowercase       =    4096
		lowercase       =    16
		lowercase       =    24
		lowercase       =    768
		lowercase       =    3072

	if model_name == "xclip-large-patch14-16-frames":
		lowercase       =    336

	lowercase       =    XCLIPConfig.from_text_vision_configs(__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE							)

	if "large" in model_name:
		lowercase       =    768

	return config






def 							UpperCAmelCase_		(							__SCREAMING_SNAKE_CASE							):
	# text encoder
	if name == "token_embedding.weight":
		lowercase       =    name.replace('token_embedding.weight' ,							'text_model.embeddings.token_embedding.weight'							)
	if name == "positional_embedding":
		lowercase       =    name.replace('positional_embedding' ,							'text_model.embeddings.position_embedding.weight'							)
	if "ln_1" in name:
		lowercase       =    name.replace('ln_1' ,							'layer_norm1'							)
	if "ln_2" in name:
		lowercase       =    name.replace('ln_2' ,							'layer_norm2'							)
	if "c_fc" in name:
		lowercase       =    name.replace('c_fc' ,							'fc1'							)
	if "c_proj" in name:
		lowercase       =    name.replace('c_proj' ,							'fc2'							)
	if name.startswith('transformer.resblocks'							):
		lowercase       =    name.replace('transformer.resblocks' ,							'text_model.encoder.layers'							)
	if "attn.out_proj" in name and "message" not in name:
		lowercase       =    name.replace('attn.out_proj' ,							'self_attn.out_proj'							)
	if "ln_final" in name:
		lowercase       =    name.replace('ln_final' ,							'text_model.final_layer_norm'							)
	# visual encoder
	if name == "visual.class_embedding":
		lowercase       =    name.replace('visual.class_embedding' ,							'vision_model.embeddings.class_embedding'							)
	if name == "visual.positional_embedding":
		lowercase       =    name.replace('visual.positional_embedding' ,							'vision_model.embeddings.position_embedding.weight'							)
	if name.startswith('visual.transformer.resblocks'							):
		lowercase       =    name.replace('visual.transformer.resblocks' ,							'vision_model.encoder.layers'							)
	if "visual.conv1" in name:
		lowercase       =    name.replace('visual.conv1' ,							'vision_model.embeddings.patch_embedding'							)
	if "visual.ln_pre" in name:
		lowercase       =    name.replace('visual.ln_pre' ,							'vision_model.pre_layernorm'							)
	if "visual.ln_post" in name:
		lowercase       =    name.replace('visual.ln_post' ,							'vision_model.post_layernorm'							)
	if "visual.proj" in name:
		lowercase       =    name.replace('visual.proj' ,							'visual_projection.weight'							)
	if "text_projection" in name:
		lowercase       =    name.replace('text_projection' ,							'text_projection.weight'							)
	# things on top
	if "prompts_visual_proj" in name:
		lowercase       =    name.replace('prompts_visual_proj' ,							'prompts_visual_projection'							)
	if "prompts_visual_ln" in name:
		lowercase       =    name.replace('prompts_visual_ln' ,							'prompts_visual_layernorm'							)
	# mit
	if name == "mit.positional_embedding":
		lowercase       =    name.replace('positional' ,							'position'							)
	if name.startswith('mit.resblocks'							):
		lowercase       =    name.replace('mit.resblocks' ,							'mit.encoder.layers'							)
	# prompts generator
	if name.startswith('prompts_generator.norm'							):
		lowercase       =    name.replace('prompts_generator.norm' ,							'prompts_generator.layernorm'							)

	return name






def 							UpperCAmelCase_		(							__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE							):
	for key in orig_state_dict.copy().keys():
		lowercase       =    orig_state_dict.pop(__SCREAMING_SNAKE_CASE							)

		if "attn.in_proj" in key:
			lowercase       =    key.split('.'							)
			if key.startswith('visual'							):
				lowercase       =    key_split[3]
				lowercase       =    config.vision_config.hidden_size
				if "message_attn" in key:
					if "weight" in key:
						lowercase       =    val[
						    :dim, :
						]
						lowercase       =    val[
						    dim : dim * 2, :
						]
						lowercase       =    val[
						    -dim:, :
						]
					else:
						lowercase       =    val[
						    :dim
						]
						lowercase       =    val[
						    dim : dim * 2
						]
						lowercase       =    val[
						    -dim:
						]
				else:
					if "weight" in key:
						lowercase       =    val[
						    :dim, :
						]
						lowercase       =    val[
						    dim : dim * 2, :
						]
						lowercase       =    val[
						    -dim:, :
						]
					else:
						lowercase       =    val[:dim]
						lowercase       =    val[
						    dim : dim * 2
						]
						lowercase       =    val[-dim:]
			elif key.startswith('mit'							):
				lowercase       =    key_split[2]
				lowercase       =    config.vision_config.mit_hidden_size
				if "weight" in key:
					lowercase       =    val[:dim, :]
					lowercase       =    val[dim : dim * 2, :]
					lowercase       =    val[-dim:, :]
				else:
					lowercase       =    val[:dim]
					lowercase       =    val[dim : dim * 2]
					lowercase       =    val[-dim:]
			else:
				lowercase       =    key_split[2]
				lowercase       =    config.text_config.hidden_size
				if "weight" in key:
					lowercase       =    val[:dim, :]
					lowercase       =    val[
					    dim : dim * 2, :
					]
					lowercase       =    val[-dim:, :]
				else:
					lowercase       =    val[:dim]
					lowercase       =    val[
					    dim : dim * 2
					]
					lowercase       =    val[-dim:]
		else:
			lowercase       =    rename_key(__SCREAMING_SNAKE_CASE							)
			if new_key_name in ["visual_projection.weight", "text_projection.weight"]:
				lowercase       =    val.T
			lowercase       =    val

	return orig_state_dict






def 							UpperCAmelCase_		(							__SCREAMING_SNAKE_CASE							):
	if num_frames == 8:
		lowercase       =    'eating_spaghetti_8_frames.npy'
	elif num_frames == 16:
		lowercase       =    'eating_spaghetti.npy'
	elif num_frames == 32:
		lowercase       =    'eating_spaghetti_32_frames.npy'
	lowercase       =    hf_hub_download(
	    repo_id='hf-internal-testing/spaghetti-video' ,							filename=__SCREAMING_SNAKE_CASE ,							repo_type='dataset' ,							)
	lowercase       =    np.load(__SCREAMING_SNAKE_CASE							)
	return list(__SCREAMING_SNAKE_CASE							)






def 							UpperCAmelCase_		(							__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE=None ,							__SCREAMING_SNAKE_CASE=False							):
	lowercase       =    {
	    # fully supervised kinetics-400 checkpoints
	    'xclip-base-patch32': 'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/k400_32_8.pth',
	    'xclip-base-patch32-16-frames': (
	        'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/k400_32_16.pth'
	    ),
	    'xclip-base-patch16': 'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/k400_16_8.pth',
	    'xclip-base-patch16-16-frames': (
	        'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/k400_16_16.pth'
	    ),
	    'xclip-large-patch14': 'https://drive.google.com/u/0/uc?id=1NUOImq0o5DlQTST17iIP3vG7DgmHQuCx&amp;export=download&amp;confirm=t&amp;uuid=b26caedc-88e2-473e-830a-9d158b653cdb',
	    'xclip-large-patch14-16-frames': 'https://drive.google.com/u/0/uc?id=1FOYgnJc097OJ4lGwtRCCydQyVPJEOH7d&amp;export=download&amp;confirm=t&amp;uuid=538fa810-e671-4050-b385-9a623f89804f',
	    # fully supervised kinetics-600 checkpoints
	    'xclip-base-patch16-kinetics-600': (
	        'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/k600_16_8.pth'
	    ),
	    'xclip-base-patch16-kinetics-600-16-frames': (
	        'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/k600_16_16.pth'
	    ),
	    'xclip-large-patch14-kinetics-600': 'https://drive.google.com/u/0/uc?id=1FV8C1INuM91sLAN4ImjzePLIlpMSihwV&amp;export=download&amp;confirm=t&amp;uuid=141d4977-4a65-44ae-864f-4b0c19f838be',
	    # few shot
	    'xclip-base-patch16-hmdb-2-shot': (
	        'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_hmdb_2.pth'
	    ),
	    'xclip-base-patch16-hmdb-4-shot': (
	        'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_hmdb_4.pth'
	    ),
	    'xclip-base-patch16-hmdb-8-shot': (
	        'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_hmdb_8.pth'
	    ),
	    'xclip-base-patch16-hmdb-16-shot': (
	        'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_hmdb_16.pth'
	    ),
	    'xclip-base-patch16-ucf-2-shot': (
	        'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_ucf_2.pth'
	    ),
	    'xclip-base-patch16-ucf-4-shot': (
	        'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_ucf_4.pth'
	    ),
	    'xclip-base-patch16-ucf-8-shot': (
	        'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_ucf_8.pth'
	    ),
	    'xclip-base-patch16-ucf-16-shot': (
	        'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/few_ucf_16.pth'
	    ),
	    # zero shot
	    'xclip-base-patch16-zero-shot': 'https://github.com/nbl97/X-CLIP_Model_Zoo/releases/download/v1.0/zero.pth',
	}

	lowercase       =    model_to_url[model_name]
	lowercase       =    8
	if "16-frames" in model_name:
		lowercase       =    16
	elif "shot" in model_name:
		lowercase       =    32

	lowercase       =    get_xclip_config(__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE							)
	lowercase       =    XCLIPModel(__SCREAMING_SNAKE_CASE							)
	model.eval()

	if "drive" in checkpoint_url:
		lowercase       =    'pytorch_model.bin'
		gdown.cached_download(__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE ,							quiet=__SCREAMING_SNAKE_CASE							)
		lowercase       =    torch.load(__SCREAMING_SNAKE_CASE ,							map_location='cpu'							)['model']
	else:
		lowercase       =    torch.hub.load_state_dict_from_url(__SCREAMING_SNAKE_CASE							)['model']

	lowercase       =    convert_state_dict(__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE							)

	lowercase       =    XCLIPModel(__SCREAMING_SNAKE_CASE							)
	lowercase  ,					lowercase       =    model.load_state_dict(__SCREAMING_SNAKE_CASE ,							strict=__SCREAMING_SNAKE_CASE							)
	assert missing_keys == ["text_model.embeddings.position_ids", "vision_model.embeddings.position_ids"]
	model.eval()

	lowercase       =    336 if model_name == 'xclip-large-patch14-16-frames' else 224
	lowercase       =    VideoMAEImageProcessor(size=__SCREAMING_SNAKE_CASE							)
	lowercase       =    CLIPTokenizer.from_pretrained('openai/clip-vit-base-patch32'							)
	lowercase       =    CLIPTokenizerFast.from_pretrained('openai/clip-vit-base-patch32'							)
	lowercase       =    XCLIPProcessor(image_processor=__SCREAMING_SNAKE_CASE ,							tokenizer=__SCREAMING_SNAKE_CASE							)

	lowercase       =    prepare_video(__SCREAMING_SNAKE_CASE							)
	lowercase       =    processor(
	    text=['playing sports', 'eating spaghetti', 'go shopping'] ,							videos=__SCREAMING_SNAKE_CASE ,							return_tensors='pt' ,							padding=__SCREAMING_SNAKE_CASE							)

	print('Shape of pixel values:' ,							inputs.pixel_values.shape							)

	with torch.no_grad():
		lowercase       =    model(**__SCREAMING_SNAKE_CASE							)

	# Verify outputs
	lowercase       =    outputs.logits_per_video
	lowercase       =    logits_per_video.softmax(dim=1							)
	print('Probs:' ,							__SCREAMING_SNAKE_CASE							)
	# kinetics-400
	if model_name == "xclip-base-patch32":
		lowercase       =    torch.tensor([[0.00_19, 0.99_51, 0.00_30]]							)
	elif model_name == "xclip-base-patch32-16-frames":
		lowercase       =    torch.tensor([[7.09_99e-04, 9.98_83e-01, 4.55_80e-04]]							)
	elif model_name == "xclip-base-patch16":
		lowercase       =    torch.tensor([[0.00_83, 0.96_81, 0.02_36]]							)
	elif model_name == "xclip-base-patch16-16-frames":
		lowercase       =    torch.tensor([[7.69_37e-04, 9.97_28e-01, 1.94_73e-03]]							)
	elif model_name == "xclip-large-patch14":
		lowercase       =    torch.tensor([[0.00_62, 0.98_64, 0.00_75]]							)
	elif model_name == "xclip-large-patch14-16-frames":
		lowercase       =    torch.tensor([[3.38_77e-04, 9.99_37e-01, 2.88_88e-04]]							)
	# kinetics-600
	elif model_name == "xclip-base-patch16-kinetics-600":
		lowercase       =    torch.tensor([[0.05_55, 0.89_14, 0.05_31]]							)
	elif model_name == "xclip-base-patch16-kinetics-600-16-frames":
		lowercase       =    torch.tensor([[3.85_54e-04, 9.99_29e-01, 3.27_54e-04]]							)
	elif model_name == "xclip-large-patch14-kinetics-600":
		lowercase       =    torch.tensor([[0.00_36, 0.99_20, 0.00_45]]							)
	# few shot
	elif model_name == "xclip-base-patch16-hmdb-2-shot":
		lowercase       =    torch.tensor([[7.18_90e-06, 9.99_94e-01, 5.65_59e-05]]							)
	elif model_name == "xclip-base-patch16-hmdb-4-shot":
		lowercase       =    torch.tensor([[1.03_20e-05, 9.99_93e-01, 6.24_35e-05]]							)
	elif model_name == "xclip-base-patch16-hmdb-8-shot":
		lowercase       =    torch.tensor([[4.13_77e-06, 9.99_90e-01, 9.83_86e-05]]							)
	elif model_name == "xclip-base-patch16-hmdb-16-shot":
		lowercase       =    torch.tensor([[4.13_47e-05, 9.99_62e-01, 3.34_11e-04]]							)
	elif model_name == "xclip-base-patch16-ucf-2-shot":
		lowercase       =    torch.tensor([[8.58_57e-05, 9.99_28e-01, 6.32_91e-04]]							)
	elif model_name == "xclip-base-patch16-ucf-4-shot":
		lowercase       =    torch.tensor([[8.58_57e-05, 9.99_28e-01, 6.32_91e-04]]							)
	elif model_name == "xclip-base-patch16-ucf-8-shot":
		lowercase       =    torch.tensor([[0.00_27, 0.99_04, 0.00_70]]							)
	elif model_name == "xclip-base-patch16-ucf-16-shot":
		lowercase       =    torch.tensor([[9.82_19e-04, 9.95_93e-01, 3.08_63e-03]]							)
	# zero shot
	elif model_name == "xclip-base-patch16-zero-shot":
		lowercase       =    torch.tensor([[3.50_82e-04, 9.97_85e-01, 1.79_66e-03]]							)
	else:
		raise ValueError(F'''Model name {model_name} not supported'''							)
	assert torch.allclose(__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE ,							atol=1e-3							)
	print('Looks ok!'							)

	if pytorch_dump_folder_path is not None:
		print(F'''Saving model {model_name} to {pytorch_dump_folder_path}'''							)
		model.save_pretrained(__SCREAMING_SNAKE_CASE							)

	if push_to_hub:
		print('Pushing model, processor and slow tokenizer files to the hub...'							)
		model.push_to_hub(__SCREAMING_SNAKE_CASE ,							organization='nielsr'							)
		processor.push_to_hub(__SCREAMING_SNAKE_CASE ,							organization='nielsr'							)
		slow_tokenizer.push_to_hub(__SCREAMING_SNAKE_CASE ,							organization='nielsr'							)


if __name__ == "__main__":
	UpperCAmelCase	      = argparse.ArgumentParser()
	# Required parameters
	parser.add_argument(
	    '''--model_name''',
	    default='''xclip-base-patch32''',
	    type=str,
	    help='''Name of the model.''',
	)
	parser.add_argument(
	    '''--pytorch_dump_folder_path''', default=None, type=str, help='''Path to the output PyTorch model directory.'''
	)
	parser.add_argument(
	    '''--push_to_hub''', action='''store_true''', help='''Whether or not to push the converted model to the 🤗 hub.'''
	)

	UpperCAmelCase	      = parser.parse_args()
	convert_xclip_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)



import collections
import json
import math
import os
import re
import time
from fnmatch import fnmatch
from typing import Dict

import requests
from slack_sdk import WebClient


UpperCAmelCase	      = WebClient(token=os.environ['''CI_SLACK_BOT_TOKEN'''])






def 							UpperCAmelCase_		(							__SCREAMING_SNAKE_CASE							):
	lowercase       =    test_results.split(' '							)

	lowercase       =    0
	lowercase       =    0

	# When the output is short enough, the output is surrounded by = signs: "== OUTPUT =="
	# When it is too long, those signs are not present.
	lowercase       =    expressions[-2] if '=' in expressions[-1] else expressions[-1]

	for i, expression in enumerate(__SCREAMING_SNAKE_CASE							):
		if "failed" in expression:
			failed += int(expressions[i - 1]							)
		if "passed" in expression:
			success += int(expressions[i - 1]							)

	return failed, success, time_spent






def 							UpperCAmelCase_		(							__SCREAMING_SNAKE_CASE							):
	lowercase       =    {}
	lowercase       =    None
	lowercase       =    False
	for line in failures_short_lines.split('\n'							):
		if re.search(r'_ \[doctest\]' ,							__SCREAMING_SNAKE_CASE							):
			lowercase       =    True
			lowercase       =    line.split(' '							)[2]
		elif in_error and not line.split(' '							)[0].isdigit():
			lowercase       =    line
			lowercase       =    False

	return failures







class        A_   :




	'''simple docstring'''


	def __init__(       self		,    snake_case		,    snake_case       ):
		lowercase       =    title

		lowercase       =    doc_test_results['time_spent'].split(','       )[0]
		lowercase       =    doc_test_results['success']
		lowercase       =    doc_test_results['failures']
		lowercase       =    self.n_success + self.n_failures

		# Failures and success of the modeling tests
		lowercase       =    doc_test_results





	@property
	def 	SCREAMING_SNAKE_CASE__						(       self       ):
		lowercase       =    [self._time_spent]
		lowercase       =    0

		for time in time_spent:
			lowercase       =    time.split(':'       )

			# Time can be formatted as xx:xx:xx, as .xx, or as x.xx if the time spent was less than a minute.
			if len(snake_case       ) == 1:
				lowercase       =    [0, 0, time_parts[0]]

			lowercase  ,					lowercase  ,					lowercase       =    int(time_parts[0]       ), int(time_parts[1]       ), float(time_parts[2]       )
			total_secs += hours * 3600 + minutes * 60 + seconds

		lowercase  ,					lowercase  ,					lowercase       =    total_secs // 3600, (total_secs % 3600) // 60, total_secs % 60
		return F'''{int(snake_case       )}h{int(snake_case       )}m{int(snake_case       )}s'''





	@property
	def 	SCREAMING_SNAKE_CASE__						(       self       ):
		return {"type": "header", "text": {"type": "plain_text", "text": self.title}}





	@property
	def 	SCREAMING_SNAKE_CASE__						(       self       ):
		return {
		    "type": "section",
		    "text": {
		        "type": "plain_text",
		        "text": F'''🌞 There were no failures: all {self.n_tests} tests passed. The suite ran in {self.time}.''',
		        "emoji": True,
		    },
		    "accessory": {
		        "type": "button",
		        "text": {"type": "plain_text", "text": "Check Action results", "emoji": True},
		        "url": F'''https://github.com/huggingface/transformers/actions/runs/{os.environ['GITHUB_RUN_ID']}''',
		    },
		}





	@property
	def 	SCREAMING_SNAKE_CASE__						(       self       ):
		return {
		    "type": "section",
		    "text": {
		        "type": "plain_text",
		        "text": (
		            F'''There were {self.n_failures} failures, out of {self.n_tests} tests.\nThe suite ran in'''
		            F''' {self.time}.'''
		        ),
		        "emoji": True,
		    },
		    "accessory": {
		        "type": "button",
		        "text": {"type": "plain_text", "text": "Check Action results", "emoji": True},
		        "url": F'''https://github.com/huggingface/transformers/actions/runs/{os.environ['GITHUB_RUN_ID']}''',
		    },
		}





	@property
	def 	SCREAMING_SNAKE_CASE__						(       self       ):
		lowercase       =    40
		lowercase       =    {k: v['failed'] for k, v in doc_test_results.items() if isinstance(snake_case		,    snake_case       )}

		lowercase       =    ''
		for category, failures in category_failures.items():
			if len(snake_case       ) == 0:
				continue

			if report != "":
				report += "\n\n"

			report += F'''*{category} failures*:'''.ljust(line_length // 2       ).rjust(line_length // 2       ) + "\n"
			report += "`"
			report += "`\n`".join(snake_case       )
			report += "`"

		return {
		    "type": "section",
		    "text": {
		        "type": "mrkdwn",
		        "text": F'''The following examples had failures:\n\n\n{report}\n''',
		    },
		}





	@property
	def 	SCREAMING_SNAKE_CASE__						(       self       ):
		lowercase       =    [self.header]

		if self.n_failures > 0:
			blocks.append(self.failures       )

		if self.n_failures > 0:
			blocks.extend([self.category_failures]       )

		if self.n_failures == 0:
			blocks.append(self.no_failures       )

		return json.dumps(snake_case       )





	@staticmethod
	def 	SCREAMING_SNAKE_CASE__						(       ):
		lowercase       =    [
		    {
		        'type': 'section',
		        'text': {
		            'type': 'plain_text',
		            'text': 'There was an issue running the tests.',
		        },
		        'accessory': {
		            'type': 'button',
		            'text': {'type': 'plain_text', 'text': 'Check Action results', 'emoji': True},
		            'url': F'''https://github.com/huggingface/transformers/actions/runs/{os.environ['GITHUB_RUN_ID']}''',
		        },
		    }
		]

		print('Sending the following payload'       )
		print(json.dumps({'blocks': json.loads(snake_case       )}       )       )

		client.chat_postMessage(
		    channel=os.environ['CI_SLACK_CHANNEL_ID_DAILY']		,    text='There was an issue running the tests.'		,    blocks=snake_case		,    )





	def 	SCREAMING_SNAKE_CASE__						(       self       ):
		print('Sending the following payload'       )
		print(json.dumps({'blocks': json.loads(self.payload       )}       )       )

		lowercase       =    F'''{self.n_failures} failures out of {self.n_tests} tests,''' if self.n_failures else 'All tests passed.'

		lowercase       =    client.chat_postMessage(
		    channel=os.environ['CI_SLACK_CHANNEL_ID_DAILY']		,    blocks=self.payload		,    text=snake_case		,    )





	def 	SCREAMING_SNAKE_CASE__						(       self		,    snake_case		,    snake_case		,    snake_case		,    snake_case       ):
		lowercase       =    ''
		for key, value in failures.items():
			lowercase       =    value[:200] + ' [Truncated]' if len(snake_case       ) > 250 else value
			failures_text += F'''*{key}*\n_{value}_\n\n'''

		lowercase       =    job_name
		lowercase       =    {'type': 'section', 'text': {'type': 'mrkdwn', 'text': text}}

		if job_link is not None:
			lowercase       =    {
			    'type': 'button',
			    'text': {'type': 'plain_text', 'text': 'GitHub Action job', 'emoji': True},
			    'url': job_link,
			}

		return [
		    {"type": "header", "text": {"type": "plain_text", "text": title.upper(), "emoji": True}},
		    content,
		    {"type": "section", "text": {"type": "mrkdwn", "text": failures_text}},
		]





	def 	SCREAMING_SNAKE_CASE__						(       self       ):
		if self.thread_ts is None:
			raise ValueError('Can only post reply if a post has been made.'       )

		lowercase       =    self.doc_test_results.pop('job_link'       )
		self.doc_test_results.pop('failures'       )
		self.doc_test_results.pop('success'       )
		self.doc_test_results.pop('time_spent'       )

		lowercase       =    sorted(self.doc_test_results.items()		,    key=lambda snake_case       : t[0]       )
		for job, job_result in sorted_dict:
			if len(job_result['failures']       ):
				lowercase       =    F'''*Num failures* :{len(job_result['failed']       )} \n'''
				lowercase       =    job_result['failures']
				lowercase       =    self.get_reply_blocks(snake_case		,    snake_case		,    snake_case		,    text=snake_case       )

				print('Sending the following reply'       )
				print(json.dumps({'blocks': blocks}       )       )

				client.chat_postMessage(
				    channel=os.environ['CI_SLACK_CHANNEL_ID_DAILY']		,    text=F'''Results for {job}'''		,    blocks=snake_case		,    thread_ts=self.thread_ts['ts']		,    )

				time.sleep(1       )






def 							UpperCAmelCase_		(							):
	lowercase       =    os.environ['GITHUB_RUN_ID']
	lowercase       =    F'''https://api.github.com/repos/huggingface/transformers/actions/runs/{run_id}/jobs?per_page=100'''
	lowercase       =    requests.get(__SCREAMING_SNAKE_CASE							).json()
	lowercase       =    {}

	try:
		jobs.update({job['name']: job['html_url'] for job in result['jobs']}							)
		lowercase       =    math.ceil((result['total_count'] - 100) / 100							)

		for i in range(__SCREAMING_SNAKE_CASE							):
			lowercase       =    requests.get(url + F'''&page={i + 2}'''							).json()
			jobs.update({job['name']: job['html_url'] for job in result['jobs']}							)

		return jobs
	except Exception as e:
		print('Unknown error, could not fetch links.' ,							__SCREAMING_SNAKE_CASE							)

	return {}






def 							UpperCAmelCase_		(							__SCREAMING_SNAKE_CASE							):
	lowercase       =    {}

	if os.path.exists(__SCREAMING_SNAKE_CASE							):
		lowercase       =    os.listdir(__SCREAMING_SNAKE_CASE							)
		for file in files:
			try:
				with open(os.path.join(__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE							) ,							encoding='utf-8'							) as f:
					lowercase       =    f.read()
			except UnicodeDecodeError as e:
				raise ValueError(F'''Could not open {os.path.join(__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE							)}.'''							) from e

	return _artifact






def 							UpperCAmelCase_		(							):







	class        A_   :




		'''simple docstring'''


		def __init__(       self		,    snake_case       ):
			lowercase       =    name
			lowercase       =    []





		def __str__(       self       ):
			return self.name





		def 	SCREAMING_SNAKE_CASE__						(       self		,    snake_case       ):
			self.paths.append({'name': self.name, 'path': path}       )




	lowercase       =    {}

	lowercase       =    filter(os.path.isdir ,							os.listdir()							)
	for directory in directories:
		lowercase       =    directory
		if artifact_name not in _available_artifacts:
			lowercase       =    Artifact(__SCREAMING_SNAKE_CASE							)

			_available_artifacts[artifact_name].add_path(__SCREAMING_SNAKE_CASE							)

	return _available_artifacts


if __name__ == "__main__":
	UpperCAmelCase	      = get_job_links()
	UpperCAmelCase	      = retrieve_available_artifacts()

	UpperCAmelCase	      = collections.OrderedDict(
	    [
	        ('''*.py''', '''API Examples'''),
	        ('''*.md''', '''MD Examples'''),
	    ]
	)

	# This dict will contain all the information relative to each doc test category:
	# - failed: list of failed tests
	# - failures: dict in the format 'test': 'error_message'
	UpperCAmelCase	      = {
	    v: {
	        '''failed''': [],
	        '''failures''': {},
	    }
	    for v in docs.values()
	}

	# Link to the GitHub Action job
	UpperCAmelCase	      = github_actions_job_links.get('''run_doctests''')

	UpperCAmelCase	      = available_artifacts['''doc_tests_gpu_test_reports'''].paths[0]
	UpperCAmelCase	      = retrieve_artifact(artifact_path['''name'''])
	if "stats" in artifact:
		UpperCAmelCase      , UpperCAmelCase      , UpperCAmelCase	      = handle_test_results(artifact['''stats'''])
		UpperCAmelCase	      = failed
		UpperCAmelCase	      = success
		UpperCAmelCase	      = time_spent[1:-1] + ''', '''

		UpperCAmelCase	      = extract_first_line_failure(artifact['''failures_short'''])
		for line in artifact["summary_short"].split('''\n'''):
			if re.search('''FAILED''', line):
				UpperCAmelCase	      = line.replace('''FAILED ''', '''''')
				UpperCAmelCase	      = line.split()[0].replace('''\n''', '''''')

				if "::" in line:
					UpperCAmelCase      , UpperCAmelCase	      = line.split('''::''')
				else:
					UpperCAmelCase      , UpperCAmelCase	      = line, line

				for file_regex in docs.keys():
					if fnmatch(file_path, file_regex):
						UpperCAmelCase	      = docs[file_regex]
						doc_test_results[category]["failed"].append(test)

						UpperCAmelCase	      = all_failures[test] if test in all_failures else '''N/A'''
						UpperCAmelCase	      = failure
						break

	UpperCAmelCase	      = Message('''🤗 Results of the doc tests.''', doc_test_results)
	message.post()
	message.post_reply()

