Spaces:
Build error
Build error
File size: 8,620 Bytes
3c0c2d6 d5350ac 3c0c2d6 cc26fab 3c0c2d6 5585dcf 3c0c2d6 d5350ac 84bd3e9 3c0c2d6 d5350ac 5585dcf 3c0c2d6 84bd3e9 3c0c2d6 5585dcf 3c0c2d6 5585dcf d26f874 5585dcf d26f874 cc26fab 5585dcf d26f874 9f0f462 d5350ac 9f0f462 84bd3e9 d5350ac 9f0f462 d26f874 5585dcf d26f874 3c0c2d6 5585dcf d5350ac 5585dcf d5350ac d26f874 d5350ac cc26fab d5350ac d26f874 84bd3e9 9253b94 84bd3e9 9253b94 cc26fab 84bd3e9 3c0c2d6 5585dcf 3c0c2d6 5585dcf 3c0c2d6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | import streamlit as st
import pandas as pd
import numpy as np
from azure.core.credentials import AzureKeyCredential
from azure.ai.formrecognizer import DocumentAnalysisClient
import time
from dotenv import load_dotenv
import os
load_dotenv()
# Azure Form Recognizer credentials
endpoint = os.environ["endpoint"]
key = os.environ["key"]
# Initialize DocumentAnalysisClient
document_analysis_client = DocumentAnalysisClient(
endpoint=endpoint, credential=AzureKeyCredential(key)
)
# Sidebar for document type selection
document_type = st.sidebar.selectbox(
"Select Document Type", ["Invoice", "Receipt", "Identity Document"]
)
# Center area for file upload
uploaded_file = st.file_uploader(f"Choose or drag an {document_type} file", type=["pdf", "png", "jpg", "jpeg"])
# Initialize session state for processing results
if "processed" not in st.session_state:
st.session_state.processed = False
st.session_state.tables = []
st.session_state.kv_df = pd.DataFrame()
# Process the uploaded file if the button is clicked
if uploaded_file is not None:
if st.button("Upload and Process"):
with st.spinner("Processing..."):
time.sleep(1) # Simulate some delay to show the spinner
# Analyze the document
poller = document_analysis_client.begin_analyze_document(
"prebuilt-document", document=uploaded_file
)
result = poller.result()
# Extract key-value pairs and store them in a dictionary
kv_dict = {}
for kv_pair in result.key_value_pairs:
if kv_pair.key and kv_pair.value: # Ensure both key and value exist
clean_key = kv_pair.key.content.rstrip(':')
kv_dict[clean_key] = kv_pair.value.content
kv_df = pd.DataFrame(list(kv_dict.items()), columns=["Key", "Value"]).T
# Set the first row as the header
header = kv_df.iloc[0]
# Create a new DataFrame with the header and the remaining rows
kv_df = kv_df[1:].reset_index(drop=True)
# Insert the new header row
header_df = pd.DataFrame([header], columns=range(len(header)))
# Concatenate the header row DataFrame with the original DataFrame
kv_df = pd.concat([header_df, kv_df], ignore_index=True)
st.session_state.kv_df = kv_df
st.session_state.tables = []
if result.tables:
for table in result.tables:
data = []
for cell in table.cells:
data.append([cell.row_index, cell.column_index, cell.content])
table_df = pd.DataFrame(data, columns=["row_index", "column_index", "content"])
table_df = table_df.pivot(index="row_index", columns="column_index", values="content")
# Reset the column index
table_df.reset_index(drop=True, inplace=True)
# Set the first row as header
table_df.columns = table_df.iloc[0] # Take the first row as column names
table_df = table_df.drop(table_df.index[0]) # Remove the first row after setting it as headers
# Optionally reset the index if required
table_df.reset_index(drop=True, inplace=True)
st.session_state.tables.append(table_df)
st.session_state.processed = True
# Predefine default columns in the selected table
default_columns = ['Invoice No', 'Invoice Date', 'Customer Name']
# Sidebar for table and key-value pair selection
if st.session_state.processed:
if not st.session_state.kv_df.empty:
st.sidebar.write("Key-Value Pairs found.")
else:
st.sidebar.write("No Key-Value Pairs found in document.")
if st.session_state.tables:
# Display available tables for selection in the sidebar
table_options = ["Select"] + [f"Table {i + 1}" for i in range(len(st.session_state.tables))]
selected_table_option = st.sidebar.selectbox(
"Select table to join key-value pairs:", table_options, index=0
)
# Proceed only if a table is selected
if selected_table_option != "Select":
selected_table_index = table_options.index(selected_table_option) - 1 # Adjust for "None"
selected_table_df = st.session_state.tables[selected_table_index]
# Add default columns to the left side of the table with NaN values initially
for col in default_columns:
if col not in selected_table_df.columns:
selected_table_df[col] = np.nan
# Move default columns to the left
# We include only those columns that exist in the table
existing_columns = [col for col in default_columns if col in selected_table_df.columns]
remaining_columns = [col for col in selected_table_df.columns if col not in existing_columns]
selected_table_df = selected_table_df[[*existing_columns, *remaining_columns]]
if not st.session_state.kv_df.empty:
# Allow the user to select multiple columns using checkboxes
first_row_values = st.session_state.kv_df.iloc[0].values
second_row_values = st.session_state.kv_df.iloc[1].values
key_value_options = [
f"{key}: {value}" for key, value in zip(first_row_values, second_row_values)
]
selected_columns = []
st.sidebar.write("Select key-value pairs to the default columns:")
# Create draggable interface for each key-value pair
for i, option in enumerate(key_value_options):
selected_column_option = st.sidebar.selectbox(
f"Insert {option} to the column:",
["Select"] + default_columns,
key=f"col_select_{i}"
)
if selected_column_option != "Select":
selected_columns.append((i, selected_column_option))
# Insert selected key-value pairs into the appropriate columns
for idx, selected_column in selected_columns:
st.session_state.kv_df[selected_column] = second_row_values[idx]
# Fill the column in the table with the selected key-value pair
selected_table_df[selected_column] = st.session_state.kv_df.iloc[1, idx]
st.write(f"Selected Table {selected_table_index + 1} with Key-Value Pairs Added:")
# st.dataframe(selected_table_df)
# Allow row and column selection for deletion
st.sidebar.subheader("Manage Table")
# Delete columns
if st.sidebar.checkbox("Delete Columns"):
col = list(selected_table_df.columns)
col = col[3:]
cols_to_delete = st.sidebar.multiselect(
"Select Columns to Delete", col
)
if st.sidebar.button("Remove Columns"):
st.session_state.tables[selected_table_index].drop(columns=cols_to_delete, inplace=True)
# Delete rows
if st.sidebar.checkbox("Delete Rows"):
row_indices = st.sidebar.multiselect(
"Select Rows to Delete", selected_table_df.index.tolist()
)
if st.sidebar.button("Remove Rows"):
st.session_state.tables[selected_table_index].drop(index=row_indices, inplace=True)
# Show the updated table
# st.write(f"Updated Table {selected_table_index + 1}:")
st.dataframe(selected_table_df)
# Download updated table
st.download_button(
label=f"Download Updated Table {selected_table_index + 1} as CSV",
data=selected_table_df.to_csv(index=False).encode('utf-8'),
file_name=f"updated_table_{selected_table_index + 1}.csv",
mime='text/csv',
)
else:
st.sidebar.write("No tables found in the document.")
# Option to remove the file and clear the session
if st.session_state.processed and st.sidebar.button("Remove File"):
st.session_state.processed = False
st.session_state.tables = []
st.session_state.kv_df = pd.DataFrame()
st.rerun()
|