import gradio as gr from bs4 import BeautifulSoup import json import time import os from transformers import AutoTokenizer, pipeline example1 = ''' Contact Form

Contact Form








''' solution1 = '''{ "name": "Ana Guida", "email": "example@gmail.com", "location": "Amsterdam, Netherlands", "github": "https://github.com/34kmddfn", "linkedin": "https://www.linkedin.com/in/ana-rguida/", "phone": "+351 928 169 341" }''' example2 = ''' Resume Form










''' solution2 = '''{ "pet": "dog", "color": [ "black", "brown" ] }''' example3 = ''' Create account Form







''' solution3 = '''{ "name": "Mike", "country": "Germany", "birthday": "1990-05-07" }''' models = { "model_n1": "sileod/deberta-v3-base-tasksource-nli", # "model_n2": "roberta-large-mnli", # "model_n3": "facebook/bart-large-mnli", # "model_n4": "cross-encoder/nli-deberta-v3-xsmall" } def find_form_fields_from_file(file): with open(file.name, "r") as f: content = f.read() return find_form_fields(content) def find_form_fields(html_content): soup = BeautifulSoup(html_content, 'html.parser') # find all form tags forms = soup.find_all('form') form_fields = [] for form in forms: # find all input and select tags within each form input_tags = form.find_all('input') select_tags = form.find_all('select') for tag in input_tags: form_fields.append(str(tag)) for tag in select_tags: form_fields.append(str(tag)) # Convert the list to a single string for display return form_fields def load_json(json_file): with open(json_file, 'r') as f: data = json.load(f) return data def classify_lines(text, candidate_labels, model_name): start_time = time.time() # Start measuring time classifier = pipeline('zero-shot-classification', model=model_name) # Check if the text is already a list or if it needs splitting if isinstance(text, list): lines = text else: lines = text.split('\n') classified_lines = [] for line in lines: if line.strip() and (line.strip().startswith(" - certainty: {format(top_scores[0], '.2f')} -->" elif results['labels'][0] == "button": # print("button") last_input = "button" line = line + f"" elif results['labels'][0] == "radio": # print("radio") if(last_input == "radio"): radio_options.append(line) radio_options_i.append(i) else: radio_options = [line] radio_options_i = [i] radio_results_list = [] last_input = "radio" input_results = classifier(line, candidate_labels=candidate_labels) top_classifications = input_results['labels'][:2] # Get the top two classifications top_scores = input_results['scores'][:2] # Get the top two scores radio_results = classifier(line, candidate_labels=[json_content[top_classifications[0]]]) radio_results_list.append(radio_results) # Get the scores from the radio_results_list scores = [result['scores'][0] for result in radio_results_list] previous_max_index = max_index # Find the index of the maximum score max_index = scores.index(max(scores)) if previous_max_index != max_index: line_selected = radio_options[previous_max_index] real_index = radio_options_i[previous_max_index] if real_index < len(output_content): output_content[real_index] = line_selected line_selected = radio_options[max_index] line_selected = line_selected + f"" real_index = radio_options_i[max_index] if real_index < len(output_content): output_content[real_index] = line_selected else: line = line_selected elif results['labels'][0] == "checkbox": # print("checkbox") last_input = "checkbox" input_results = classifier(line, candidate_labels=candidate_labels) top_classifications = input_results['labels'][:2] # Get the top two classifications top_scores = input_results['scores'][:2] # Get the top two scores checkbox_results = classifier(line, candidate_labels=[json_content[top_classifications[0]]]) if checkbox_results['scores'][0] > 0.8: line = line + f"" else: #elif results['labels'][0] == "select" or results['labels'][0] == "option": # print("select") if(last_input == "select"): select_options.append(line) select_options_i.append(i) else: select_options = [line] select_options_i = [i] select_results_list = [] last_input = "select" input_results = classifier(line, candidate_labels=candidate_labels) top_classifications = input_results['labels'][:2] # Get the top two classifications top_scores = input_results['scores'][:2] # Get the top two scores select_results = classifier(line, candidate_labels=[json_content[top_classifications[0]]]) select_results_list.append(select_results) # Get the scores from the select_results_list scores = [result['scores'][0] for result in select_results_list] previous_max_index = max_index # Find the index of the maximum score max_index = scores.index(max(scores)) if previous_max_index != max_index: line_selected = select_options[previous_max_index] real_index = select_options_i[previous_max_index] if real_index < len(output_content): output_content[real_index] = line_selected line_selected = select_options[max_index] line_selected = line_selected + f"" real_index = select_options_i[max_index] if real_index < len(output_content): output_content[real_index] = line_selected else: line = line_selected output_content.append(line) end_time = time.time() # Stop measuring time execution_time = end_time - start_time # Calculate execution time return output_content, execution_time def retrieve_fields(data, path=''): """Recursively retrieve all fields from a given JSON structure and prompt for filling.""" fields = {} # If the data is a dictionary if isinstance(data, dict): for key, value in data.items(): # Construct the updated path for nested structures new_path = f"{path}.{key}" if path else key fields.update(retrieve_fields(value, new_path)) # If the data is a list, iterate over its items elif isinstance(data, list): for index, item in enumerate(data): new_path = f"{path}[{index}]" fields.update(retrieve_fields(item, new_path)) # If the data is a simple type (str, int, etc.) else: prompt = f"Please fill in the {path} field." if not data else data fields[path] = prompt return fields def retrieve_fields_from_file(file_path): """Load JSON data from a file, then retrieve all fields and prompt for filling.""" with open(file_path.name, 'r') as f: data = f.read() return retrieve_fields(json.loads(data)) def process_files(html_file, json_file): #html_content = open_html(html_file) #print(html_file) html_inputs = find_form_fields(html_file) #print(json_file) json_content = retrieve_fields(json.loads(json_file)) #Classificar os inputs do json para ver em que tipo de input ["text", "radio", "checkbox", "button", "date"] # Classify lines and measure execution time for model_name in models.values(): tokenizer = AutoTokenizer.from_pretrained(model_name) #html_classified_lines, html_execution_time = classify_lines(html_inputs, ["text", "radio", "checkbox", "button", "date", "select"], model_name) json_classified_lines, json_execution_time = classify_lines_json(html_file, json_content, list(json_content.keys()), model_name) # print(str(html_execution_time) + " - " + str(html_classified_lines)) # print(str(json_execution_time) + " - " + str(json_classified_lines)) #print(type(json_classified_lines)) #return '\n'.join(map(str, html_classified_lines)) return '\n'.join(map(str, json_classified_lines)) HF_TOKEN = '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' hf_writer = gr.HuggingFaceDatasetSaver(HF_TOKEN, "form_matcher_demo_flagged") iface = gr.Interface(fn=process_files, inputs=[gr.Textbox(lines = 20, max_lines = 1000, label="Upload HTML File"), gr.Textbox(lines = 20, max_lines = 1000, label="Upload JSON File")], outputs=gr.Textbox(lines = 20, max_lines = 1000, label="Output"), examples=[ [example1, solution1], [example2, solution2], [example3, solution3], ], allow_flagging="manual", flagging_callback=hf_writer ) iface.launch()