Metadata-Version: 2.4
Name: langchain-saudi-gov
Version: 0.1.0
Summary: LangChain toolkit for Saudi Arabian government and public APIs
Author: Syntera AI
License: MIT
Project-URL: Repository, https://github.com/fouadmahmoud283-ai/langchain-saudi-gov
Project-URL: Documentation, https://github.com/fouadmahmoud283-ai/langchain-saudi-gov#readme
Project-URL: Bug Tracker, https://github.com/fouadmahmoud283-ai/langchain-saudi-gov/issues
Keywords: langchain,saudi-arabia,government-api,national-address,wathq,zatca,open-data
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: langchain-core<1.0,>=0.3
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Dynamic: license-file

<div align="center">

# 🇸🇦 langchain-saudi-gov

**The first LangChain toolkit for Saudi Arabian government APIs**

*Give your AI agents native access to 27 Saudi government services across 7 domains*

[![PyPI](https://img.shields.io/pypi/v/langchain-saudi-gov)](https://pypi.org/project/langchain-saudi-gov/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://python.org)
[![LangChain](https://img.shields.io/badge/LangChain-compatible-blue)](https://python.langchain.com)
[![Tests](https://img.shields.io/badge/tests-116%20passed-brightgreen)](tests/)
[![Tools](https://img.shields.io/badge/tools-27-orange)](docs/tools/)

</div>

---

## Overview

**langchain-saudi-gov** is a production-ready LangChain partner package that wraps 27 Saudi Arabian government and public service APIs into LangChain-compatible tools. It enables AI agents to query national addresses, verify commercial registrations, search open data portals, check prayer times, and much more — all with native Arabic/English bilingual support.

### Why this toolkit?

- 🏛️ **27 tools** across 7 government domains — the most comprehensive Saudi API toolkit available
- 🔑 **16 tools work with zero configuration** — no API keys required for open data portals
- 🌐 **Bilingual Arabic/English** — auto-detects query language, returns bilingual results
- 🤖 **LangChain-native** — every tool is a `BaseTool` subclass, ready for agents and chains
- ⚡ **Async-first** — all tools support both sync and async execution
- 🧪 **Fully tested** — 116 unit tests with mocked HTTP, zero network dependency

---

## 📦 Installation

```bash
pip install langchain-saudi-gov
```

Or with development dependencies:

```bash
pip install "langchain-saudi-gov[dev]"
```

---

## 🚀 Quick Start

### Zero-config — no API keys needed

```python
from langchain_saudi_gov import SaudiGovToolkit

# 16 tools work out of the box with no API keys
toolkit = SaudiGovToolkit()
tools = toolkit.get_tools()
print(f"{len(tools)} tools ready!")  # 16 tools ready!
```

### Use with a LangChain agent

```python
from langchain_saudi_gov import SaudiGovToolkit
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

toolkit = SaudiGovToolkit(
    national_address_key="your-key",   # Free from api.address.gov.sa
    wathq_key="your-wathq-key",        # From developer.wathq.sa
    najiz_key="your-najiz-key",        # From developers.najiz.sa
)

agent = create_react_agent(
    model=ChatOpenAI(model="gpt-4o"),
    tools=toolkit.get_tools(),  # All 27 tools
)

# Ask in Arabic
result = agent.invoke({
    "messages": [{"role": "user", "content": "ابحث عن عنوان مطار الملك عبدالعزيز في جدة"}]
})

# Ask in English
result = agent.invoke({
    "messages": [{"role": "user", "content": "Look up commercial registration 1010123456"}]
})
```

### Use individual tools directly

```python
from langchain_saudi_gov.tools.cultural import PrayerTimesTool, HijriDateTool
from langchain_saudi_gov.tools.statistics import KAPSARCEnergyTool

# Prayer times — no API key
prayer = PrayerTimesTool()
print(prayer.invoke({"city": "Riyadh"}))
# Prayer times for Riyadh — 15 Jul 2025 (18 Muharram 1447)
#   Fajr:    03:35
#   Dhuhr:   12:10
#   Asr:     15:33
#   Maghrib: 18:54
#   Isha:    20:24

# Hijri conversion
hijri = HijriDateTool()
print(hijri.invoke({"date": "01-01-2025", "to_hijri": True}))

# Energy data
energy = KAPSARCEnergyTool()
print(energy.invoke({"query": "Saudi oil production 2024"}))
```

### Domain filtering

```python
# Only load finance and statistics tools
toolkit = SaudiGovToolkit(domains=["finance", "statistics"])
tools = toolkit.get_tools()  # 7 tools from those domains only

# Disable cultural tools
toolkit = SaudiGovToolkit(include_cultural=False)
```

---

## 🛠️ Complete Tool Reference

### 📍 Location Domain (3 tools)

| Tool | API Source | Auth | Description |
|------|-----------|------|-------------|
| `NationalAddressSearchTool` | [api.address.gov.sa](https://api.address.gov.sa) | 🔑 Free key | Free-text address search with auto Arabic/English detection |
| `NationalAddressReverseGeocodeTool` | [api.address.gov.sa](https://api.address.gov.sa) | 🔑 Free key | GPS coordinates → structured national address |
| `BaladyMunicipalTool` | [data.gov.sa](https://data.gov.sa) | ✅ None | Search municipal services & urban planning data |

<details>
<summary><strong>📍 Location examples</strong></summary>

```python
from langchain_saudi_gov.tools.location import (
    NationalAddressSearchTool,
    NationalAddressReverseGeocodeTool,
    BaladyMunicipalTool,
)

# Search by text (Arabic auto-detected)
address = NationalAddressSearchTool(api_key="your-key")
result = address.invoke({"query": "مطار الملك عبدالعزيز جدة"})
# Returns: building number, street, district, city, postcode, GPS

# Reverse geocode
reverse = NationalAddressReverseGeocodeTool(api_key="your-key")
result = reverse.invoke({"lat": 24.7136, "lng": 46.6753})

# Municipal data
balady = BaladyMunicipalTool()
result = balady.invoke({"query": "building permits Riyadh"})
```

**Use cases:**
- 🏢 Address validation for e-commerce checkout
- 🚗 Fleet management and delivery routing
- 🏗️ Urban planning data analysis
- 📍 GPS-to-address conversion for mobile apps

</details>

---

### 🏢 Business Domain — Wathq (8 tools)

| Tool | Endpoint | Description |
|------|----------|-------------|
| `CommercialRegistrationTool` | `/v5/commercialregistration/info/{cr}` | CR lookup: trade name, status, capital, owners, activities |
| `CommercialContractTool` | `/v5/commercialregistration/contracts/{cr}` | Verify and retrieve commercial contracts |
| `RealEstateDeedTool` | `/v5/realestate/deed/{deed}` | Real estate deed verification |
| `TrademarkLookupTool` | `/v5/trademark/search` | Search Saudi trademark registry |
| `CorporateIdentityTool` | `/v5/corporate/identity/{cr}` | Verify company corporate identity |
| `FinancialStatementsTool` | `/v5/commercialregistration/financial/{cr}` | Access company financial statements |
| `EmployeeInfoTool` | `/v5/commercialregistration/employees/{cr}` | Employee count and GOSI registration info |
| `ChamberVerificationTool` | `/v5/chamber/verify/{membership}` | Verify Chamber of Commerce membership |

> All 8 tools require a **Wathq API key** from [developer.wathq.sa](https://developer.wathq.sa). They share the `WathqBaseTool` base class with unified auth, error handling, and rate-limit management.

<details>
<summary><strong>🏢 Business examples</strong></summary>

```python
from langchain_saudi_gov.tools.business import (
    CommercialRegistrationTool,
    TrademarkLookupTool,
    EmployeeInfoTool,
)

# Look up any Saudi company by CR number
cr = CommercialRegistrationTool(api_key="your-wathq-key")
result = cr.invoke({"cr_number": "1010123456"})
# Returns: Trade name, Status, Capital (SAR), Issue/Expiry dates, City, Activities

# Search trademarks
tm = TrademarkLookupTool(api_key="your-wathq-key")
result = tm.invoke({"query": "شركة الراجحي", "search_type": "name"})

# Check employee info
emp = EmployeeInfoTool(api_key="your-wathq-key")
result = emp.invoke({"cr_number": "1010123456"})
```

**Use cases:**
- 📋 Due diligence automation for investment firms
- 🔍 KYC/AML compliance checks
- 📊 Competitive intelligence gathering
- 🏭 Supply chain vendor verification

</details>

---

### ⚖️ Legal Domain (2 tools)

| Tool | API Source | Auth | Description |
|------|-----------|------|-------------|
| `NajizVerificationTool` | [developers.najiz.sa](https://developers.najiz.sa) | 🔑 API key | Verify deeds, POA, marriage contracts, judicial licenses |
| `MoJOpenDataTool` | [data.gov.sa](https://data.gov.sa) | ✅ None | Search Ministry of Justice open datasets |

<details>
<summary><strong>⚖️ Legal examples</strong></summary>

```python
from langchain_saudi_gov.tools.legal import NajizVerificationTool, MoJOpenDataTool

# Verify a real estate deed
najiz = NajizVerificationTool(api_key="your-najiz-key")
result = najiz.invoke({
    "document_number": "310100012345",
    "document_type": "deed",
})

# Verify a power of attorney
result = najiz.invoke({
    "document_number": "440100067890",
    "document_type": "power_of_attorney",
    "identity_number": "1012345678",
})

# Search judicial open data
moj = MoJOpenDataTool()
result = moj.invoke({"query": "court statistics 2024"})
```

**Use cases:**
- 🏠 Real estate transaction verification
- 📜 Legal document authentication
- ⚖️ Judicial statistics analysis
- 🤝 Power of attorney validation

</details>

---

### 💰 Finance Domain (3 tools)

| Tool | API Source | Auth | Description |
|------|-----------|------|-------------|
| `ZATCAOpenDataTool` | [data.zatca.gov.sa](https://data.zatca.gov.sa) | ✅ None | Tax, customs, and Zakat datasets |
| `CMAFinancialDataTool` | [opendata.cma.org.sa](https://opendata.cma.org.sa) | ✅ None | Capital Market Authority financial data |
| `EtimadProcurementTool` | [data.gov.sa](https://data.gov.sa) | ✅ None | Government procurement and tender data |

<details>
<summary><strong>💰 Finance examples</strong></summary>

```python
from langchain_saudi_gov.tools.finance import (
    ZATCAOpenDataTool,
    CMAFinancialDataTool,
    EtimadProcurementTool,
)

# Search ZATCA tax data
zatca = ZATCAOpenDataTool()
result = zatca.invoke({"query": "VAT collections 2024"})

# Capital markets data
cma = CMAFinancialDataTool()
result = cma.invoke({"query": "Tadawul listed companies"})

# Government procurement
etimad = EtimadProcurementTool()
result = etimad.invoke({"query": "IT infrastructure tenders"})
```

**Use cases:**
- 💵 Tax compliance research
- 📈 Stock market data analysis
- 🏦 Government spending analysis
- 📋 Tender monitoring for businesses

</details>

---

### 📊 Statistics Domain (4 tools)

| Tool | API Source | Auth | Description |
|------|-----------|------|-------------|
| `GASTATTool` | [data.gov.sa](https://data.gov.sa) | ✅ None | General Authority for Statistics datasets |
| `KAPSARCEnergyTool` | [datasource.kapsarc.org](https://datasource.kapsarc.org) | ✅ None | Oil, energy, renewables, OPEC data |
| `SaudiOpenDataSearchTool` | [data.gov.sa](https://data.gov.sa) | ✅ None | Search 11,000+ government open datasets |
| `HRSDLabourTool` | [data.gov.sa](https://data.gov.sa) | ✅ None | Labour market and social development data |

<details>
<summary><strong>📊 Statistics examples</strong></summary>

```python
from langchain_saudi_gov.tools.statistics import (
    GASTATTool,
    KAPSARCEnergyTool,
    SaudiOpenDataSearchTool,
    HRSDLabourTool,
)

# Population and economic statistics
gastat = GASTATTool()
result = gastat.invoke({"query": "population census 2024"})

# Energy and oil data
kapsarc = KAPSARCEnergyTool()
result = kapsarc.invoke({"query": "Saudi oil production OPEC"})

# Search all government datasets
opendata = SaudiOpenDataSearchTool()
result = opendata.invoke({"query": "education enrollment", "organization": "ministry-of-education"})

# Labour market
hrsd = HRSDLabourTool()
result = hrsd.invoke({"query": "Saudization employment rates"})
```

**Use cases:**
- 📈 Economic research and analysis
- ⛽ Oil & gas market intelligence
- 📚 Academic research on Saudi demographics
- 👥 Labour market insights for HR

</details>

---

### 🏭 Sector Domain (5 tools)

| Tool | API Source | Auth | Description |
|------|-----------|------|-------------|
| `HealthDataTool` | [data.gov.sa](https://data.gov.sa) | ✅ None | Ministry of Health datasets |
| `TelecomDataTool` | [data.gov.sa](https://data.gov.sa) | ✅ None | CITC telecommunications data |
| `AgricultureDataTool` | [data.gov.sa](https://data.gov.sa) | ✅ None | Agriculture and water resources data |
| `IndustrialDataTool` | [data.gov.sa](https://data.gov.sa) | ✅ None | NIIC industrial development data |
| `MonshaatSMETool` | [data.gov.sa](https://data.gov.sa) | ✅ None | SME and entrepreneurship data |

<details>
<summary><strong>🏭 Sector examples</strong></summary>

```python
from langchain_saudi_gov.tools.sector import (
    HealthDataTool,
    TelecomDataTool,
    AgricultureDataTool,
    IndustrialDataTool,
    MonshaatSMETool,
)

# Healthcare data
health = HealthDataTool()
result = health.invoke({"query": "hospital bed capacity"})

# Telecommunications
telecom = TelecomDataTool()
result = telecom.invoke({"query": "5G coverage statistics"})

# Agriculture
agri = AgricultureDataTool()
result = agri.invoke({"query": "water consumption agriculture"})

# Industrial data
industrial = IndustrialDataTool()
result = industrial.invoke({"query": "manufacturing output"})

# SME ecosystem
monshaat = MonshaatSMETool()
result = monshaat.invoke({"query": "startup funding statistics"})
```

**Use cases:**
- 🏥 Healthcare analytics and planning
- 📱 Telecom market research
- 🌾 Agricultural resource planning
- 🏭 Industrial development tracking
- 🚀 Startup ecosystem analysis

</details>

---

### 🕌 Cultural Domain (2 tools)

| Tool | API Source | Auth | Description |
|------|-----------|------|-------------|
| `PrayerTimesTool` | [api.aladhan.com](https://aladhan.com/prayer-times-api) | ✅ None | Prayer times using Umm al-Qura method (official Saudi standard) |
| `HijriDateTool` | [api.aladhan.com](https://aladhan.com/prayer-times-api) | ✅ None | Gregorian ↔ Hijri calendar conversion |

<details>
<summary><strong>🕌 Cultural examples</strong></summary>

```python
from langchain_saudi_gov.tools.cultural import PrayerTimesTool, HijriDateTool

# Prayer times for any Saudi city
prayer = PrayerTimesTool()
result = prayer.invoke({"city": "Makkah"})
# Prayer times for Makkah — 15 Jul 2025 (18 Muharram 1447)
#   Fajr:    04:28    Dhuhr:   12:27
#   Asr:     15:48    Maghrib: 19:15
#   Isha:    20:45

# With specific date
result = prayer.invoke({"city": "Medina", "date": "01-01-2025"})

# Gregorian → Hijri
hijri = HijriDateTool()
result = hijri.invoke({"date": "25-12-2024", "to_hijri": True})

# Hijri → Gregorian
result = hijri.invoke({"date": "01-07-1446", "to_hijri": False})
```

**Use cases:**
- 🕌 Prayer time reminders and scheduling
- 📅 Hijri calendar integration for apps
- 🏢 Business scheduling around prayer times
- 📰 Date conversion for document processing

</details>

---

## 🏗️ Architecture

```
langchain-saudi-gov/
├── langchain_saudi_gov/
│   ├── __init__.py              # Exports all 27 tools + SaudiGovToolkit
│   ├── toolkit.py               # Unified toolkit with domain filtering
│   ├── tools/
│   │   ├── _base.py             # WathqBaseTool & CKANBaseTool base classes
│   │   ├── location/            # Address search, reverse geocode, Balady
│   │   ├── business/            # 8 Wathq tools (CR, contracts, deeds, etc.)
│   │   ├── legal/               # Najiz verification, MoJ open data
│   │   ├── finance/             # ZATCA, CMA, Etimad
│   │   ├── statistics/          # GASTAT, KAPSARC, Open Data, HRSD
│   │   ├── sector/              # Health, Telecom, Agriculture, Industrial, SME
│   │   └── cultural/            # Prayer times, Hijri dates
│   └── utils/
│       └── arabic.py            # Arabic text normalization, language detection
├── tests/
│   ├── unit_tests/              # 116 tests, fully mocked (respx)
│   └── integration_tests/       # Live API tests
├── docs/                        # Detailed documentation
├── pyproject.toml               # Package config
├── Makefile                     # dev commands
└── LICENSE                      # MIT
```

### Base Classes

The toolkit uses two shared base classes to reduce boilerplate:

- **`WathqBaseTool`** — Shared by all 8 Wathq/Ministry of Commerce tools. Provides unified authentication (`apiKey` header), HTTP client management, and error handling (401, 404, 429 rate-limit).

- **`CKANBaseTool`** — Shared by 10+ open data tools (ZATCA, CMA, GASTAT, Health, etc.). Provides `_ckan_search()` with CKAN `package_search` API, organization filtering via `fq` parameter, and standardized result formatting.

```python
# How WathqBaseTool simplifies tool creation:
class CommercialRegistrationTool(WathqBaseTool):
    name = "saudi_commercial_registration"
    # ... just define _run() and _format()

    def _run(self, cr_number: str) -> str:
        data = self._wathq_get(f"/v5/commercialregistration/info/{cr_number}")
        return self._format(data)
```

---

## 🔑 API Keys Reference

| Service | Registration URL | Cost | Tools Enabled |
|---------|-----------------|------|---------------|
| National Address | [api.address.gov.sa](https://api.address.gov.sa) | **Free** | 2 location tools |
| Wathq | [developer.wathq.sa](https://developer.wathq.sa) | Varies by plan | 8 business tools |
| Najiz | [developers.najiz.sa](https://developers.najiz.sa) | Varies | 1 legal tool |
| All CKAN portals | No registration needed | **Free** | 14 open data tools |
| Aladhan | No registration needed | **Free** | 2 cultural tools |

### Environment variables (recommended)

```bash
export NATIONAL_ADDRESS_API_KEY="your-key-here"
export WATHQ_API_KEY="your-wathq-key"
export NAJIZ_API_KEY="your-najiz-key"
```

```python
import os
from langchain_saudi_gov import SaudiGovToolkit

toolkit = SaudiGovToolkit(
    national_address_key=os.getenv("NATIONAL_ADDRESS_API_KEY"),
    wathq_key=os.getenv("WATHQ_API_KEY"),
    najiz_key=os.getenv("NAJIZ_API_KEY"),
)
```

---

## 🌍 Real-World Use Cases

### 1. 🏢 Business Due Diligence Agent

```python
"""AI agent that performs company due diligence on Saudi companies."""

from langchain_saudi_gov import SaudiGovToolkit
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

toolkit = SaudiGovToolkit(
    wathq_key="your-key",
    domains=["business"],
)

agent = create_react_agent(
    model=ChatOpenAI(model="gpt-4o"),
    tools=toolkit.get_tools(),
)

result = agent.invoke({
    "messages": [{
        "role": "user",
        "content": (
            "Perform due diligence on CR 1010123456. "
            "Check the registration status, financial statements, "
            "employee count, and verify their chamber membership."
        ),
    }]
})
```

### 2. 📊 Saudi Economic Research Assistant

```python
"""Research assistant for Saudi economic data and Vision 2030 metrics."""

toolkit = SaudiGovToolkit(domains=["statistics", "finance"])
agent = create_react_agent(
    model=ChatOpenAI(model="gpt-4o"),
    tools=toolkit.get_tools(),
)

result = agent.invoke({
    "messages": [{
        "role": "user",
        "content": (
            "I need data on Saudi Arabia's economic diversification. "
            "Find non-oil GDP statistics, labour market Saudization rates, "
            "and recent energy production data from KAPSARC."
        ),
    }]
})
```

### 3. 🏠 Real Estate Verification Bot

```python
"""Verify real estate transactions with address and deed data."""

toolkit = SaudiGovToolkit(
    national_address_key="your-key",
    najiz_key="your-najiz-key",
    domains=["location", "legal"],
)

agent = create_react_agent(
    model=ChatOpenAI(model="gpt-4o"),
    tools=toolkit.get_tools(),
)

result = agent.invoke({
    "messages": [{
        "role": "user",
        "content": (
            "Verify the title deed 310100012345 and find the "
            "national address at coordinates 24.7136, 46.6753"
        ),
    }]
})
```

### 4. 🕌 Saudi Lifestyle Assistant

```python
"""Culturally-aware assistant for daily Saudi life."""

toolkit = SaudiGovToolkit(
    domains=["cultural", "location"],
    national_address_key="your-key",
)

agent = create_react_agent(
    model=ChatOpenAI(model="gpt-4o"),
    tools=toolkit.get_tools(),
)

# Works in Arabic
result = agent.invoke({
    "messages": [{
        "role": "user",
        "content": "ما مواقيت الصلاة اليوم في الرياض؟ وما التاريخ الهجري؟",
    }]
})
```

---

## 📋 Arabic Language Support

All tools support **bilingual Arabic and English** input and output:

| Feature | Details |
|---------|---------|
| Auto language detection | `NationalAddressSearchTool` detects Arabic vs English queries |
| Bilingual responses | APIs return data in both languages when available |
| Arabic normalization | Built-in diacritics removal, Alef normalization, Teh Marbuta handling |
| RTL-ready output | String formatting compatible with RTL display |

```python
from langchain_saudi_gov.utils.arabic import (
    normalize_arabic,
    remove_diacritics,
    detect_language,
    is_arabic,
)

normalize_arabic("الرِّيَاض")        # → "الرياض"
remove_diacritics("بِسْمِ اللَّهِ")   # → "بسم الله"
detect_language("مطار الملك خالد")   # → "A" (Arabic)
detect_language("King Khalid Airport") # → "E" (English)
is_arabic("الرياض")                  # → True
```

---

## 🧪 Development

### Setup

```bash
git clone https://github.com/fouadmahmoud283-ai/langchain-saudi-gov.git
cd langchain-saudi-gov
pip install -e ".[dev]"
```

### Commands

```bash
make test              # Run 116 unit tests (mocked, no network)
make integration_tests # Run live API tests (needs keys + network)
make lint              # Lint with ruff
make format            # Auto-format with ruff
```

### Running tests

```bash
# All unit tests
pytest tests/unit_tests -v

# Specific domain
pytest tests/unit_tests/test_business.py -v
pytest tests/unit_tests/test_cultural.py -v

# With coverage
pytest tests/unit_tests --cov=langchain_saudi_gov
```

### Project structure

```
tests/
├── unit_tests/
│   ├── test_arabic.py       # 24 tests — Arabic text normalization
│   ├── test_base.py         # 7 tests — WathqBaseTool & CKANBaseTool
│   ├── test_business.py     # 5 tests — CR, contracts, trademark, chamber
│   ├── test_cultural.py     # 6 tests — prayer times, Hijri conversion
│   ├── test_data_tools.py   # 10 tests — ZATCA, CMA, Etimad, GASTAT, KAPSARC
│   ├── test_imports.py      # 30 tests — all 28 exports importable
│   ├── test_legal.py        # 6 tests — Najiz verification, MoJ data
│   ├── test_location.py     # 8 tests — address search, reverse geocode, Balady
│   ├── test_sector.py       # 8 tests — health, telecom, agriculture, SME
│   └── test_toolkit.py      # 12 tests — toolkit config, domains, toggles
└── integration_tests/       # Live API tests (optional)
```

---

## 🔧 Configuration Reference

### SaudiGovToolkit parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `national_address_key` | `str \| None` | `None` | API key from api.address.gov.sa (free) |
| `wathq_key` | `str \| None` | `None` | Subscription key from developer.wathq.sa |
| `najiz_key` | `str \| None` | `None` | Developer API key from developers.najiz.sa |
| `include_open_data` | `bool` | `True` | Include the 14 free open data tools |
| `include_cultural` | `bool` | `True` | Include prayer times and Hijri tools |
| `domains` | `list[str] \| None` | `None` | Limit to specific domains (see below) |

### Available domains

| Domain | Key Required | Tools |
|--------|-------------|-------|
| `location` | `national_address_key` for 2, none for 1 | 3 |
| `business` | `wathq_key` | 8 |
| `legal` | `najiz_key` for 1, none for 1 | 2 |
| `finance` | None | 3 |
| `statistics` | None | 4 |
| `sector` | None | 5 |
| `cultural` | None | 2 |

---

## 📄 API Coverage

| Government Entity | Portal | Tools |
|-------------------|--------|-------|
| Saudi Post (SPL) | api.address.gov.sa | 2 |
| Ministry of Commerce (Wathq) | developer.wathq.sa | 8 |
| Ministry of Justice (Najiz) | developers.najiz.sa | 1 |
| Ministry of Justice (Open Data) | data.gov.sa | 1 |
| ZATCA (Tax & Customs) | data.zatca.gov.sa | 1 |
| Capital Market Authority | opendata.cma.org.sa | 1 |
| Etimad (Government Procurement) | data.gov.sa | 1 |
| General Authority for Statistics | data.gov.sa | 1 |
| KAPSARC (Energy Research) | datasource.kapsarc.org | 1 |
| Saudi Open Data Portal | data.gov.sa | 1 |
| HRSD (Human Resources) | data.gov.sa | 1 |
| Ministry of Health | data.gov.sa | 1 |
| CITC (Telecom) | data.gov.sa | 1 |
| Ministry of Agriculture | data.gov.sa | 1 |
| NIIC (Industrial) | data.gov.sa | 1 |
| Monshaat (SME Authority) | data.gov.sa | 1 |
| Balady (Municipal) | data.gov.sa | 1 |
| Aladhan (Islamic Services) | api.aladhan.com | 2 |
| **Total** | **12 portals** | **27 tools** |

---

## 🤝 Contributing

We welcome contributions! Whether it's adding new Saudi API integrations, improving documentation, or fixing bugs:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/new-tool`)
3. Write tests for your changes
4. Run `make lint && make test` to verify
5. Submit a pull request

See [CONTRIBUTING.md](docs/CONTRIBUTING.md) for detailed guidelines.

---

## 📄 License

MIT — see [LICENSE](LICENSE) for details.

---

## 🙏 Acknowledgments

- [LangChain](https://github.com/langchain-ai/langchain) for the tool framework
- Saudi government digital transformation teams for providing public APIs
- [Aladhan](https://aladhan.com) for the Islamic prayer times API
- [KAPSARC](https://datasource.kapsarc.org) for the energy data API

---

<div align="center">

**Built with 🤍 by [Syntera AI](https://github.com/Syntera-AI) for the Saudi developer community**

🇸🇦 *Supporting Saudi Vision 2030 through open-source AI tools*

</div>
