Skip to main content

Phone number and timezone → country, currency, and language inference. Extended locale data (symbols, formatting, VAT, RTL) for 55 countries. Zero dependencies.

Project description

tala-locale

CI PyPI Version Python Versions License: MIT Coverage

Phone number → country, currency, and language. One call. Zero dependencies.

from tala_locale import infer_locale

infer_locale("+2348012345678")   # LocaleResult(country='NG', currency='NGN', language='en')
infer_locale("+14155552671")     # LocaleResult(country='US', currency='USD', language='en')
infer_locale("+33612345678")     # LocaleResult(country='FR', currency='EUR', language='fr')
infer_locale("+819012345678")    # LocaleResult(country='JP', currency='JPY', language='ja')

Why tala-locale?

Any application that collects a phone number can instantly know where a user is from — no GPS, no IP lookup, no user forms.

What you want What you get
Pre-fill currency for pricing result.currency"GBP", "NGN", "AED"
Show onboarding in the user's language result.language"en", "fr", "ar", "sw"
Route to the right regional support team result.country"KE", "ZA", "IN"
Skip asking "where are you from?" Infer it silently at signup
Validate that a number is internationally recognisable is_supported(phone)

Works with any messaging platform or application that handles phone numbers: WhatsApp, Telegram, SMS, iMessage, SaaS onboarding flows, e-commerce checkout, fintech KYC, fraud detection, analytics pipelines, CRM enrichment.


Installation

pip install tala-locale

Pure Python. No dependencies. Works on Python 3.10+.


Quick start

from tala_locale import infer_locale, is_supported

# Basic usage
result = infer_locale("+447911123456")
print(result.country)   # "GB"
print(result.currency)  # "GBP"
print(result.language)  # "en"

# Unpack like a plain tuple
country, currency, language = infer_locale("+254712345678")
# country="KE", currency="KES", language="en"

# Check before using
result = infer_locale(user_phone)
if result.is_known():
    set_user_currency(result.currency)
else:
    ask_user_for_currency()

# Quick boolean check
if is_supported(phone):
    ...

Phone format tolerance

tala-locale accepts phone numbers in any common format — it strips everything that isn't a digit before matching:

infer_locale("+234 801 234 5678")        # spaces
infer_locale("+234-801-234-5678")        # dashes
infer_locale("(234) 801 234 5678")       # parentheses
infer_locale("2348012345678")            # bare digits, no +
infer_locale("+2348012345678")           # E.164 standard
infer_locale("whatsapp:+2348012345678")  # WhatsApp format
infer_locale("whatsapp:2348012345678")   # WhatsApp without +

All of the above return LocaleResult(country='NG', currency='NGN', language='en').


Handling unknown numbers

When the prefix is not recognised, all three fields are None. Never assume a default — ask the user explicitly instead:

result = infer_locale(phone)

if result.is_known():
    # Safe to use result.country, result.currency, result.language
    create_account(country=result.country, currency=result.currency)
else:
    # Ask the user — don't guess
    prompt_user_for_country_and_currency()

API reference

infer_locale(phone_number: str) -> LocaleResult

Main function. Returns a LocaleResult named tuple.

class LocaleResult(NamedTuple)

Field Type Description
country str | None ISO 3166-1 alpha-2 (e.g. "NG", "US", "DE")
currency str | None ISO 4217 (e.g. "NGN", "USD", "EUR")
language str | None ISO 639-1 (e.g. "en", "fr", "ar")
.is_known() bool True if prefix was recognised

Shortcut functions

infer_country(phone)   # → str | None  (ISO 3166-1 alpha-2)
infer_currency(phone)  # → str | None  (ISO 4217)
infer_language(phone)  # → str | None  (ISO 639-1)
is_supported(phone)    # → bool

supported_countries() -> list[dict]

Returns all supported entries. Useful for building dropdowns or documentation:

from tala_locale import supported_countries

for entry in supported_countries():
    print(entry["prefix"], entry["country"], entry["currency"], entry["language"])
# 1   US USD en
# 7   RU RUB ru
# 20  EG EGP ar
# ...

