Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
| 1 |
-
# app.py - Advanced Email Verifier
|
| 2 |
-
# For Hugging Face Spaces
|
| 3 |
|
| 4 |
import re
|
| 5 |
import socket
|
|
@@ -53,7 +52,7 @@ def is_catchall_domain(domain: str, mx_host: str) -> bool:
|
|
| 53 |
return domain_catchall_cache[domain]
|
| 54 |
|
| 55 |
accepted_count = 0
|
| 56 |
-
for _ in range(2):
|
| 57 |
random_local = ''.join(random.choices(string.ascii_lowercase + string.digits, k=16))
|
| 58 |
test_email = f"{random_local}@{domain}"
|
| 59 |
if smtp_rcpt_check(mx_host, test_email) == "true":
|
|
@@ -82,19 +81,35 @@ def verify_email(email: str) -> Dict:
|
|
| 82 |
result["comments"] = "No MX record - domain doesn't accept emails"
|
| 83 |
return result
|
| 84 |
|
| 85 |
-
# Check
|
|
|
|
| 86 |
try:
|
| 87 |
socket.create_connection((mx_host, 25), timeout=10)
|
| 88 |
except Exception:
|
| 89 |
-
|
| 90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
return result
|
| 92 |
|
|
|
|
| 93 |
mailbox_status = smtp_rcpt_check(mx_host, email)
|
| 94 |
|
| 95 |
-
big_providers = ["gmail.com", "outlook.com", "hotmail.com", "yahoo.com", "icloud.com", "protonmail.com"]
|
| 96 |
-
is_big = any(domain.endswith(p) for p in big_providers)
|
| 97 |
-
|
| 98 |
if mailbox_status == "true":
|
| 99 |
result["status"] = "Real (Confirmed)"
|
| 100 |
result["comments"] = "Server confirmed mailbox exists"
|
|
@@ -102,7 +117,7 @@ def verify_email(email: str) -> Dict:
|
|
| 102 |
result["status"] = "Fake (Rejected)"
|
| 103 |
result["comments"] = "Server rejected - mailbox does not exist"
|
| 104 |
else: # unknown
|
| 105 |
-
if
|
| 106 |
result["status"] = "Likely Real"
|
| 107 |
result["comments"] = "Inconclusive (major providers block deep verification)"
|
| 108 |
else:
|
|
@@ -123,33 +138,35 @@ def verify_emails(input_text: str):
|
|
| 123 |
results = [verify_email(email) for email in emails]
|
| 124 |
df = pd.DataFrame(results)
|
| 125 |
|
| 126 |
-
|
|
|
|
|
|
|
| 127 |
invalid = len(df) - deliverable
|
| 128 |
summary = f"Processed: {len(emails)} | Deliverable/Likely Real: {deliverable} | Fake/Invalid: {invalid}"
|
| 129 |
|
| 130 |
-
#
|
| 131 |
df_to_save = df[["email", "status", "comments"]]
|
| 132 |
temp_dir = tempfile.gettempdir()
|
| 133 |
excel_filename = "email_verification_results.xlsx"
|
| 134 |
excel_path = os.path.join(temp_dir, excel_filename)
|
| 135 |
-
|
| 136 |
-
df_to_save.to_excel(excel_path, index=False, sheet_name="Verification Results")
|
| 137 |
|
| 138 |
return df_to_save, summary, excel_path
|
| 139 |
|
| 140 |
# Gradio Interface
|
| 141 |
-
with gr.Blocks(title="Advanced Email Verifier", theme=gr.themes.Soft()) as demo:
|
| 142 |
-
gr.Markdown("# π‘οΈ Advanced Email Verifier
|
| 143 |
gr.Markdown("""
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
|
|
|
| 147 |
""")
|
| 148 |
|
| 149 |
input_box = gr.Textbox(
|
| 150 |
label="Emails to Verify",
|
| 151 |
lines=15,
|
| 152 |
-
placeholder="example@gmail.com\ninfo@business.com
|
| 153 |
info="One email per line"
|
| 154 |
)
|
| 155 |
|
|
@@ -180,14 +197,14 @@ with gr.Blocks(title="Advanced Email Verifier", theme=gr.themes.Soft()) as demo:
|
|
| 180 |
|
| 181 |
gr.Markdown("""
|
| 182 |
### Status Meanings:
|
| 183 |
-
- **Real (Confirmed)** β
|
| 184 |
-
- **
|
| 185 |
-
- **
|
| 186 |
-
- **Possibly Real** β Inconclusive
|
| 187 |
-
- **Fake (Rejected)** β
|
| 188 |
- **Fake/Invalid** β Bad format or no mail server
|
| 189 |
|
| 190 |
-
π
|
| 191 |
""")
|
| 192 |
|
| 193 |
demo.launch()
|
|
|
|
| 1 |
+
# app.py - Advanced Email Verifier (Optimized for 2026 Cloud Limitations + Excel Export)
|
|
|
|
| 2 |
|
| 3 |
import re
|
| 4 |
import socket
|
|
|
|
| 52 |
return domain_catchall_cache[domain]
|
| 53 |
|
| 54 |
accepted_count = 0
|
| 55 |
+
for _ in range(2):
|
| 56 |
random_local = ''.join(random.choices(string.ascii_lowercase + string.digits, k=16))
|
| 57 |
test_email = f"{random_local}@{domain}"
|
| 58 |
if smtp_rcpt_check(mx_host, test_email) == "true":
|
|
|
|
| 81 |
result["comments"] = "No MX record - domain doesn't accept emails"
|
| 82 |
return result
|
| 83 |
|
| 84 |
+
# Check connectivity
|
| 85 |
+
server_reachable = True
|
| 86 |
try:
|
| 87 |
socket.create_connection((mx_host, 25), timeout=10)
|
| 88 |
except Exception:
|
| 89 |
+
server_reachable = False
|
| 90 |
+
|
| 91 |
+
big_providers = [
|
| 92 |
+
"gmail.com", "googlemail.com",
|
| 93 |
+
"outlook.com", "hotmail.com", "live.com", "msn.com",
|
| 94 |
+
"yahoo.com", "ymail.com", "rocketmail.com",
|
| 95 |
+
"icloud.com", "me.com", "mac.com",
|
| 96 |
+
"protonmail.com", "proton.me",
|
| 97 |
+
"aol.com"
|
| 98 |
+
]
|
| 99 |
+
is_big_provider = domain.endswith(tuple(big_providers))
|
| 100 |
+
|
| 101 |
+
if not server_reachable:
|
| 102 |
+
if is_big_provider:
|
| 103 |
+
result["status"] = "Likely Real"
|
| 104 |
+
result["comments"] = "Major provider (Gmail/Outlook/etc.) blocks cloud verifiers β almost always valid"
|
| 105 |
+
else:
|
| 106 |
+
result["status"] = "Likely Fake"
|
| 107 |
+
result["comments"] = "Mail server unreachable (may be blocked or down)"
|
| 108 |
return result
|
| 109 |
|
| 110 |
+
# Server is reachable β do full SMTP check
|
| 111 |
mailbox_status = smtp_rcpt_check(mx_host, email)
|
| 112 |
|
|
|
|
|
|
|
|
|
|
| 113 |
if mailbox_status == "true":
|
| 114 |
result["status"] = "Real (Confirmed)"
|
| 115 |
result["comments"] = "Server confirmed mailbox exists"
|
|
|
|
| 117 |
result["status"] = "Fake (Rejected)"
|
| 118 |
result["comments"] = "Server rejected - mailbox does not exist"
|
| 119 |
else: # unknown
|
| 120 |
+
if is_big_provider:
|
| 121 |
result["status"] = "Likely Real"
|
| 122 |
result["comments"] = "Inconclusive (major providers block deep verification)"
|
| 123 |
else:
|
|
|
|
| 138 |
results = [verify_email(email) for email in emails]
|
| 139 |
df = pd.DataFrame(results)
|
| 140 |
|
| 141 |
+
# Count deliverable/likely
|
| 142 |
+
good_statuses = df["status"].str.contains("Real|Deliverable|Likely", case=False)
|
| 143 |
+
deliverable = len(df[good_statuses])
|
| 144 |
invalid = len(df) - deliverable
|
| 145 |
summary = f"Processed: {len(emails)} | Deliverable/Likely Real: {deliverable} | Fake/Invalid: {invalid}"
|
| 146 |
|
| 147 |
+
# Excel export
|
| 148 |
df_to_save = df[["email", "status", "comments"]]
|
| 149 |
temp_dir = tempfile.gettempdir()
|
| 150 |
excel_filename = "email_verification_results.xlsx"
|
| 151 |
excel_path = os.path.join(temp_dir, excel_filename)
|
| 152 |
+
df_to_save.to_excel(excel_path, index=False, sheet_name="Results")
|
|
|
|
| 153 |
|
| 154 |
return df_to_save, summary, excel_path
|
| 155 |
|
| 156 |
# Gradio Interface
|
| 157 |
+
with gr.Blocks(title="Advanced Email Verifier 2026", theme=gr.themes.Soft()) as demo:
|
| 158 |
+
gr.Markdown("# π‘οΈ Advanced Email Verifier (2026 Edition)")
|
| 159 |
gr.Markdown("""
|
| 160 |
+
**Works great on custom/business domains**
|
| 161 |
+
For Gmail, Outlook, Yahoo, etc.: Shows "Likely Real" because these providers block cloud-based verification tools (common in 2026).
|
| 162 |
+
|
| 163 |
+
Paste emails (one per line) β get accurate results + Excel download.
|
| 164 |
""")
|
| 165 |
|
| 166 |
input_box = gr.Textbox(
|
| 167 |
label="Emails to Verify",
|
| 168 |
lines=15,
|
| 169 |
+
placeholder="example@gmail.com\ninfo@business.com",
|
| 170 |
info="One email per line"
|
| 171 |
)
|
| 172 |
|
|
|
|
| 197 |
|
| 198 |
gr.Markdown("""
|
| 199 |
### Status Meanings:
|
| 200 |
+
- **Real (Confirmed)** β Server confirmed it exists
|
| 201 |
+
- **Likely Real** β Gmail/Outlook/Yahoo/etc. or blocked server β 99% valid in practice
|
| 202 |
+
- **Deliverable (Catch-all)** β Domain accepts everything
|
| 203 |
+
- **Possibly Real** β Inconclusive on custom domain
|
| 204 |
+
- **Fake (Rejected)** β Explicitly doesn't exist
|
| 205 |
- **Fake/Invalid** β Bad format or no mail server
|
| 206 |
|
| 207 |
+
π No emails sent β’ Runs on Hugging Face (cloud IPs blocked by big providers β hence "Likely Real")
|
| 208 |
""")
|
| 209 |
|
| 210 |
demo.launch()
|