rajsecrets0 commited on
Commit
332b35d
·
verified ·
1 Parent(s): 752af65

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +89 -107
app.py CHANGED
@@ -5,165 +5,147 @@ from PIL import Image, ImageDraw
5
  from io import BytesIO
6
  import fitz # PyMuPDF
7
  import time
8
- import os
9
 
10
- # Document categories
 
 
11
  DOCUMENT_TYPES = ["Land Records", "Caste Certificates", "Property Registrations"]
12
 
13
- # Set up session state
14
  def initialize_session_state():
 
 
15
  if "processed_doc" not in st.session_state:
16
- st.session_state.processed_doc = None
17
- if "current_file" not in st.session_state:
18
- st.session_state.current_file = None
19
- if "gemini_api_key" not in st.session_state:
20
- st.session_state.gemini_api_key = None
21
 
22
  # Reset session state
23
  def reset_session_state():
24
- st.session_state.processed_doc = None
25
- st.session_state.current_file = None
26
 
27
- # Encode file to base64
28
- def encode_file(file):
29
  try:
30
- file_content = file.getvalue()
31
- return base64.b64encode(file_content).decode('utf-8')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  except Exception as e:
33
- st.error(f"Error encoding file: {str(e)}")
34
  return None
35
 
36
  # Query Gemini API
37
- def query_gemini(prompt, image_b64):
38
- if not st.session_state.gemini_api_key:
39
- st.error("API Key is missing. Please enter your Gemini API Key.")
40
- return None
 
41
 
42
  try:
43
- headers = {
44
- "Authorization": f"Bearer {st.session_state.gemini_api_key}",
45
- "Content-Type": "application/json"
46
- }
47
- payload = {
48
- "model": "gemini-1.5-pro", # Change based on the latest API model
49
- "prompt": prompt,
50
- "image": image_b64
51
- }
52
  response = requests.post(
53
- "https://generativelanguage.googleapis.com/v1/models/gemini-1.5-pro:generateContent", # Corrected URL
54
- headers=headers,
55
- json=payload
 
56
  )
