Spaces:
Running
Running
Download scripts/check_call_tz.py from Shurem/mz_chatbot: direct link, hf CLI and curl.
- Browser
- Download file 6.57 kB
-
https://huggingface.co/spaces/Shurem/mz_chatbot/resolve/main/scripts/check_call_tz.py
- Command line
-
hf download hf://spaces/Shurem/mz_chatbot/scripts/check_call_tz.py
-
curl -L -o check_call_tz.py https://huggingface.co/spaces/Shurem/mz_chatbot/resolve/main/scripts/check_call_tz.py
6.57 kB
| """ | |
| check_call_tz.py — what timezone does validation.call_timezone() give for a | |
| number, and how many of the CRM's real leads resolve to a zone at all? | |
| Read-only. Two parts: | |
| 1. A few known numbers with the zone they SHOULD map to (PASS/FAIL). | |
| 2. Every lead in the DB: how many resolve to a timezone, the distribution, | |
| and a sample of the ones that come back unknown (toll-free, area codes | |
| spanning two zones, no country). | |
| uv run python scripts/check_call_tz.py | |
| uv run python scripts/check_call_tz.py --unknown 30 # print more unknown rows | |
| uv run python scripts/check_call_tz.py --sample 20 # cross-check real leads by eye | |
| --sample N picks N random leads that resolved to a timezone and prints, for each, | |
| what libphonenumber's OWN geography database says the number belongs to (city / | |
| state, from the area code) next to the timezone we derived and the local time | |
| right now -- so you can check "212 -> New York -> 6:04 AM" against a world clock | |
| yourself instead of trusting the code. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import random | |
| import sys | |
| from collections import Counter | |
| from datetime import datetime, timezone | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) | |
| from sqlalchemy import select # noqa: E402 | |
| from app.database import SessionLocal # noqa: E402 | |
| from app.models import Lead # noqa: E402 | |
| from app.services.validation import call_timezone # noqa: E402 | |
| # (phone, country hint, expected zone or "" for unknown) | |
| KNOWN = [ | |
| ("+1 214-555-0142", "US", "America/Chicago"), # Dallas | |
| ("+1 212-555-0142", "US", "America/New_York"), # New York | |
| ("+1 310-555-0142", "US", "America/Los_Angeles"), # Los Angeles | |
| ("+1 604-555-0142", "CA", "America/Vancouver"), # Vancouver | |
| ("+44 20 7946 0958", "GB", "Europe/London"), | |
| ("+971 4 555 0142", "AE", "Asia/Dubai"), | |
| ("+1 800-555-0142", "US", ""), # toll-free, US multi-zone -> unknown | |
| ("+1 800-555-0142", "", ""), | |
| ("", "GB", "Europe/London"), # no number, single-zone country | |
| ("", "US", ""), | |
| ] | |
| def _print_sample(leads, n: int) -> None: | |
| import phonenumbers | |
| from phonenumbers import geocoder | |
| try: | |
| from zoneinfo import ZoneInfo | |
| except ImportError: # pragma: no cover | |
| ZoneInfo = None # type: ignore[assignment] | |
| pool = [l for l in leads if call_timezone(l.contact_phone or "", l.phone_country or l.country or "")] | |
| picks = random.sample(pool, min(n, len(pool))) | |
| now_utc = datetime.now(timezone.utc) | |
| print(f"\n3. Cross-check sample ({len(picks)} random leads). UTC now: {now_utc:%Y-%m-%d %H:%M}") | |
| print(" Compare 'number belongs to' and 'local time' with a world clock / a quick search.") | |
| warned = False | |
| for lead in picks: | |
| raw = (lead.contact_phone or "").split(",")[0].strip() | |
| if raw.startswith("00"): | |
| raw = "+" + raw[2:] | |
| region = (lead.phone_country or lead.country or "").upper() or None | |
| where = "?" | |
| try: | |
| parsed = phonenumbers.parse(raw, None if raw.startswith("+") else region) | |
| where = geocoder.description_for_number(parsed, "en") or "(country only)" | |
| except Exception: | |
| pass | |
| tz = call_timezone(lead.contact_phone or "", lead.phone_country or lead.country or "") | |
| local = "?" | |
| if ZoneInfo is not None: | |
| try: | |
| t = now_utc.astimezone(ZoneInfo(tz)) | |
| weekday = t.strftime("%a") | |
| is_open = weekday not in ("Sat", "Sun") and 9 <= t.hour < 17 | |
| local = f"{t:%a %H:%M} {'OPEN ' if is_open else 'closed'}" | |
| except Exception: | |
| if not warned: | |
| print(" (Windows has no IANA timezone data for Python: run uv pip install tzdata to see local times here)") | |
| warned = True | |
| print(f" #{lead.id:<5} {lead.company_name[:26]:26} {raw[:19]:19} belongs to: {where[:22]:22} tz={tz:20} local={local}") | |
| def main() -> int: | |
| ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) | |
| ap.add_argument("--unknown", type=int, default=15, help="how many unknown-zone leads to print") | |
| ap.add_argument("--sample", type=int, default=0, help="cross-check N random leads (geography + local time)") | |
| args = ap.parse_args() | |
| print("1. Known numbers") | |
| bad = 0 | |
| for phone, country, want in KNOWN: | |
| got = call_timezone(phone, country) | |
| ok = got == want | |
| bad += 0 if ok else 1 | |
| print(f" {'PASS' if ok else 'FAIL'} {phone or '(none)':20} {country or '-':3} -> {got or 'unknown':22} (want {want or 'unknown'})") | |
| db = SessionLocal() | |
| try: | |
| leads = list(db.scalars(select(Lead)).all()) | |
| finally: | |
| db.close() | |
| zones: Counter = Counter() | |
| unknown: list[Lead] = [] | |
| for lead in leads: | |
| tz = call_timezone(lead.contact_phone or "", lead.phone_country or lead.country or "") | |
| zones[tz or "(unknown)"] += 1 | |
| if not tz: | |
| unknown.append(lead) | |
| total = len(leads) | |
| known = total - len(unknown) | |
| no_phone = sum(1 for l in unknown if not (l.contact_phone or "").strip()) | |
| has_phone_total = sum(1 for l in leads if (l.contact_phone or "").strip()) | |
| print(f"\n2. {total} lead(s) in the CRM: {known} resolve to a timezone, {len(unknown)} unknown" | |
| + (f" ({100 * known // total}% known)" if total else "")) | |
| print(f" of the {len(unknown)} unknown: {no_phone} have NO phone number at all, " | |
| f"{len(unknown) - no_phone} have a number but no single timezone (toll-free / multi-zone area code)") | |
| print(f" leads with any phone number: {has_phone_total} of {total}" | |
| + (f" ({100 * has_phone_total // total}%)" if total else "")) | |
| for tz, n in zones.most_common(): | |
| print(f" {n:>5} {tz}") | |
| if unknown: | |
| print(f"\n Unknown sample (first {min(args.unknown, len(unknown))}):") | |
| for lead in unknown[: args.unknown]: | |
| print( | |
| f" #{lead.id:<5} {lead.company_name[:32]:32} phone={lead.contact_phone[:22]:22} " | |
| f"country={lead.country or '-':3} phone_country={lead.phone_country or '-'}" | |
| ) | |
| if args.sample: | |
| _print_sample(leads, args.sample) | |
| print("\nRESULT:", "all known-number checks passed" if not bad else f"{bad} known-number check(s) FAILED") | |
| return 0 if not bad else 1 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |