CoolFace
Apppublic

edithram23/Redaction_PDF

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
app.py238 linesDownload Raw Back to root
1from transformers import pipeline2from transformers import AutoTokenizer3from transformers import AutoModelForSeq2SeqLM4import streamlit as st5import fitz  # PyMuPDF6from docx import Document7import re8import nltk9from presidio_analyzer import AnalyzerEngine, PatternRecognizer, RecognizerResult, Pattern10nltk.download('punkt')11 12 13def sentence_tokenize(text):14    sentences = nltk.sent_tokenize(text)15    return sentences16 17model_dir_large = 'edithram23/Redaction_Personal_info_v1'18tokenizer_large = AutoTokenizer.from_pretrained(model_dir_large)19model_large = AutoModelForSeq2SeqLM.from_pretrained(model_dir_large)20pipe1 = pipeline("token-classification", model="edithram23/new-bert-v2")21 22# model_dir_small = 'edithram23/Redaction'23# tokenizer_small = AutoTokenizer.from_pretrained(model_dir_small)24# model_small = AutoModelForSeq2SeqLM.from_pretrained(model_dir_small)25 26# def small(text, model=model_small, tokenizer=tokenizer_small):27#     inputs = ["Mask Generation: " + text.lower() + '.']28#     inputs = tokenizer(inputs, max_length=256, truncation=True, return_tensors="pt")29#     output = model.generate(**inputs, num_beams=8, do_sample=True, max_length=len(text))30#     decoded_output = tokenizer.batch_decode(output, skip_special_tokens=True)[0]31#     predicted_title = decoded_output.strip()32#     pattern = r'\[.*?\]'33#     redacted_text = re.sub(pattern, '[redacted]', predicted_title)34#     return redacted_text35 36# Initialize the analyzer engine37analyzer = AnalyzerEngine()38 39# Define a custom address recognizer using a regex pattern40address_pattern = Pattern(name="address", regex=r"\d+\s\w+\s(?:street|st|road|rd|avenue|ave|lane|ln|drive|dr|blvd|boulevard)\s*\w*", score=0.5)41address_recognizer = PatternRecognizer(supported_entity="ADDRESS", patterns=[address_pattern])42 43# Add the custom address recognizer to the analyzer44analyzer.registry.add_recognizer(address_recognizer)45# analyzer.get_recognizers46# Define a function to extract entities47 48 49def combine_words(entities):50    combined_entities = []51    current_entity = None52 53    for entity in entities:54        if current_entity:55            if current_entity['end'] == entity['start']:56                # Combine the words without space57                current_entity['word'] += entity['word'].replace('##', '')58                current_entity['end'] = entity['end']59            elif current_entity['end'] + 1 == entity['start']:60                # Combine the words with a space61                current_entity['word'] += ' ' + entity['word'].replace('##', '')62                current_entity['end'] = entity['end']63            else:64                # Add the previous combined entity to the list65                combined_entities.append(current_entity)66                # Start a new entity67                current_entity = entity.copy()68                current_entity['word'] = current_entity['word'].replace('##', '')69        else:70            # Initialize the first entity71            current_entity = entity.copy()72            current_entity['word'] = current_entity['word'].replace('##', '')73 74    # Add the last entity75    if current_entity:76        combined_entities.append(current_entity)77 78    return combined_entities79 80def words_red_bert(text):81  final=[]82  sentences = sentence_tokenize(text)83  for sentence in sentences:84    x=[pipe1(sentence)]85    m = combine_words(x[0])86    for j in m:87      if(j['entity']!='none' and len(j['word'])>1 and j['word']!=', '):88        final.append(j['word'])89  return final90 91def extract_entities(text):92    entities = {93        "NAME": [],94        "PHONE_NUMBER": [],95        "EMAIL": [],96        "ADDRESS": [],97        "LOCATION": [],98        "IN_AADHAAR": [],99    }100    output = []101 102    # Analyze the text for PII103    results = analyzer.analyze(text=text, language='en')104 105    for result in results:106        if result.entity_type == "PERSON":107            entities["NAME"].append(text[result.start:result.end])108            output+=[text[result.start:result.end]]109        elif result.entity_type == "PHONE_NUMBER":110            entities["PHONE_NUMBER"].append(text[result.start:result.end])111            output+=[text[result.start:result.end]]112        elif result.entity_type == "EMAIL_ADDRESS":113            entities["EMAIL"].append(text[result.start:result.end])114            output+=[text[result.start:result.end]]115        elif result.entity_type == "ADDRESS":116            entities["ADDRESS"].append(text[result.start:result.end])117            output+=[text[result.start:result.end]]118        elif result.entity_type == 'LOCATION':119          entities['LOCATION'].append(text[result.start:result.end])120          output+=[text[result.start:result.end]]121        elif result.entity_type == 'IN_AADHAAR':122          entities['IN_PAN'].append(text[result.start:result.end])123          output+=[text[result.start:result.end]]124 125    return entities,output126    127def mask_generation(text, model=model_large, tokenizer=tokenizer_large):128    if len(text) < 90:129        text = text + '.'130        # return small(text)131    inputs = ["Mask Generation: " + text.lower() + '.']132    inputs = tokenizer(inputs, max_length=512, truncation=True, return_tensors="pt")133    output = model.generate(**inputs, num_beams=8, do_sample=True, max_length=len(text))134    decoded_output = tokenizer.batch_decode(output, skip_special_tokens=True)[0]135    predicted_title = decoded_output.strip()136    pattern = r'\[.*?\]'137    redacted_text = re.sub(pattern, '[redacted]', predicted_title)138    return redacted_text139 140def redact_text(page, text):141    text_instances = page.search_for(text)142    for inst in text_instances:143        page.add_redact_annot(inst, fill=(0, 0, 0))144    page.apply_redactions()145 146def read_pdf(file):147    pdf_document = fitz.open(stream=file.read(), filetype="pdf")148    text = ""149    for page_num in range(len(pdf_document)):150        page = pdf_document.load_page(page_num)151        text += page.get_text()152    return text, pdf_document153 154def read_docx(file):155    doc = Document(file)156    text = "\n".join([para.text for para in doc.paragraphs])157    return text158 159def read_txt(file):160    text = file.read().decode("utf-8")161    return text162 163def process_file(file):164    if file.type == "application/pdf":165        return read_pdf(file)166    elif file.type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document":167        return read_docx(file), None168    elif file.type == "text/plain":169        return read_txt(file), None170    else:171        return "Unsupported file type.", None172 173st.title("Redaction")174uploaded_file = st.file_uploader("Upload a file", type=["pdf", "docx", "txt"])175 176if uploaded_file is not None:177    file_contents, pdf_document = process_file(uploaded_file)178    if pdf_document:179        redacted_text = ''180        for pg in pdf_document:181            text = pg.get_text()182            sentences = sentence_tokenize(text)183            for sent in sentences:184              # x = mask_generation(sent)185            186              # sent_n_q_c=[]  187              # sent_n = list(set(sent.lower().replace('.',' ').split("\n")))188              # for i in sent_n:189              #     for j in i.split(" "):190              #         sent_n_q_c+=j.split(',')191              # x_q = x.lower().replace('.',' ').split(' ')    192              # e=[]193              # for i in x_q:194              #    e+=i.split(',')                     195              # t5_words=set(sent_n_q_c).difference(set(e))      196              entities,words_out = extract_entities(sent)197              # print("\nwords_out:",words_out)198              # print("\nT5",t5_words)199              # print("X:",x,"\nsent:",sent,"\nx_q:",x_q,"\nsent_n:",sent_n,"\ne:",e,"\nsent_n_q_c:",sent_n_q_c,'\nt5_words',t5_words)200              bert_words = words_red_bert(sent)201              # print("\nbert:",bert_words)202              new=[]203              for w in words_out:204                new+=w.split('\n')205              # words_out+=t5_words206              new+=bert_words207              words_out = [i for i in new if len(i)>3]208              # print("\nfinal:",words_out)209              words_out=sorted(words_out, key=len,reverse=True)210 211              for i in words_out:212                redact_text(pg,i)213        # st.text_area(redacted_text)214 215        output_pdf = "output_redacted.pdf"216        pdf_document.save(output_pdf)217 218        with open(output_pdf, "rb") as file:219            st.download_button(220                label="Download Processed PDF",221                data=file,222                file_name="processed_file.pdf",223                mime="application/pdf",224            )225    else:226        token = sentence_tokenize(file_contents)227        final = ''228        for i in range(0, len(token)):229            final += mask_generation(token[i]) + '\n'230        processed_text = final231        st.text_area("OUTPUT", processed_text, height=400)232        st.download_button(233            label="Download Processed File",234            data=processed_text,235            file_name="processed_file.txt",236            mime="text/plain",237        )238