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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -39
app.py CHANGED
@@ -11,7 +11,7 @@ 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"] = []
@@ -19,12 +19,10 @@ def initialize_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
@@ -37,11 +35,11 @@ def encode_file(uploaded_file):
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:
@@ -49,8 +47,9 @@ def encode_file(uploaded_file):
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
@@ -58,9 +57,15 @@ def encode_file(uploaded_file):
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(
@@ -74,16 +79,17 @@ def query_gemini(prompt, image_b64=None):
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
@@ -93,26 +99,46 @@ def query_gemini(prompt, image_b64=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
 
@@ -121,8 +147,10 @@ def process_document():
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
@@ -132,20 +160,45 @@ 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()
 
11
  GEMINI_MODEL = "gemini-2-flash"
12
  DOCUMENT_TYPES = ["Land Records", "Caste Certificates", "Property Registrations"]
13
 
14
+ # Initialize session state (excluding widget-controlled keys)
15
  def initialize_session_state():
16
  if "chat_history" not in st.session_state:
17
  st.session_state["chat_history"] = []
 
19
  st.session_state["processed_doc"] = None
20
  if "doc_preview" not in st.session_state:
21
  st.session_state["doc_preview"] = None
 
 
22
 
23
+ # Reset session state (excluding widget-controlled keys)
24
  def reset_session_state():
25
+ for key in ["chat_history", "processed_doc", "doc_preview"]:
26
  st.session_state.pop(key, None)
27
 
28
  # Encode uploaded file to base64
 
35
  page = pdf[0]
36
  pix = page.get_pixmap()
37
  img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
38
+ elif uploaded_file.type.startswith("image/"):
39
  img = Image.open(BytesIO(file_bytes))
40
  elif uploaded_file.type == "text/plain":
41
+ text = file_bytes.decode("utf-8")
42
+ img = Image.new("RGB", (800, 600), color=(73, 109, 137))
43
  d = ImageDraw.Draw(img)
44
  d.text((10, 10), text, fill=(255, 255, 0))
45
  else:
 
47
  return None
48
 
49
  img_byte_arr = BytesIO()
50
+ img.save(img_byte_arr, format="JPEG")
51
+ return base64.b64encode(img_byte_arr.getvalue()).decode("utf-8")
52
+
53
  except Exception as e:
54
  st.error(f"File processing error: {str(e)}")
55
  return None
 
57
  # Query Gemini API
58
  def query_gemini(prompt, image_b64=None):
59
  url = f"https://generativelanguage.googleapis.com/v1/models/{GEMINI_MODEL}:generateContent?key={GEMINI_API_KEY}"
60
+
61
  parts = [{"text": prompt}]
62
  if image_b64:
63
+ parts.append({
64
+ "inline_data": {
65
+ "mime_type": "image/jpeg",
66
+ "data": image_b64
67
+ }
68
+ })
69
 
70
  try:
71
  response = requests.post(
 
79
  return None
80
 
81
  data = response.json()
82
+ if "error" in data:
83
  st.error(f"API Error: {data['error'].get('message', 'Unknown error')}")
84
  return None
85
+
86
+ if not data.get("candidates"):
87
  st.error("No response candidates found in API response")
88
  return None
89
 
90
+ candidate = data["candidates"][0]
91
+ return candidate.get("content", {}).get("parts", [{}])[0].get("text", "No response text found")
92
+
93
  except requests.exceptions.RequestException as e:
94
  st.error(f"API Request failed: {str(e)}")
95
  return None
 
99
 
100
  # Process the uploaded document
101
  def process_document():
102
+ uploaded_file = st.session_state.get("uploaded_file")
103
+ if not uploaded_file:
104
  st.error("Please upload a document first.")
105
  return
106
+
107
  try:
108
  with st.spinner("Analyzing document..."):
109
+ # Encode file to base64
110
+ image_b64 = encode_file(uploaded_file)
111
  if not image_b64:
112
  return
113
 
114
+ # Store preview image
115
+ if uploaded_file.type == "application/pdf":
116
+ pdf = fitz.open(stream=BytesIO(uploaded_file.getvalue()))
117
+ page = pdf[0]
118
+ pix = page.get_pixmap()
119
+ st.session_state.doc_preview = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
120
+ else:
121
+ st.session_state.doc_preview = Image.open(uploaded_file)
122
+
123
+ # Classify document
124
+ classify_prompt = (
125
+ f"Classify this document into one of these categories: {', '.join(DOCUMENT_TYPES)}. "
126
+ "Respond only with the category name."
127
+ )
128
  doc_type = query_gemini(classify_prompt, image_b64)
129
 
130
+ # Extract details
131
+ extract_prompt = (
132
+ "Extract key details including:\n"
133
+ "- Names\n"
134
+ "- Dates\n"
135
+ "- Identification numbers\n"
136
+ "- Locations\n"
137
+ "Format as a bullet-point list."
138
+ )
139
  details = query_gemini(extract_prompt, image_b64)
140
+
141
+ # Verify authenticity
142
  verify_prompt = "Analyze this document for signs of tampering. Provide verification status."
143
  verification = query_gemini(verify_prompt, image_b64)
144
 
 
147
  "details": details or "No details extracted",
148
  "verification": verification or "Verification failed",
149
  }
150
+
151
  st.success("Document processing complete!")
152
  time.sleep(1)
153
+
154
  except Exception as e:
155
  st.error(f"Document processing failed: {str(e)}")
156
  st.session_state.processed_doc = None
 
160
  st.set_page_config(page_title="DocVerify AI", layout="wide")
161
  initialize_session_state()
162
 
163
+ # Sidebar Controls
164
+ with st.sidebar:
165
+ st.header("Document Controls")
166
+ # The file uploader widget manages its own state with key "uploaded_file"
167
+ st.file_uploader(
168
+ "Upload Document",
169
+ type=["pdf", "jpg", "jpeg", "png", "txt"],
170
+ key="uploaded_file",
171
+ on_change=process_document,
172
+ help="Supported formats: PDF, JPG, PNG, TXT"
173
+ )
174
+
175
+ if st.button("New Document"):
176
+ reset_session_state()
177
+ st.experimental_rerun()
178
+
179
+ if st.session_state.get("processed_doc"):
180
+ st.divider()
181
+ st.subheader("Document Summary")
182
+ st.markdown(f"**Type:** {st.session_state.processed_doc['type']}")
183
+ st.markdown(f"**Verification Status:** {st.session_state.processed_doc['verification']}")
184
+
185
+ # Main Interface
186
+ st.title("📄 Automated Document Verifier")
187
 
188
+ if st.session_state.get("processed_doc") and st.session_state.get("doc_preview"):
189
+ col1, col2 = st.columns([1, 2])
190
+ with col1:
191
+ st.subheader("Document Preview")
192
+ st.image(st.session_state.doc_preview, use_column_width=True)
193
+
194
+ with col2:
195
+ st.subheader("Extracted Details")
196
+ st.markdown(st.session_state.processed_doc["details"])
197
+
198
+ st.subheader("Verification Analysis")
199
+ st.markdown(st.session_state.processed_doc["verification"])
200
+ else:
201
+ st.info("Please upload a document to begin verification analysis")
202
 
203
  if __name__ == "__main__":
204
  main()