Coverage

215+ country/territory entries across all regions:

Region Countries
West Africa Nigeria, Ghana, Senegal, Côte d'Ivoire, Mali, and 11 more
East Africa Kenya, Tanzania, Uganda, Ethiopia, Rwanda, and 5 more
North Africa Egypt, Morocco, Algeria, Tunisia, Libya, Sudan
Southern Africa South Africa, Zambia, Zimbabwe, Botswana, and 5 more
Central Africa DRC, Cameroon, Angola, Gabon, and 5 more
Indian Ocean Madagascar, Mauritius, Seychelles, Comoros
Western Europe UK, France, Germany, Spain, Italy, Netherlands, and 10 more
Eastern Europe Russia, Ukraine, Poland, Czech Republic, and 15 more
North America USA, Canada (via +1), Mexico
Caribbean Trinidad, Jamaica, Barbados, Dominican Republic, and 8 more
Central America Guatemala, Costa Rica, Panama, and 4 more
South America Brazil, Argentina, Colombia, Chile, and 7 more
Middle East UAE, Saudi Arabia, Israel, Turkey, Iran, and 10 more
South Asia India, Pakistan, Bangladesh, Sri Lanka, Nepal
East Asia China, Japan, South Korea, Hong Kong, Taiwan
Southeast Asia Singapore, Indonesia, Malaysia, Thailand, Philippines, Vietnam, and 4 more
Central Asia Uzbekistan, Kazakhstan, Georgia, Armenia, and 4 more
Oceania Australia, New Zealand, Fiji, Papua New Guinea, and 10 more

How prefix matching works

tala-locale uses longest-prefix-match to handle overlapping calling codes:

infer_locale("18681234567")   # +1868 → Trinidad (TT), NOT USA (+1)
infer_locale("18761234567")   # +1876 → Jamaica (JM), NOT USA (+1)
infer_locale("85291234567")   # +852  → Hong Kong (HK)
infer_locale("8801712345678") # +880  → Bangladesh (BD)

The longest matching prefix always wins. Prefixes are sorted at import time, so every call is O(n) on the prefix list — effectively constant for the fixed dataset size.


Contributing

git clone https://github.com/rvethllc/tala-locale
cd tala-locale
pip install -e ".[dev]"
pytest
  • Missing a country or territory? Open a PR — add an entry to src/tala_locale/_data.py with a test.
  • Found an incorrect currency or language code? Same thing — one line change + test.

Versioning

Follows Semantic Versioning. Breaking changes to the public API bump the major version.


License

MIT — see LICENSE for details.


Built by RVETH — makers of TALA, the AI operating system for global enterprise.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tala_locale-0.2.0.tar.gz (27.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tala_locale-0.2.0-py3-none-any.whl (21.0 kB view details)

Uploaded Python 3

File details

Details for the file tala_locale-0.2.0.tar.gz.

File metadata

  • Download URL: tala_locale-0.2.0.tar.gz
  • Upload date:
  • Size: 27.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tala_locale-0.2.0.tar.gz
Algorithm Hash digest
SHA256 3897c9005e813fd67151b9e63e1833ef3abd04be5de157c2bf54df8924e6eb87
MD5 eb87ad61d30304bc018bdae69ae05b8a
BLAKE2b-256 c948c88d0af650c8f070737419089cb49932d94ffdb48be12e923e0625f13833

See more details on using hashes here.

Provenance

The following attestation bundles were made for tala_locale-0.2.0.tar.gz:

Publisher: ci.yml on rvethllc/tala-locale

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tala_locale-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: tala_locale-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 21.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tala_locale-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dc4774e7abcca25c970a8841bf7b8803609bfc8e9c4eef3dc40a6bf6d0ca1523
MD5 b56f96e1d48305f63fe16e7ea2691722
BLAKE2b-256 061b6907c190d4491e19f24765cb9e3d60472809f49391bf8abb7f0be36ec264

See more details on using hashes here.

Provenance

The following attestation bundles were made for tala_locale-0.2.0-py3-none-any.whl:

Publisher: ci.yml on rvethllc/tala-locale

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page