File size: 6,458 Bytes
81dda2b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | """
email-deliverability-scorer — LeadsBlue Hugging Face Space.
Estimates an email list's expected deliverability (0-100) from honest, real
factors: verification claim, data age, country compliance friction, and
industry receptiveness (derived from benchmark open rates).
This is an estimate, not a guarantee (stated in the UI).
Data source: country-insights.json, industry-insights.json
Author: Luther Johnson (ORCID 0009-0008-9836-1280) · LeadsBlue Research
License: CC BY 4.0 · Dataset DOI: 10.5281/zenodo.20136256
"""
import gradio as gr
from leadsblue_common import (
CITATION_FOOTER,
softwareapplication_jsonld,
load_country_insights,
load_industry_insights,
parse_pct_range,
)
try:
COUNTRIES = load_country_insights()
INDUSTRIES = load_industry_insights()
LOAD_ERROR = None
except Exception as exc: # pragma: no cover
COUNTRIES, INDUSTRIES, LOAD_ERROR = {}, {}, str(exc)
COUNTRY_CHOICES = sorted(c.title() for c in COUNTRIES.keys())
INDUSTRY_CHOICES = sorted(INDUSTRIES.keys())
VERIFICATION_CHOICES = ["Yes — recently verified", "Partial", "No / unknown"]
AGE_CHOICES = ["Under 6 months", "6–12 months", "12–24 months", "24+ months"]
# GDPR / strict-consent jurisdictions (compliance friction for cold B2B email)
GDPR_COUNTRIES = {
"austria", "belgium", "bulgaria", "croatia", "cyprus", "czech republic",
"denmark", "estonia", "finland", "france", "germany", "greece", "hungary",
"ireland", "italy", "latvia", "lithuania", "luxembourg", "malta",
"netherlands", "poland", "portugal", "romania", "slovakia", "slovenia",
"spain", "sweden", "united kingdom",
}
CANSPAM_COUNTRIES = {"united states", "canada"}
VERIFICATION_POINTS = {"Yes — recently verified": 30, "Partial": 10, "No / unknown": 0}
AGE_POINTS = {"Under 6 months": 0, "6–12 months": -10, "12–24 months": -20, "24+ months": -35}
def _compliance_friction(country):
c = country.lower()
if c in GDPR_COUNTRIES:
return -10, "GDPR jurisdiction (consent expectations): -10"
if c in CANSPAM_COUNTRIES:
return -3, "CAN-SPAM/CASL jurisdiction: -3"
return 0, "Lighter regulatory friction: 0"
def _industry_receptiveness(industry):
perf = INDUSTRIES.get(industry, {}).get("cold_email_performance", {})
if "open_rate" not in perf:
return 0, "Industry receptiveness: no data (0)"
lo, hi = parse_pct_range(perf["open_rate"])
mid = (lo + hi) / 2
if mid >= 25:
return 10, "High-receptiveness industry (open ~%.0f%%): +10" % mid
if mid >= 20:
return 6, "Above-average receptiveness (open ~%.0f%%): +6" % mid
if mid >= 15:
return 3, "Moderate receptiveness (open ~%.0f%%): +3" % mid
return 0, "Lower-receptiveness industry (open ~%.0f%%): 0" % mid
def score(country, industry, verification, data_age, list_source):
if LOAD_ERROR:
return "**Data failed to load.** %s" % LOAD_ERROR
if not country or not industry or not verification or not data_age:
return "Please complete country, industry, verification, and data age."
base = 50
parts = ["Baseline: 50"]
v = VERIFICATION_POINTS[verification]
parts.append("Verification (%s): %+d" % (verification, v))
a = AGE_POINTS[data_age]
parts.append("Data age (%s): %+d" % (data_age, a))
cf, cf_note = _compliance_friction(country)
parts.append(cf_note)
ir, ir_note = _industry_receptiveness(industry)
parts.append(ir_note)
total = max(0, min(100, base + v + a + cf + ir))
if total >= 75:
verdict = "Strong — list profile supports good deliverability."
elif total >= 55:
verdict = "Moderate — workable with verification and warm-up."
elif total >= 35:
verdict = "Caution — refresh and re-verify before sending at volume."
else:
verdict = "High risk — re-source or heavily clean before use."
recs = []
if v < 30:
recs.append("Verify the list with a real-time validation pass before sending.")
if a < 0:
recs.append("Refresh records older than 6 months; B2B data decays ~2-3%/month.")
if cf < 0:
recs.append("For this jurisdiction, ensure a legitimate-interest basis and easy opt-out.")
if not recs:
recs.append("Maintain list hygiene and monitor bounce/complaint rates per send.")
body = (
"## Deliverability estimate: %d / 100\n\n"
"**%s**\n\n"
"### Score breakdown\n%s\n\n"
"### Recommended actions\n%s\n\n"
"> _This is an estimate based on benchmark factors, not a guarantee. "
"Actual deliverability depends on sender reputation, content, and ESP "
"configuration._\n\n---\n%s"
) % (
total,
verdict,
"\n".join("- " + p for p in parts),
"\n".join("- " + r for r in recs),
CITATION_FOOTER,
)
return body
HEAD = softwareapplication_jsonld(
"LeadsBlue Email Deliverability Scorer",
"Estimates B2B email list deliverability from verification, data age, jurisdiction, and industry.",
)
_blocks_kwargs = {"title": "LeadsBlue Email Deliverability Scorer"}
try:
demo = gr.Blocks(head=HEAD, **_blocks_kwargs)
except TypeError:
demo = gr.Blocks(**_blocks_kwargs) # older/newer gradio: head set at launch()
with demo:
gr.Markdown(
"# LeadsBlue Email Deliverability Scorer\n"
"An honest, factor-based estimate of how a B2B list is likely to perform. "
"No guarantees — just transparent scoring."
)
with gr.Row():
country = gr.Dropdown(COUNTRY_CHOICES, label="Country", value=("United States" if "United States" in COUNTRY_CHOICES else None))
industry = gr.Dropdown(INDUSTRY_CHOICES, label="Industry", value=(INDUSTRY_CHOICES[0] if INDUSTRY_CHOICES else None))
with gr.Row():
verification = gr.Dropdown(VERIFICATION_CHOICES, label="Email verification", value="Partial")
data_age = gr.Dropdown(AGE_CHOICES, label="Data age", value="6–12 months")
list_source = gr.Textbox(label="List source (optional)", placeholder="e.g. opt-in webinar, scraped directory, purchased...")
btn = gr.Button("Score deliverability", variant="primary")
out = gr.Markdown()
btn.click(score, [country, industry, verification, data_age, list_source], out)
gr.Markdown("---\n_%s_" % CITATION_FOOTER)
if __name__ == "__main__":
try:
demo.launch(head=HEAD)
except TypeError:
demo.launch()
|