57
- response.raise_for_status()
58
- return response.json().get("result", "No response received.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  except Exception as e:
60
- st.error(f"Gemini API error: {str(e)}")
61
  return None
62
 
63
- # Process the document
64
- def process_document(file):
 
 
 
65
  try:
66
  with st.spinner("Analyzing document..."):
67
- image_b64 = encode_file(file)
68
  if not image_b64:
69
  return
70
 
71
- # Store preview image
72
- if file.type == "application/pdf":
73
- pdf = fitz.open(stream=BytesIO(file.getvalue()))
74
- page = pdf[0]
75
- pix = page.get_pixmap()
76
- st.session_state.doc_preview = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
77
- elif file.type.startswith('image/'):
78
- st.session_state.doc_preview = Image.open(BytesIO(file.getvalue()))
79
- else:
80
- st.error("Unsupported file format")
81
- return
82
-
83
- # Classify document
84
  classify_prompt = f"Classify this document into one of these categories: {', '.join(DOCUMENT_TYPES)}. Respond only with the category name."
85
  doc_type = query_gemini(classify_prompt, image_b64)
86
 
87
- # Extract details
88
- extract_prompt = """Extract and organize all important details from this document including:
89
  - Names
90
  - Dates
91
  - Identification numbers
92
  - Locations
93
- - Key terms
94
- Format as a bullet-point list with clear headings."""
95
  details = query_gemini(extract_prompt, image_b64)
96
-
97
- # Verify authenticity
98
- verify_prompt = "Analyze this document for signs of tampering or forgery. Provide verification results."
99
  verification = query_gemini(verify_prompt, image_b64)
100
 
101
  st.session_state.processed_doc = {
102
  "type": doc_type or "Unclassified",
103
  "details": details or "No details extracted",
104
  "verification": verification or "Verification failed",
105
- "preview": st.session_state.doc_preview
106
  }
107
-
108
  st.success("Document processing complete!")
109
  time.sleep(1)
110
-
111
  except Exception as e:
112
  st.error(f"Document processing failed: {str(e)}")
113
  st.session_state.processed_doc = None
114
 
115
- # Main application
116
  def main():
117
  st.set_page_config(page_title="DocVerify AI", layout="wide")
118
  initialize_session_state()
119
 
120
- # Sidebar Controls
121
- with st.sidebar:
122
- st.header("Document Controls")
123
-
124
- # API Key input
125
- st.session_state.gemini_api_key = st.text_input("Enter Gemini API Key", type="password")
126
-
127
- uploaded_file = st.file_uploader(
128
- "Upload Document",
129
- type=["pdf", "jpg", "jpeg", "png"],
130
- key="uploaded_file"
131
- )
132
-
133
- if st.button("Process Document"):
134
- if uploaded_file:
135
- st.session_state.current_file = uploaded_file
136
- process_document(uploaded_file)
137
- else:
138
- st.error("Please select a document to process.")
139
-
140
- if st.button("New Document"):
141
- reset_session_state()
142
- st.rerun()
143
-
144
- if st.session_state.processed_doc:
145
- st.divider()
146
- st.subheader("Document Summary")
147
- st.markdown(f"**Type:** {st.session_state.processed_doc['type']}")
148
- st.markdown(f"**Verification Status:**\n{st.session_state.processed_doc['verification']}")
149
-
150
- # Main Interface
151
- st.title("📄 Automated Document Verifier")
152
 
153
- if st.session_state.processed_doc and 'preview' in st.session_state.processed_doc:
154
- col1, col2 = st.columns([1, 2])
155
- with col1:
156
- st.subheader("Document Preview")
157
- st.image(st.session_state.processed_doc['preview'], use_column_width=True)
158
-
159
- with col2:
160
- st.subheader("Extracted Details")
161
- st.markdown(st.session_state.processed_doc['details'])
162
-
163
- st.subheader("Verification Analysis")
164
- st.markdown(st.session_state.processed_doc['verification'])
165
- else:
166
- st.info("Please upload a document and click 'Process Document' to start verification.")
167
 
168
  if __name__ == "__main__":
169
  main()
 
5
  from io import BytesIO
6
  import fitz # PyMuPDF
7
  import time
 
8
 
9
+ # Configuration - Get API key from Streamlit secrets
10
+ GEMINI_API_KEY = st.secrets["GEMINI_API_KEY"]
11
+ GEMINI_MODEL = "gemini-2-flash"
12
  DOCUMENT_TYPES = ["Land Records", "Caste Certificates", "Property Registrations"]
13
 
14
+ # Initialize session state
15
  def initialize_session_state():
16
+ if "chat_history" not in st.session_state:
17
+ st.session_state["chat_history"] = []
18
  if "processed_doc" not in st.session_state:
19
+ st.session_state["processed_doc"] = None
20
+ if "doc_preview" not in st.session_state:
21
+ st.session_state["doc_preview"] = None
22
+ if "uploaded_file" not in st.session_state:
23
+ st.session_state["uploaded_file"] = None
24
 
25
  # Reset session state
26
  def reset_session_state():
27
+ for key in ["chat_history", "processed_doc", "doc_preview", "uploaded_file"]:
28
+ st.session_state.pop(key, None)
29
 
30
+ # Encode uploaded file to base64
31
+ def encode_file(uploaded_file):
32
  try:
33
+ file_bytes = uploaded_file.getvalue()
34
+
35
+ if uploaded_file.type == "application/pdf":
36
+ pdf = fitz.open(stream=BytesIO(file_bytes))
37
+ page = pdf[0]
38
+ pix = page.get_pixmap()
39
+ img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
40
+ elif uploaded_file.type.startswith('image/'):
41
+ img = Image.open(BytesIO(file_bytes))
42
+ elif uploaded_file.type == "text/plain":
43
+ text = file_bytes.decode('utf-8')
44
+ img = Image.new('RGB', (800, 600), color=(73, 109, 137))
45
+ d = ImageDraw.Draw(img)
46
+ d.text((10, 10), text, fill=(255, 255, 0))
47
+ else:
48
+ st.error("Unsupported file format")
49
+ return None
50
+
51
+ img_byte_arr = BytesIO()
52
+ img.save(img_byte_arr, format='JPEG')
53
+ return base64.b64encode(img_byte_arr.getvalue()).decode('utf-8')
54
  except Exception as e:
55
+ st.error(f"File processing error: {str(e)}")
56
  return None
57
 
58
  # Query Gemini API
59
+ def query_gemini(prompt, image_b64=None):
60
+ url = f"https://generativelanguage.googleapis.com/v1/models/{GEMINI_MODEL}:generateContent?key={GEMINI_API_KEY}"
61
+ parts = [{"text": prompt}]
62
+ if image_b64:
63
+ parts.append({"inline_data": {"mime_type": "image/jpeg", "data": image_b64}})
64
 
65
  try:
 
 
 
 
 
 
 
 
 
66
  response = requests.post(
67
+ url,
68
+ json={"contents": [{"parts": parts}]},
69
+ headers={"Content-Type": "application/json"},
70
+ timeout=30
71
  )
72
+ if response.status_code != 200:
73
+ st.error(f"API Request failed with status code: {response.status_code}")
74
+ return None
75
+
76
+ data = response.json()
77
+ if 'error' in data:
78
+ st.error(f"API Error: {data['error'].get('message', 'Unknown error')}")
79
+ return None
80
+
81
+ if not data.get('candidates'):
82
+ st.error("No response candidates found in API response")
83
+ return None
84
+
85
+ candidate = data['candidates'][0]
86
+ return candidate.get('content', {}).get('parts', [{}])[0].get('text', 'No response text found')
87
+ except requests.exceptions.RequestException as e:
88
+ st.error(f"API Request failed: {str(e)}")
89
+ return None
90
  except Exception as e:
91
+ st.error(f"Unexpected error: {str(e)}")
92
  return None
93
 
94
+ # Process the uploaded document
95
+ def process_document():
96
+ if not st.session_state.uploaded_file:
97
+ st.error("Please upload a document first.")
98
+ return
99
  try:
100
  with st.spinner("Analyzing document..."):
101
+ image_b64 = encode_file(st.session_state.uploaded_file)
102
  if not image_b64:
103
  return
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  classify_prompt = f"Classify this document into one of these categories: {', '.join(DOCUMENT_TYPES)}. Respond only with the category name."
106
  doc_type = query_gemini(classify_prompt, image_b64)
107
 
108
+ extract_prompt = """Extract key details including:
 
109
  - Names
110
  - Dates
111
  - Identification numbers
112
  - Locations
113
+ Format as a bullet-point list."""
 
114
  details = query_gemini(extract_prompt, image_b64)
115
+
116
+ verify_prompt = "Analyze this document for signs of tampering. Provide verification status."
 
117
  verification = query_gemini(verify_prompt, image_b64)
118
 
119
  st.session_state.processed_doc = {
120
  "type": doc_type or "Unclassified",
121
  "details": details or "No details extracted",
122
  "verification": verification or "Verification failed",
 
123
  }
 
124
  st.success("Document processing complete!")
125
  time.sleep(1)
 
126
  except Exception as e:
127
  st.error(f"Document processing failed: {str(e)}")
128
  st.session_state.processed_doc = None
129
 
130
+ # Main app function
131
  def main():
132
  st.set_page_config(page_title="DocVerify AI", layout="wide")
133
  initialize_session_state()
134
 
135
+ st.sidebar.header("Document Controls")
136
+ st.sidebar.file_uploader("Upload Document", type=["pdf", "jpg", "jpeg", "png", "txt"], key="uploaded_file", on_change=process_document)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
+ if st.sidebar.button("New Document"):
139
+ reset_session_state()
140
+ st.rerun()
141
+
142
+ st.title("DocVerify AI - Document Analysis")
143
+
144
+ if st.session_state.processed_doc:
145
+ st.subheader("Document Summary")
146
+ st.markdown(f"**Type:** {st.session_state.processed_doc['type']}")
147
+ st.markdown(f"**Verification Status:** {st.session_state.processed_doc['verification']}")
148
+ st.text_area("Extracted Details", st.session_state.processed_doc['details'], height=200)
 
 
 
149
 
150
  if __name__ == "__main__":
151
  main()