CoolFace
Apppublic

MikeMai/Certificate_Manager_API

sourceHugging Facemitupdated 1y agoView on Hugging Face
0likes
app.py227 linesDownload Raw Back to root
1from pdfminer.high_level import extract_text2from pdf2image import convert_from_path  # Convert PDF pages to images3import base644import io5import os6from PIL import Image7 8import json9 10from openai import OpenAI11 12from dotenv import load_dotenv13 14import gradio as gr15 16load_dotenv()17client = OpenAI()18 19# Function to encode image to Base6420def encode_image(image_input):21    """22    Encode an image to Base64.23    24    Supports both file paths (str) and in-memory PIL images.25    """26    if isinstance(image_input, str):  # If input is a file path27        with open(image_input, "rb") as image_file:28            return base64.b64encode(image_file.read()).decode("utf-8")29    elif isinstance(image_input, Image.Image):  # If input is a PIL image30        buffered = io.BytesIO()31        image_input.save(buffered, format="JPEG")32        return base64.b64encode(buffered.getvalue()).decode("utf-8")33    else:34        raise ValueError("Unsupported input type. Provide a file path or a PIL image.")35 36# Function to process image files37def process_image(image_path):38    print(f"๐Ÿ–ผ๏ธ Processing image file: {image_path}")39    image_base64 = encode_image(image_path)40    image_url = f"data:image/jpeg;base64,{image_base64}"41 42    response = client.chat.completions.create(43        model="gpt-4o",44        messages=[45            {46                "role": "user",47                "content": [48                    {"type": "text", "text": "Extract all text from this image."},49                    {"type": "image_url", "image_url": {"url": image_url}},50                ],51            }52        ],53    )54    55    extracted_text = response.choices[0].message.content.strip()56    # print(f"๐Ÿ“ Extracted text: {extracted_text}")57 58    return extracted_text59 60# Function to process text-based PDFs61def process_text_pdf(pdf_path):62    text_content = extract_text(pdf_path).strip()63    if text_content:64        print(f"๐Ÿ“„ Extracting text from PDF: {pdf_path}")65        return text_content66    return None  # No text found, fallback to image processing67 68# Function to process scanned PDFs (image-based)69def process_image_pdf(pdf_path):70    print(f"๐Ÿ–ผ๏ธ No text found! Processing as an image-based (scanned) PDF: {pdf_path}")71    images = convert_from_path(pdf_path)72 73    extracted_text = []74    for i, image in enumerate(images):75        image_text = process_image(image)76        extracted_text.append(image_text)77 78    return "\n\n".join(extracted_text)79 80# Function to detect file type and extract text accordingly81def process_file(file_path):82    if not os.path.exists(file_path):83        print(f"โŒ Error: File not found: {file_path}")84        return None85 86    file_extension = file_path.lower().split(".")[-1]87 88    if file_extension in ["jpg", "jpeg", "png"]:89        return process_image(file_path)  # Process images90    elif file_extension == "pdf":91        text_data = process_text_pdf(file_path)92        if text_data:  # If text extraction succeeds, return it93            return text_data94        return process_image_pdf(file_path)  # Otherwise, process as image95    else:96        print(f"โŒ Unsupported file type: {file_path}")97        return None98 99def extract_certificate_details(certificate_path):100    101    certificate_text = process_file(certificate_path)102    103    print(f"๐Ÿ–ผ๏ธ Extracting details from certificate: {certificate_path}")104    105    if not certificate_text:106        print(f"โŒ Error: Certificate text could not be extracted from {certificate_path}")107        return None   108    109    # Ask GPT-4o to extract the details110    response = client.chat.completions.create(111        model="gpt-4o",112        response_format={ "type": "json_object" },113        seed=123,114        temperature=0,115        messages=[116            {117                "role": "developer",118                "content": f"""Extract the following details from the certificate text in JSON format, leave blank if not found:119                120{{121    "Certificate Name": "",122    "Certificate ID": "",123    "Ship Name": "",124    "Date of Issue": "",125    "Expiration Date": ""126}}127 128Certificate Text:129{certificate_text}130"""131            }132        ],133    )134 135    result = response.choices[0].message.content136    result_json = json.loads(result)  # Parse the result as JSON137 138    certificate_name = result_json.get("Certificate Name", "")139    certificate_id = result_json.get("Certificate ID", "")140    ship_name = result_json.get("Ship Name", "")141    date_of_issue = result_json.get("Date of Issue", "")142    expiration_date = result_json.get("Expiration Date", "")143    144    print(f"โœ… Extracted details:\n- Certificate Name: {certificate_name}\n- Certificate ID: {certificate_id}\n- Ship Name: {ship_name}\n- Date of Issue: {date_of_issue}\n- Expiration Date: {expiration_date}")145    146    return {147        "Certificate Name": certificate_name,148        "Certificate ID": certificate_id,149        "Ship Name": ship_name,150        "Date of Issue": date_of_issue,151        "Expiration Date": expiration_date,152        "Certificate Text": certificate_text153    }154 155# Function to compare two certificates using AI156def compare_certificates(new_cert_details, old_cert_details):157 158    # Ask GPT-4o to compare the texts159    response = client.chat.completions.create(160        model="gpt-4o",161        messages=[162            {163                "role": "user",164                "content": f"""Compare the two certificates below and provide a structured summary highlighting key differences in the format below:165 166### Comparison Summary:167- Identify differences in terms of:168    - Certificate ID169    - Date of Issue170    - Expiration Date171    172- Highlight any changes in other key details, if applicable.173 174### Take Note:175- Clearly structure the output for easy reading176- Do not include any structural changes in the text, only content changes177 178### Old Certificate:179{old_cert_details}180 181### New Certificate:182{new_cert_details}"""183            }184        ],185    )186 187    comparison_result = response.choices[0].message.content.strip()188 189    return comparison_result190 191def gradio_process_certificate(certificate,  old_cert_details=""):192    # Process the certificate193    cert_details = extract_certificate_details(certificate)194    195    if not cert_details:196        return "โŒ Failed to extract certificate details."197    198    # If old_certificate is provided, compare the certificates199    if old_cert_details:200        201        print(f"๐Ÿ” Comparing certificates")202        # Compare the certificates203        comparison_result = compare_certificates(cert_details, old_cert_details)204        205        # Return both certificate details and comparison result206        return {207            "new_certificate": cert_details,208            "old_certificate": old_cert_details,209            "comparison": comparison_result210        }211    212    # If only one certificate is provided, return just its details213    return cert_details214 215# Launch Gradio UI216gr.Interface(217    fn=gradio_process_certificate,218    inputs=[219        gr.File(label="Certificate (PDF or Image)"),220        gr.Textbox(label="Old Certificate Details (JSON) - Optional")221    ],222    outputs=gr.JSON(label="Certificate Details"),223    title="๐Ÿ“œ Certificate Details Extractor",224    description="Upload a certificate to extract details, or upload two certificates to compare them.",225    show_progress='full',226    allow_flagging="never"227).launch()