Utility functions for Mozambique — validation of NUIT, BI, documents, and phone number formatting.
Project description
moz-utils
Python
The Swiss Army Knife for developers in Mozambique — ported to Python. Ideal for integration into backends with Django, Flask, FastAPI, and data science projects.
📦 Installation
You can install the library directly from the local directory or using pip:
# Installation from the python folder root
pip install .
🚀 API Reference Guide
1. Document Validation
is_valid_nuit(nuit: Union[str, int]) -> bool
Validates if a NUIT (Unique Tax Identification Number) is syntactically valid following the Modulo 11 rules of the Tax Authority (AT).
from moz_utils import is_valid_nuit
is_valid_nuit('123456789') # True
is_valid_nuit(111111111) # False (repeated digit)
get_nuit_entity_type(nuit: Union[str, int]) -> Optional[str]
Returns the entity classification corresponding to the first digit of the NUIT. Returns None if the NUIT is invalid.
from moz_utils import get_nuit_entity_type
get_nuit_entity_type('100000008') # "Singular (Cidadãos nacionais/estrangeiros e ENI)"
get_nuit_entity_type('400000006') # "Colectiva (Sociedades por Quotas, SA, Lda, Associações)"
is_valid_bi(bi: str) -> bool
Validates if the Mozambican National Identity Card (BI) format is correct (12 digits + 1 letter). It ignores spaces and dashes.
from moz_utils import is_valid_bi
is_valid_bi('110101234567A') # True
is_valid_bi('110101234567 a') # True (case-insensitive and ignores spaces)
is_valid_bi('11010123456') # False
2. Mobile Phone and Communication Utilities
is_valid_mozambican_phone(phone: str) -> bool
Validates if the number belongs to a valid national mobile carrier (Vodacom, Tmcel, or Movitel).
from moz_utils import is_valid_mozambican_phone
is_valid_mozambican_phone('841234567') # True
is_valid_mozambican_phone('+258869876543') # True
is_valid_mozambican_phone('991234567') # False
format_mozambican_phone(phone: str) -> str
Formats the mobile number to the standard international display format: +258 XX XXX XXXX. Throws ValueError if the number is invalid.
from moz_utils import format_mozambican_phone
format_mozambican_phone('841234567') # "+258 84 123 4567"
get_mobile_operator(phone: str) -> Optional[str]
Returns the carrier name associated with the phone number ('Vodacom', 'Tmcel', or 'Movitel').
from moz_utils import get_mobile_operator
get_mobile_operator('841234567') # "Vodacom"
get_mobile_operator('821234567') # "Tmcel"
build_whatsapp_url(phone: str, message: str = "") -> str
Generates a direct link to open a WhatsApp conversation pre-filled with the Mozambican country code (258) and the optional URL-encoded message.
from moz_utils import build_whatsapp_url
build_whatsapp_url('841234567', 'Olá Formiga Antonio, bem-vindo a Nampula!')
# "https://wa.me/258841234567?text=Ol%C3%A1%20Formiga%20Antonio%2C%20bem-vindo%20a%20Nampula%21"
3. Currency Utilities
format_mzn(value: float, currency: str = 'MT') -> str
Formats a value into the official Metical format (space separator for thousands, comma for decimals).
from moz_utils import format_mzn
format_mzn(1250.5) # "1 250,50 MT"
format_mzn(5000000, 'MZN') # "5 000 000,00 MZN"
4. Legacy Postal Codes
is_valid_postal_code(code: str) -> bool
Validates if a legacy postal code of Moçambique is valid (exactly 4 digits belonging to the classic system of the Correios de Moçambique).
from moz_utils import is_valid_postal_code
is_valid_postal_code('1100') # True
is_valid_postal_code('1199') # False
get_postal_code_locality(code: str) -> Optional[str]
Returns the locality associated with the legacy postal code, or None.
from moz_utils import get_postal_code_locality
get_postal_code_locality('1100') # "Maputo ECP (Sede)"
get_postal_code_province(code: str) -> Optional[str]
Returns the province associated with the legacy postal code, or None.
from moz_utils import get_postal_code_province
get_postal_code_province('1100') # "Maputo"
5. Geographical Database
from moz_utils import get_mozambique_provinces, get_districts_by_province, get_all_districts
# 1. Get the complete list with all provinces, districts, posts, and neighborhoods
provinces = get_mozambique_provinces()
# 2. Get districts of a specific province by its ID (e.g., 'npl' for Nampula)
nampula_districts = get_districts_by_province('npl') # ['Angoche', 'Eráti', ...]
# 3. Get a flat list of all districts along with their respective provinces
all_districts = get_all_districts()
📄 License
This project is licensed under the AGPL-3.0-or-later license.
Developed by Edmilson Muacigarro and contributors.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file moz_utils-0.2.0.tar.gz.
File metadata
- Download URL: moz_utils-0.2.0.tar.gz
- Upload date:
- Size: 26.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b86e5c0097651edba96ad3c19115c10c0204455ee668b33869d68eaf23350b9
|
|
| MD5 |
1d43b55f83f3a52fcb269c95ff859831
|
|
| BLAKE2b-256 |
3b78a7ddd624313692180636cc24c356e114ad8bb197f1f5c38a9eb7db449d1e
|
File details
Details for the file moz_utils-0.2.0-py3-none-any.whl.
File metadata
- Download URL: moz_utils-0.2.0-py3-none-any.whl
- Upload date:
- Size: 24.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d00542e4c703fb0c643cf7d938f6f346f83ffb09c7b91364c1d4c02661710930
|
|
| MD5 |
7c070d9006f2172e129f1d82b7d98815
|
|
| BLAKE2b-256 |
8b305a0443922a7c99cacdfa4970f9b62d59b2808bd43f3a869d47378fcf367e
|