Update visa_checker_with_download.py
Browse files- visa_checker_with_download.py +83 -41
visa_checker_with_download.py
CHANGED
@@ -4,6 +4,7 @@ import bisect
|
|
4 |
import requests
|
5 |
from io import BytesIO
|
6 |
from bs4 import BeautifulSoup
|
|
|
7 |
|
8 |
# ------------------------------------------------------------------------------------
|
9 |
# Step 1: Load Data (Fetch and Prepare the DataFrame)
|
@@ -106,7 +107,83 @@ def binary_search_nearest(df, target):
|
|
106 |
return before, after
|
107 |
|
108 |
# ------------------------------------------------------------------------------------
|
109 |
-
# Step 3:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
# ------------------------------------------------------------------------------------
|
111 |
|
112 |
def search_application(df):
|
@@ -120,23 +197,11 @@ def search_application(df):
|
|
120 |
|
121 |
if user_input:
|
122 |
# Validate user input
|
123 |
-
if
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
return
|
129 |
-
except ValueError:
|
130 |
-
st.error("Invalid input after IRL. Please enter only digits.")
|
131 |
-
return
|
132 |
-
else:
|
133 |
-
if not user_input.isdigit() or len(user_input) < 8:
|
134 |
-
st.warning("Please enter at least 8 digits for your VISA application number.")
|
135 |
-
return
|
136 |
-
elif len(user_input) > 8:
|
137 |
-
st.warning("The application number cannot exceed 8 digits. Please correct your input.")
|
138 |
-
return
|
139 |
-
application_number = int(user_input)
|
140 |
|
141 |
# Search for the application number in the DataFrame
|
142 |
result = df[df["Application Number"] == application_number]
|
@@ -151,8 +216,6 @@ def search_application(df):
|
|
151 |
st.info(f"Application Number: {application_number}\n\nDecision: **{decision}**")
|
152 |
else:
|
153 |
st.warning(f"No record found for Application Number: {application_number}.")
|
154 |
-
|
155 |
-
# Find nearest application numbers using binary search
|
156 |
before, after = binary_search_nearest(df, application_number)
|
157 |
|
158 |
nearest_records = pd.DataFrame({
|
@@ -174,27 +237,6 @@ def search_application(df):
|
|
174 |
else:
|
175 |
st.info("No nearest application numbers found.")
|
176 |
|
177 |
-
# ------------------------------------------------------------------------------------
|
178 |
-
# Step 4: Allow User to Download Cleaned DataFrame
|
179 |
-
# ------------------------------------------------------------------------------------
|
180 |
-
|
181 |
-
def download_dataframe(df, file_name):
|
182 |
-
"""
|
183 |
-
Provides a download link for the cleaned DataFrame.
|
184 |
-
|
185 |
-
Args:
|
186 |
-
df: The cleaned DataFrame to download.
|
187 |
-
file_name: The name of the original file for naming convention.
|
188 |
-
"""
|
189 |
-
cleaned_file_name = f"cleaned_{file_name.replace('.ods', '.csv')}"
|
190 |
-
csv_data = df.to_csv(index=False)
|
191 |
-
st.download_button(
|
192 |
-
label="Download Cleaned Data",
|
193 |
-
data=csv_data,
|
194 |
-
file_name=cleaned_file_name,
|
195 |
-
mime="text/csv"
|
196 |
-
)
|
197 |
-
|
198 |
# ------------------------------------------------------------------------------------
|
199 |
# Main Streamlit Application Logic
|
200 |
# ------------------------------------------------------------------------------------
|
|
|
4 |
import requests
|
5 |
from io import BytesIO
|
6 |
from bs4 import BeautifulSoup
|
7 |
+
from fpdf import FPDF
|
8 |
|
9 |
# ------------------------------------------------------------------------------------
|
10 |
# Step 1: Load Data (Fetch and Prepare the DataFrame)
|
|
|
107 |
return before, after
|
108 |
|
109 |
# ------------------------------------------------------------------------------------
|
110 |
+
# Step 3: Export DataFrame to PDF
|
111 |
+
# ------------------------------------------------------------------------------------
|
112 |
+
|
113 |
+
def export_to_pdf(df, file_name):
|
114 |
+
"""
|
115 |
+
Converts the cleaned DataFrame to a PDF file.
|
116 |
+
|
117 |
+
Args:
|
118 |
+
df: The DataFrame to be converted to PDF.
|
119 |
+
file_name: The name of the PDF file to create.
|
120 |
+
|
121 |
+
Returns:
|
122 |
+
A BytesIO object containing the PDF file.
|
123 |
+
"""
|
124 |
+
pdf = FPDF()
|
125 |
+
pdf.set_auto_page_break(auto=True, margin=15)
|
126 |
+
pdf.add_page()
|
127 |
+
pdf.set_font("Arial", size=12)
|
128 |
+
|
129 |
+
# Title
|
130 |
+
pdf.set_font("Arial", style="B", size=16)
|
131 |
+
pdf.cell(0, 10, "Visa Decisions Data", ln=True, align="C")
|
132 |
+
pdf.ln(10)
|
133 |
+
|
134 |
+
# Table Header
|
135 |
+
pdf.set_font("Arial", style="B", size=12)
|
136 |
+
for col in df.columns:
|
137 |
+
pdf.cell(50, 10, col, border=1)
|
138 |
+
pdf.ln()
|
139 |
+
|
140 |
+
# Table Data
|
141 |
+
pdf.set_font("Arial", size=12)
|
142 |
+
for _, row in df.iterrows():
|
143 |
+
for cell in row:
|
144 |
+
pdf.cell(50, 10, str(cell), border=1)
|
145 |
+
pdf.ln()
|
146 |
+
|
147 |
+
pdf_output = BytesIO()
|
148 |
+
pdf.output(pdf_output)
|
149 |
+
pdf_output.seek(0)
|
150 |
+
|
151 |
+
return pdf_output
|
152 |
+
|
153 |
+
# ------------------------------------------------------------------------------------
|
154 |
+
# Step 4: Allow User to Download Cleaned DataFrame
|
155 |
+
# ------------------------------------------------------------------------------------
|
156 |
+
|
157 |
+
def download_dataframe(df, file_name):
|
158 |
+
"""
|
159 |
+
Provides a download link for the cleaned DataFrame as CSV or PDF.
|
160 |
+
|
161 |
+
Args:
|
162 |
+
df: The cleaned DataFrame to download.
|
163 |
+
file_name: The name of the original file for naming convention.
|
164 |
+
"""
|
165 |
+
cleaned_file_name_csv = f"{file_name.replace('.ods', '.csv')}"
|
166 |
+
csv_data = df.to_csv(index=False)
|
167 |
+
|
168 |
+
st.sidebar.download_button(
|
169 |
+
label="Download Cleaned Data as CSV",
|
170 |
+
data=csv_data,
|
171 |
+
file_name=cleaned_file_name_csv,
|
172 |
+
mime="text/csv"
|
173 |
+
)
|
174 |
+
|
175 |
+
cleaned_file_name_pdf = f"{file_name.replace('.ods', '.pdf')}"
|
176 |
+
pdf_data = export_to_pdf(df, cleaned_file_name_pdf)
|
177 |
+
|
178 |
+
st.sidebar.download_button(
|
179 |
+
label="Download Cleaned Data as PDF",
|
180 |
+
data=pdf_data,
|
181 |
+
file_name=cleaned_file_name_pdf,
|
182 |
+
mime="application/pdf"
|
183 |
+
)
|
184 |
+
|
185 |
+
# ------------------------------------------------------------------------------------
|
186 |
+
# Step 5: Search Application Status
|
187 |
# ------------------------------------------------------------------------------------
|
188 |
|
189 |
def search_application(df):
|
|
|
197 |
|
198 |
if user_input:
|
199 |
# Validate user input
|
200 |
+
if not user_input.isdigit() or len(user_input) < 8:
|
201 |
+
st.warning("Please enter at least 8 digits for your VISA application number.")
|
202 |
+
return
|
203 |
+
|
204 |
+
application_number = int(user_input)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
|
206 |
# Search for the application number in the DataFrame
|
207 |
result = df[df["Application Number"] == application_number]
|
|
|
216 |
st.info(f"Application Number: {application_number}\n\nDecision: **{decision}**")
|
217 |
else:
|
218 |
st.warning(f"No record found for Application Number: {application_number}.")
|
|
|
|
|
219 |
before, after = binary_search_nearest(df, application_number)
|
220 |
|
221 |
nearest_records = pd.DataFrame({
|
|
|
237 |
else:
|
238 |
st.info("No nearest application numbers found.")
|
239 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
# ------------------------------------------------------------------------------------
|
241 |
# Main Streamlit Application Logic
|
242 |
# ------------------------------------------------------------------------------------
|