manabb commited on
Commit
b28a8a0
·
verified ·
1 Parent(s): fee88dd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -103
app.py CHANGED
@@ -5,9 +5,8 @@ import pandas as pd
5
  from docx import Document
6
  import time
7
 
8
- #==== import completed
9
-
10
  client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
 
11
  #=====
12
  #Payment type
13
  manual_payment_type="""
@@ -72,155 +71,114 @@ PQC_rules="""
72
  15. PQC should balance inclusion of capable vendors and exclusion of incapable ones."""
73
 
74
  #============starting extract_docx_text
 
75
  def extract_docx_text(file_path):
76
- # Load the DOCX file
77
  doc = Document(file_path)
78
-
79
- # Extract all content in a structured way
80
  final_data = []
81
-
82
- # Process all tables in the document
83
  for table_idx, table in enumerate(doc.tables):
84
  for row in table.rows:
85
  cells = [cell.text.strip() for cell in row.cells]
86
-
87
- # If it's a 2-column layout (Key: Value format)
88
  if len(cells) == 2:
89
  key = cells[0].replace(':', '').strip()
90
  value = cells[1].strip()
91
  if key and value:
92
  final_data.append({'Field': key, 'Value': value, 'Source': f'Table_{table_idx+1}'})
93
  else:
94
- # Multi-column or single column data
95
  combined = ' | '.join([c for c in cells if c])
96
  if combined:
97
  final_data.append({'Field': 'Multi-Column Data', 'Value': combined, 'Source': f'Table_{table_idx+1}'})
 
98
 
99
- # Create DataFrame
100
- df= pd.DataFrame(final_data)
101
- #doc = Document(file_path)
102
- #text = "\n".join([para.text for para in doc.paragraphs])
103
- return df
104
-
105
- #====generate response function started
106
- def generate_response(manual,proposal):
107
- prompt = """
108
  You are a strict compliance checker for Govt. procurement policies.
109
 
110
- You must check whether the proposal is complying the requirements of MANUAL and then respond in the exact structured format shown below.
111
 
112
- Format (use these exact labels):
113
- Status: COMPLIANT or NON-COMPLIANT
114
- Severity: HIGH or MEDIUM or LOW
115
- Deviations: <short bullet-style description of deviations or 'None'>
116
- Fix: <clear corrective action>
117
 
118
- COMPLIANCE ANALYSIS: <2–4 sentences explaining reasoning>
119
 
120
  MANUAL: {manual}
121
 
122
  proposal: {proposal}
123
-
124
  """
125
- response = client.responses.create(
126
- #model="gpt-4.1-nano",
127
- model="gpt-5-mini",
128
- input=prompt,
129
- temperature=0.1
130
- )
131
- return response.output[0].content[0].text
132
- #===generate_response function end
133
- #=====loop function start
134
- def loop_function(df):
135
- Value_of_proposal=""
136
- Category_of_proposal=""
137
- Tender_Type_of_proposal=""
138
- Name_of_proposal=""
139
- manual_rules=""
140
- proposal_details=""
141
  for index, row in df.iterrows():
142
  key = str(row['Field'])
143
  value = str(row['Value'])
144
- i=0
145
- proposal_details=""
146
- manual_rules=""
147
- if key == "File No.":
148
- #print(f"The proposal E-File No. of Arohan is: {value}")
149
- continue
150
- if key == "PR No.":
151
- #print(f"The proposal PR No. is: {value}")
152
  continue
 
153
  if key == "Value (Rs)":
154
- #print(f"The proposal Value is: {value}")
155
- Value_of_proposal=f"The proposal Value is {value}. \n"
156
  continue
157
  if key == "Category":
158
- #print(f"The proposal Category is: {value}")
159
- Category_of_proposal=f"The proposal Category is {value}. \n"
160
  continue
161
  if key == "Tender Type":
162
- #print(f"The proposal Tender Type is: {value}")
163
- Tender_Type_of_proposal=f"The proposal Tender Type is {value}. \n"
164
- continue
165
- if key == "Name of proposal":
166
- #print(f"The proposal Name of proposal is: {value}. \n")
167
- continue
168
- if key == "Justification/Reason for Procurement":
169
- #print(f"The reason for Procurement of the items is as under: {value}. \n")
170
  continue
 
171
  if key == "PQC for Open tenders":
172
  manual_rules = PQC_rules
173
- proposal_details= f"The Pre Qualifying Criteria (PQC) of the proposal is under: {value}. {Value_of_proposal}"
174
- i=1
175
- if key == "Basis of estimate":
176
- manual_rules=manual_basis_of_estimate
177
- proposal_details= f"The basis of estimate of the proposal is under: {value}. "
178
- i=1
179
- if key == "Payment Terms":
180
- manual_rules=manual_payment_type
181
- proposal_details=f"The Payment Terms of the proposal is {value}. "
182
- i=1
183
-
184
- #query = f"{key}: {value}"
185
-
186
-
187
- if i==1:
188
- try:
189
- rr = generate_response(manual_rules,proposal_details)
190
- text += rr
191
- yield text
192
- time.sleep(3)
193
- continue
194
- except Exception as e:
195
- print(f"Error: {e} - skipping row")
196
- continue
197
- #======loop function completed
198
-
199
-
200
-
201
- def check_compliance(file):
202
  if file.name.endswith(".docx"):
203
  df1 = extract_docx_text(file.name)
204
- loop_function(df1)
205
  else:
206
- return "Unsupported file format"
207
-
208
-
209
- #=====gradio coding
210
 
 
211
  with gr.Blocks() as demo:
212
  with gr.Row():
213
- inp=gr.File(
214
  label="Upload Proposal",
215
  file_types=[".docx"]
216
  )
217
 
218
  out = gr.Textbox(lines=15, label="Compliance Result")
219
-
220
  run_btn = gr.Button("Check compliance")
221
-
222
- # Important: use queue() to enable streaming
223
- run_btn.click(check_compliance, inputs=inp, outputs=out)
224
 
225
  demo.queue().launch()
226
-
 
5
  from docx import Document
6
  import time
7
 
 
 
8
  client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
9
+
10
  #=====
11
  #Payment type
12
  manual_payment_type="""
 
