Skip to main content

moz-utils (Python)

The definitive, zero-dependency, offline-first open-source library for software built in or for Mozambique.

PyPI License: Apache 2.0 Website

Author: Edmilson Muacigarro (@iradoweck)
Official Documentation: iradoweck.github.io/moz-utils
GitHub Repository: iradoweck/moz-utils


🌍 The Vision

When developing applications for Mozambique, engineers constantly solve the exact same problems from scratch:

  • 🔎 Is this NUIT valid? — The Tax Authority uses a Modulo 11 algorithm. A single wrong digit and your backend fails silently.
  • 📱 Is this number Vodacom, Tmcel or Movitel? — The prefix rules are operator-specific and rarely documented publicly.
  • 🗺️ What is the new CEP for Namutequeliua, Nampula? — The new 6-digit postal system has low adoption. We built the first offline database for it.
  • 🪪 Is this BI / DIRE / Passport valid? — Every identity document has a strict format.

moz-utils solves all of this out-of-the-box, with zero runtime dependencies, offline-first algorithms, and strict privacy (we don't send data anywhere).


💻 System Requirements

  • Python: >= 3.8
  • Ecosystem: Natively tested on Django, FastAPI, Flask, and raw Data Science scripts (Jupyter/Pandas).

📦 Installation

Install via pip:

pip install moz-utils

🚀 Comprehensive Usage Guide

📱 Phones & Mobile

Validating and extracting information from Mozambican mobile numbers. Fully supports Vodacom, Tmcel, and Movitel.

from moz_utils import (
    is_valid_mozambican_phone, 
    get_mobile_operator, 
    get_mobile_wallet, 
    format_mozambican_phone,
    build_whatsapp_url 
)

# Validation
print(is_valid_mozambican_phone("841234567"))       # True
print(is_valid_mozambican_phone("+258 82 123 4567")) # True
print(is_valid_mozambican_phone("811234567"))        # False

# Operator & Wallet Extraction
print(get_mobile_operator("841234567")) # "Vodacom"
print(get_mobile_wallet("861234567"))   # "e-Mola"

# Formatting
print(format_mozambican_phone("84 123 4567")) # "+258841234567"

# WhatsApp Links
url = build_whatsapp_url("841234567", "Hello!")
print(url) # "https://wa.me/258841234567?text=Hello%21"

⚙️ Under the Hood: Operator Prefixes

Telecommunication operators in Mozambique acquire specific number blocks through the INCM. We map operators using this offline logic:

  • Vodacom: Starts with 84 or 85.
  • Tmcel: Starts with 82 or 83.
  • Movitel: Starts with 86 or 87 or 88.

🪪 Identity Documents

Validating documents prevents fraudulent registrations in systems deployed in Maputo, Nampula, or any other province.

from moz_utils import (
    is_valid_nuit, 
    get_nuit_entity_type, 
    is_valid_bi, 
    is_valid_passport, 
    is_valid_dire, 
    is_valid_driving_license 
)

# NUIT (Tax ID)
print(is_valid_nuit("400000008")) # True
print(get_nuit_entity_type("400000008")) # "Singular" (Individual)

# BI (Identity Card)
print(is_valid_bi("123456789123A")) # True

# Passports, DIRE & Driving License
print(is_valid_passport("AO1234567")) # True
print(is_valid_dire("120345678A"))   # True
print(is_valid_driving_license("MP1234567")) # True

⚙️ Under the Hood: The NUIT Algorithm

Unlike other tax numbers that use descending multipliers, the Mozambican Tax Authority uses a specific fixed matrix of weights [8, 9, 4, 5, 6, 7, 8, 9] to calculate the Modulo 11 for the NUIT. moz-utils replicates this exact mathematical equation offline.


💰 Currency (MZN)

Format numbers into the official Metical standard.

from moz_utils import format_mzn

print(format_mzn(1500)) # "1 500,00 MT"
print(format_mzn(2500000.5)) # "2 500 000,50 MT"

🗺️ Geography & Districts

An offline database containing all 11 provinces and 161 districts of Mozambique.

from moz_utils import MOZAMBIQUE_PROVINCES, get_districts_by_province, get_all_districts

# Loop through provinces
for p in MOZAMBIQUE_PROVINCES:
    print(p['name'])

# Get districts for a specific province
maputo_districts = get_districts_by_province("Maputo")
print(maputo_districts) # ["Boane", "Magude", "Manhiça", "Marracuene", ...]

# Get all 161 districts in a flat array
all_districts = get_all_districts()

📬 Postal Codes (CEP)

Mozambique recently transitioned from the classic 4-digit code to a modern 6-digit CEP (XXXX-XX). moz-utils supports both!

from moz_utils import is_valid_new_cep, suggest_ceps, is_valid_postal_code, get_postal_code_locality

# Modern CEP
print(is_valid_new_cep("3100-05")) # True

# Autocomplete / Suggestion Engine
results = suggest_ceps("namutequeliua")
print(results[0]) 
# {'cep': '3100-05', 'province': 'Nampula', 'district': 'Nampula', 'locality': 'Namutequeliua'}

# Legacy Postal Codes
print(is_valid_postal_code("3100")) # True
print(get_postal_code_locality("3100")) # "Nampula"

⚙️ Under the Hood: The New CEP

The New Postal Addressing Code (CEP) abandons the old 4-digit system in favor of a geospatial alphanumeric format (XXXX-XX). We ported the entire official geographic mapping tree to provide instant autocomplete.


🛠️ Troubleshooting

  • My NUIT fails validation, but the user swears it's real! Cause: The Mozambican NUIT uses a Check Digit generated through a Modulo 11 algorithm. moz-utils does not make exceptions to the mathematical algorithm. If your system accepts mathematically invalid NUITs, your company might face integration issues with the government's e-Tributação systems.

  • Names Returning Empty to the Database (Sanitize) Cause: The sanitize_name() function aggressively strips mathematical characters and numbers. Always run is_valid_name() before sanitizing and saving to the database to ensure the string contains actual alphabetical characters.


📜 License

This project is licensed under the Apache-2.0 License - see the LICENSE file for details.

Release files for moz-utils 0.3.9.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for moz-utils 0.3.9.1
File Size Uploaded
moz_utils-0.3.9.1.tar.gz 31.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for moz-utils 0.3.9.1
File Interpreter ABI Platform
moz_utils-0.3.9.1-py3-none-any.whl Python 3 none any Details

Total release size: 59.1 kB

Release files / moz_utils-0.3.9.1.tar.gz

Download URL moz_utils-0.3.9.1.tar.gz
Size 31.5 kB
Tags Source
SHA-256 checksum
How to use checksums
8c810a347f53cf3590d21ab37a100402ab072db54ba5639a118eee6503fb32f4
BLAKE2b-256 checksum
How to use checksums
b8382dd90d25189becb15a096de8936f24e4021439783e2007f17ab7578ac43b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / moz_utils-0.3.9.1-py3-none-any.whl

Download URL moz_utils-0.3.9.1-py3-none-any.whl
Size 27.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7395e4301a0c50bef596eddc65c2f2b281611d71c65fff8e5cf9866cc9842efd
BLAKE2b-256 checksum
How to use checksums
0cbe988ff1952be56ef2f6a66f455bc6e0411455733f8eb291bf6cb062589cca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

0.3.10

2 release files

This release

0.3.9.1 This release

2 release files

0.3.9

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page