gaamaa's picture
Update app.py
11f7ada verified
Raw
History Blame Contribute Delete
6.49 kB
import gradio as gr
import pandas as pd
from openai import OpenAI
import os
import pdfplumber
import pytesseract
from PIL import Image
# Set your OpenAI API key using environment variables for security
OPENAI_API_KEY = os.getenv('OPEN_API_KEY')
client = OpenAI(
api_key=OPENAI_API_KEY
# os.getenv('OPENAI_API_KEY'),
)
# Function to extract text from PDFs
def extract_text_from_pdf(file_path):
text = ""
try:
with pdfplumber.open(file_path) as pdf:
for page in pdf.pages:
text += page.extract_text() + "\n"
except Exception as e:
print(f"Error extracting text from PDF: {str(e)}")
return text
# Function to extract text from images using OCR
def extract_text_from_image(image):
try:
text = pytesseract.image_to_string(image)
return text
except Exception as e:
print(f"Error extracting text from image: {str(e)}")
return ""
# Function to infer table and column names from extracted text
def infer_table_columns_from_text(text):
messages = [
{"role": "system", "content": "You are a helpful assistant that can interpret text to identify table and column names."},
{"role": "user", "content": f"The following text is extracted from a document: '{text}'. Identify any table names and corresponding column names in the text."}
]
response = client.chat.completions.create(
model="gpt-4",
messages=messages,
max_tokens=300,
temperature=0.5
)
return response.choices[0].message.content.strip()
# Function to classify columns using GPT and pre-defined classifications
def classify_columns_from_text(text, classification_file='classifications.xlsx'):
# Load classification rules
classification_df = pd.read_excel(classification_file)
# print("Classification DataFrame Columns:\n", classification_df.columns)
# Infer table and column names using GPT-4
inferred_structure = infer_table_columns_from_text(text)
# print("GPT Inferred Structure:\n", inferred_structure)
classified_columns = []
inferred_lines = inferred_structure.split("\n")
table_name = None
for line in inferred_lines:
line = line.strip()
if "typically be found in a" in line and "table" in line:
table_name = line.split("typically be found in a ")[-1].split(" table")[0].strip()
print(f"Inferred Table Name: {table_name}")
elif line and line[0].isdigit():
column_name = line.split(".")[1].strip()
print(f"Checking for Column: '{column_name}' in Table: '{table_name}'")
# Find the closest match using GPT-4 to compare the inferred column name with the classification file's columns
best_match = None
best_similarity = 0
for col in classification_df['Column names'].unique():
prompt_messages = [
{"role": "system", "content": "You are a helpful assistant that can compare and identify similarity between two strings."},
{"role": "user", "content": f"On a scale of 0 to 1, how similar are these two column names? Column 1: '{column_name}', Column 2: '{col}'. Respond with only the similarity score."}
]
response = client.chat.completions.create(
model="gpt-4",
messages=prompt_messages,
max_tokens=10,
temperature=0
)
raw_response = response.choices[0].message.content.strip()
# print("Raw GPT-4 Response:", raw_response)
try:
similarity_score = float(response.choices[0].message.content.strip())
except ValueError:
print("Error: Unable to convert GPT-4 response to a float. Response was:", response.choices[0].message['content'].strip())
similarity_score = 0.0 # Default to 0 if conversion fails
if similarity_score > best_similarity:
best_similarity = similarity_score
best_match = col
# print(f"Best match for '{column_name}' is '{best_match}' with similarity {best_similarity}")
if best_match:
classification_match = classification_df[classification_df['Column names'].str.strip().str.lower() == best_match.strip().lower()]['Classification']
if not classification_match.empty:
classification = classification_match.values[0]
print(f"Match Found: '{column_name}' classified as '{classification}'")
else:
classification = "General Use"
print(f"No Match Found for Column: '{column_name}' - Defaulting to 'General Use'")
else:
classification = "General Use"
classified_columns.append({
'Table Name': table_name,
'Column Name': column_name,
'Classification': classification
})
result_df = pd.DataFrame(classified_columns)
print("Resulting Classified Columns DataFrame:\n", result_df)
return result_df
def process_file(file):
text = ""
file_extension = file.name.split(".")[-1].lower()
if file_extension in ["pdf"]:
# Extract text from PDF
text = extract_text_from_pdf(file)
elif file_extension in ["jpg", "jpeg", "png", "tiff"]:
# Extract text from image
image = Image.open(file)
text = extract_text_from_image(image)
else:
# Assume it's an Excel file
input_df = pd.read_excel(file)
text = "\n".join(input_df.apply(lambda row: " ".join(row.values.astype(str)), axis=1))
# Classify columns based on the extracted text
result_df = classify_columns_from_text(text)
return result_df
# Create a Gradio interface
iface = gr.Interface(
fn=process_file,
inputs=gr.File(label="Upload Excel, PDF, or Image File"),
outputs=gr.Dataframe(label="Classified Data"),
title="Data Classification using GPT and Pre-defined Rules",
description="Upload an Excel, PDF, or Image file to classify its columns based on predefined rules and GPT-4."
)
# Launch the Gradio app with a public link
iface.launch(share=True)