71
  15. PQC should balance inclusion of capable vendors and exclusion of incapable ones."""
72
 
73
  #============starting extract_docx_text
74
+
75
  def extract_docx_text(file_path):
 
76
  doc = Document(file_path)
 
 
77
  final_data = []
 
 
78
  for table_idx, table in enumerate(doc.tables):
79
  for row in table.rows:
80
  cells = [cell.text.strip() for cell in row.cells]
 
 
81
  if len(cells) == 2:
82
  key = cells[0].replace(':', '').strip()
83
  value = cells[1].strip()
84
  if key and value:
85
  final_data.append({'Field': key, 'Value': value, 'Source': f'Table_{table_idx+1}'})
86
  else:
 
87
  combined = ' | '.join([c for c in cells if c])
88
  if combined:
89
  final_data.append({'Field': 'Multi-Column Data', 'Value': combined, 'Source': f'Table_{table_idx+1}'})
90
+ return pd.DataFrame(final_data)
91
 
92
+ def generate_response(manual, proposal):
93
+ prompt = f"""
 
 
 
 
 
 
 
94
  You are a strict compliance checker for Govt. procurement policies.
95
 
96
+ Check whether the proposal complies with MANUAL requirements. Respond in EXACT format:
97
 
98
+ Status: COMPLIANT or NON-COMPLIANT
99
+ Severity: HIGH or MEDIUM or LOW
100
+ Deviations: <short bullet-style description or 'None'>
101
+ Fix: <clear corrective action>
 
102
 
103
+ COMPLIANCE ANALYSIS: <2–4 sentences explaining reasoning>
104
 
105
  MANUAL: {manual}
106
 
107
  proposal: {proposal}
 
108
  """
109
+
110
+ response = client.chat.completions.create( # FIXED: correct method
111
+ model="gpt-4o-mini", # FIXED: use existing model (gpt-5-mini may not exist)
112
+ messages=[{"role": "user", "content": prompt}],
113
+ temperature=0.1
114
+ )
115
+ return response.choices[0].message.content # FIXED: correct path
116
+
117
+ def loop_function(df): # now properly yields
118
+ text = "" # FIXED: initialize
119
+ Value_of_proposal = ""
120
+
 
 
 
 
121
  for index, row in df.iterrows():
122
  key = str(row['Field'])
123
  value = str(row['Value'])
124
+ i = 0
125
+ proposal_details = ""
126
+ manual_rules = ""
127
+
128
+ if key == "File No." or key == "PR No." or key == "Name of proposal" or key == "Justification/Reason for Procurement":
 
 
 
129
  continue
130
+
131
  if key == "Value (Rs)":
132
+ Value_of_proposal = f"The proposal Value is {value}. \n"
 
133
  continue
134
  if key == "Category":
135
+ Category_of_proposal = f"The proposal Category is {value}. \n"
 
136
  continue
137
  if key == "Tender Type":
138
+ Tender_Type_of_proposal = f"The proposal Tender Type is {value}. \n"
 
 
 
 
 
 
 
139
  continue
140
+
141
  if key == "PQC for Open tenders":
142
  manual_rules = PQC_rules
143
+ proposal_details = f"The Pre Qualifying Criteria (PQC) of the proposal is under: {value}. {Value_of_proposal}"
144
+ i = 1
145
+ elif key == "Basis of estimate": # FIXED: elif
146
+ manual_rules = manual_basis_of_estimate
147
+ proposal_details = f"The basis of estimate of the proposal is under: {value}."
148
+ i = 1
149
+ elif key == "Payment Terms":
150
+ manual_rules = manual_payment_type
151
+ proposal_details = f"The Payment Terms of the proposal is {value}."
152
+ i = 1
153
+
154
+ if i == 1:
155
+ try:
156
+ rr = generate_response(manual_rules, proposal_details)
157
+ text += rr + "\n\n" # FIXED: accumulate
158
+ yield text
159
+ time.sleep(3)
160
+ except Exception as e:
161
+ print(f"Error: {e} - skipping row")
162
+ continue
163
+
164
+ def check_compliance(file): # FIXED: now streams
 
 
 
 
 
 
 
165
  if file.name.endswith(".docx"):
166
  df1 = extract_docx_text(file.name)
167
+ yield from loop_function(df1) # FIXED: delegate yields
168
  else:
169
+ yield "Unsupported file format"
 
 
 
170
 
171
+ # Gradio (FIXED input name)
172
  with gr.Blocks() as demo:
173
  with gr.Row():
174
+ inp = gr.File( # consistent name
175
  label="Upload Proposal",
176
  file_types=[".docx"]
177
  )
178
 
179
  out = gr.Textbox(lines=15, label="Compliance Result")
 
180
  run_btn = gr.Button("Check compliance")
181
+
182
+ run_btn.click(check_compliance, inputs=inp, outputs=out) # FIXED: inputs=inp
 
183
 
184
  demo.queue().launch()