Spaces:
Sleeping
Sleeping
Upload 6 files
Browse files- Invoice/invoice_1001329.pdf +0 -0
- Invoice/invoice_2001321.pdf +0 -0
- Invoice/invoice_34523334.pdf +0 -0
- app.py +39 -0
- requirements.txt +9 -0
- utils.py +115 -0
Invoice/invoice_1001329.pdf
ADDED
|
Binary file (76.2 kB). View file
|
|
|
Invoice/invoice_2001321.pdf
ADDED
|
Binary file (75.1 kB). View file
|
|
|
Invoice/invoice_34523334.pdf
ADDED
|
Binary file (75.6 kB). View file
|
|
|
app.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Description: This file contains code for streamlit application which is used to extract invoice data from pdf files.
|
| 2 |
+
import streamlit as st
|
| 3 |
+
from dotenv import load_dotenv
|
| 4 |
+
from utils import *
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
def main():
|
| 8 |
+
load_dotenv()
|
| 9 |
+
|
| 10 |
+
st.set_page_config(page_title="Invoice Parser Agent")
|
| 11 |
+
st.title("Invoice Extraction Bot 🤖")
|
| 12 |
+
st.subheader("I can help you in extracting invoice data")
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
# Upload the Invoices (pdf files)
|
| 16 |
+
pdf = st.file_uploader("Upload invoices here, only PDF files allowed", type=["pdf"],accept_multiple_files=True)
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
submit=st.button("Extract Data")
|
| 20 |
+
|
| 21 |
+
if submit:
|
| 22 |
+
with st.spinner('Wait for extraction to complete...🔄'):
|
| 23 |
+
df=create_docs(pdf)
|
| 24 |
+
st.write(df.head())
|
| 25 |
+
|
| 26 |
+
data_as_csv= df.to_csv(index=False).encode("utf-8")
|
| 27 |
+
st.download_button(
|
| 28 |
+
"Download data as CSV",
|
| 29 |
+
data_as_csv,
|
| 30 |
+
"ConsolidatedInvoices.csv",
|
| 31 |
+
"text/csv",
|
| 32 |
+
key="ConsolidatedInvoices-csv",
|
| 33 |
+
)
|
| 34 |
+
st.success("Extraction complete")
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
#Invoking main function
|
| 38 |
+
if __name__ == '__main__':
|
| 39 |
+
main()
|
requirements.txt
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
langchain
|
| 2 |
+
streamlit
|
| 3 |
+
openai
|
| 4 |
+
tiktoken
|
| 5 |
+
python-dotenv
|
| 6 |
+
faiss-cpu
|
| 7 |
+
pypdf
|
| 8 |
+
|
| 9 |
+
|
utils.py
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from os import write
|
| 2 |
+
from langchain.llms import OpenAI
|
| 3 |
+
from pypdf import PdfReader
|
| 4 |
+
from langchain.llms.openai import OpenAI
|
| 5 |
+
import pandas as pd
|
| 6 |
+
import re
|
| 7 |
+
import streamlit as st
|
| 8 |
+
from langchain.prompts import PromptTemplate
|
| 9 |
+
|
| 10 |
+
#Extract Information from PDF file
|
| 11 |
+
def get_pdf_text(pdf_doc):
|
| 12 |
+
text = ""
|
| 13 |
+
pdf_reader = PdfReader(pdf_doc)
|
| 14 |
+
for page in pdf_reader.pages:
|
| 15 |
+
text += page.extract_text()
|
| 16 |
+
return text
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
#Function to extract data from text
|
| 21 |
+
def extracted_data(pages_data):
|
| 22 |
+
|
| 23 |
+
template = """
|
| 24 |
+
Remove any $ symbols.
|
| 25 |
+
Extract the following values in a JSON format : Invoice,Date, Description, Quantity,
|
| 26 |
+
Unit Price , Amount, Total, Email and Phone Number from this data: {pages}.
|
| 27 |
+
|
| 28 |
+
"""
|
| 29 |
+
prompt_template = PromptTemplate(input_variables=["pages"], template=template)
|
| 30 |
+
llm = OpenAI(temperature=.7)
|
| 31 |
+
full_response=llm(prompt_template.format(pages=pages_data))
|
| 32 |
+
|
| 33 |
+
#print("Full Response")
|
| 34 |
+
#print(full_response)
|
| 35 |
+
|
| 36 |
+
return full_response
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
# iterate over files in
|
| 40 |
+
# that user uploaded PDF files, one by one
|
| 41 |
+
def create_docs(user_pdf_list):
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
df = pd.DataFrame({'Invoice': pd.Series(dtype='str'),
|
| 45 |
+
'Description': pd.Series(dtype='str'),
|
| 46 |
+
'Date': pd.Series(dtype='str'),
|
| 47 |
+
'Quantity': pd.Series(dtype='str'),
|
| 48 |
+
'Unit Price': pd.Series(dtype='str'),
|
| 49 |
+
'Amount': pd.Series(dtype='int'),
|
| 50 |
+
'Total': pd.Series(dtype='str'),
|
| 51 |
+
'Email': pd.Series(dtype='str'),
|
| 52 |
+
'Phone Number': pd.Series(dtype='str')
|
| 53 |
+
|
| 54 |
+
})
|
| 55 |
+
|
| 56 |
+
for filename in user_pdf_list:
|
| 57 |
+
|
| 58 |
+
print("filename")
|
| 59 |
+
print(filename)
|
| 60 |
+
raw_data=get_pdf_text(filename)
|
| 61 |
+
#st.write("RAWDATA:..."+raw_data)
|
| 62 |
+
#print("extracted raw data")
|
| 63 |
+
#print(raw_data)
|
| 64 |
+
|
| 65 |
+
llm_extracted_data=extracted_data(raw_data)
|
| 66 |
+
#st.write("LLMDATA..."+llm_extracted_data)
|
| 67 |
+
# Write code to append the extracted data to the dataframe
|
| 68 |
+
# df = df.append(llm_extracted_data, ignore_index=True)
|
| 69 |
+
#print("DF start")
|
| 70 |
+
# print(df)
|
| 71 |
+
|
| 72 |
+
print("llm extracted data")
|
| 73 |
+
#Adding items to our list - Adding data & its metadata
|
| 74 |
+
print(llm_extracted_data)
|
| 75 |
+
pattern = r'{(.+)}'
|
| 76 |
+
match = re.search(pattern, llm_extracted_data, re.DOTALL)
|
| 77 |
+
|
| 78 |
+
if match:
|
| 79 |
+
extracted_text = match.group(1)
|
| 80 |
+
# Escape quotes in the extracted text
|
| 81 |
+
#extracted_text = extracted_text.replace('"', '\\"').replace("'", "\\'")
|
| 82 |
+
# Converting the extracted text to a dictionary
|
| 83 |
+
# Remove line continuation characters
|
| 84 |
+
#extracted_text = extracted_text.replace('\\', '')
|
| 85 |
+
#print("********************Extracted Text***************")
|
| 86 |
+
#print(extracted_text)
|
| 87 |
+
|
| 88 |
+
#print("********************Data Dict***************")
|
| 89 |
+
data_dict = eval('{' + extracted_text + '}')
|
| 90 |
+
#print(data_dict)
|
| 91 |
+
#Convert data_dict to a dataframe
|
| 92 |
+
# df = pd.DataFrame.from_dict(data_dict, orient='index').T
|
| 93 |
+
#print("********************Data Dict End***************")
|
| 94 |
+
|
| 95 |
+
else:
|
| 96 |
+
print("No match found.")
|
| 97 |
+
data_dict = {}
|
| 98 |
+
|
| 99 |
+
#print("********************DF Final start***************")
|
| 100 |
+
df = pd.concat([df, pd.DataFrame([data_dict])], ignore_index=True)
|
| 101 |
+
#print(df)
|
| 102 |
+
#print("********************DF Final End***************")
|
| 103 |
+
#df = pd.concat([df, pd.DataFrame.from_dict(data_dict)])
|
| 104 |
+
#df= pd.concat([df, pd.DataFrame(data_dict, index=[0])], ignore_index=True)
|
| 105 |
+
#df = pd.concat([df, pd.DataFrame.from_dict(data_dict, orient='columns', index=[0])])
|
| 106 |
+
#df = pd.concat([df, pd.DataFrame({k: [v] for k, v in data_dict.items()})])
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
# Create a DataFrame from the dictionary
|
| 110 |
+
# If the dictionary values are not lists, convert them to lists
|
| 111 |
+
|
| 112 |
+
#df=df.append(save_to_dataframe(llm_extracted_data), ignore_index=True)
|
| 113 |
+
|
| 114 |
+
df.head()
|
| 115 |
+
return df
|