Metadata-Version: 2.4
Name: wxakit
Version: 1.0.0
Summary: Official Python SDK for WhoisXML API — WHOIS, DNS, IP, Security, and more.
Author-email: WhoisXML API <support@whoisxmlapi.com>
License: MIT
Project-URL: Homepage, https://www.whoisxmlapi.com
Project-URL: Documentation, https://whois.whoisxmlapi.com/documentation
Project-URL: Repository, https://github.com/whoisxmlapi/wxa-python
Project-URL: Bug Tracker, https://github.com/whoisxmlapi/wxa-python/issues
Keywords: whois,dns,ip,geolocation,security,threat-intelligence,domain
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 :: Internet
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28
Requires-Dist: urllib3>=1.26
Requires-Dist: httpx>=0.25
Requires-Dist: pydantic>=2.0
Provides-Extra: cli
Requires-Dist: typer>=0.9; extra == "cli"
Requires-Dist: rich>=13.0; extra == "cli"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: responses>=0.23; extra == "dev"
Requires-Dist: respx>=0.20; extra == "dev"
Requires-Dist: black>=23.0; extra == "dev"
Requires-Dist: ruff>=0.1; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Requires-Dist: types-requests; extra == "dev"
Requires-Dist: typer>=0.9; extra == "dev"
Requires-Dist: rich>=13.0; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

# wxa — Python SDK for WhoisXML API

[![PyPI version](https://badge.fury.io/py/wxakit.svg)](https://pypi.org/project/wxakit/)
[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

Official Python SDK for **[WhoisXML API](https://www.whoisxmlapi.com)** — the industry-leading
provider of domain, WHOIS, DNS, IP, and threat intelligence data.

## Features

- ✅ **All 25+ APIs** covered in a single package
- 🔑 **Single API key** — inject it once, use everywhere
- 🔄 **Automatic retries** on transient errors (configurable)
- 💥 **Typed exceptions** — `AuthenticationError`, `RateLimitError`, `QuotaExceededError`, etc.
- 🧵 **Thread-safe** — shared HTTP session with connection pooling
- 🐍 **Python 3.9+**, no heavyweight dependencies (just `requests`)

---

## Installation

```bash
pip install wxakit
```

---

## Quick Start

```python
from wxa import WxaClient

wxa = WxaClient(api_key="YOUR_API_KEY")

# WHOIS lookup
record = wxa.whois.get("github.com")
print(record["WhoisRecord"]["registrant"]["organization"])  # "GitHub, Inc."

# IP Geolocation
geo = wxa.ip.geolocation.get("8.8.8.8")
print(geo["location"]["country"])  # "United States"

# DNS lookup — MX records
dns = wxa.dns.lookup.get("gmail.com", record_type="MX")

# Domain availability
avail = wxa.domains.availability.get("mynewstartup2025.io")
print(avail["DomainInfo"]["domainAvailability"])  # "AVAILABLE" or "UNAVAILABLE"

# Threat intelligence
threat = wxa.security.threat_intelligence.get("suspicious-domain.xyz")
```

---

## API Reference

### Authentication

All API keys from WhoisXML API are supported.
Get yours at [whoisxmlapi.com](https://www.whoisxmlapi.com).

```python
wxa = WxaClient(
    api_key="YOUR_KEY",
    timeout=30,          # HTTP timeout in seconds (default: 30)
    max_retries=3,       # Auto-retry on 5xx / connection errors (default: 3)
    output_format="JSON" # "JSON" or "XML" (default: "JSON")
)
```

Context-manager usage (auto-closes the HTTP session):

```python
with WxaClient(api_key="YOUR_KEY") as wxa:
    result = wxa.whois.get("example.com")
```

---

### WHOIS APIs

#### `wxa.whois` — Current WHOIS

```python
# Basic lookup
record = wxa.whois.get("github.com")

# With optional parameters
record = wxa.whois.get(
    "github.com",
    da=1,                    # Include domain availability check
    ignore_raw_texts=1,      # Omit raw text blocks
    preferred_data_provider=0,  # 0=auto, 1=RDAP only, 2=WHOIS only
)
```

#### `wxa.whois_bulk` — Bulk WHOIS

```python
# Submit a job
job = wxa.whois_bulk.create(["github.com", "google.com", "example.com"])
request_id = job["requestId"]

# Poll status
status = wxa.whois_bulk.get_status(request_id)

# Retrieve records
results = wxa.whois_bulk.get_records(request_id)

# Download CSV
csv_info = wxa.whois_bulk.download_csv(request_id)
```

#### `wxa.whois_reverse` — Reverse WHOIS

```python
results = wxa.whois_reverse.search(
    terms=[{"field": "RegistrantContact.Email", "term": "admin@example.com"}],
    mode="purchase",  # "preview" for free count
)
```

#### `wxa.whois_history` — WHOIS History

```python
history = wxa.whois_history.get(
    "github.com",
    mode="purchase",
    created_date_from="2010-01-01",
    created_date_to="2020-01-01",
)
```

#### `wxa.domain_info` — Domain Info (enriched WHOIS)

```python
info = wxa.domain_info.get("github.com")
```

---

### DNS APIs

#### `wxa.dns.lookup` — DNS Records

```python
# Supports type names or numeric codes
a_records   = wxa.dns.lookup.get("github.com", record_type="A")
mx_records  = wxa.dns.lookup.get("gmail.com",  record_type="MX")
ns_records  = wxa.dns.lookup.get("amazon.com", record_type="NS")
txt_records = wxa.dns.lookup.get("example.com", record_type="TXT")
all_records = wxa.dns.lookup.get("example.com", record_type="ANY")
```

Supported types: `A`, `NS`, `CNAME`, `SOA`, `MX`, `TXT`, `AAAA`, `SRV`, `DS`, `DNSKEY`, `ANY`
and all other standard DNS types by numeric code.

#### `wxa.dns.chronicle` — Historical DNS

```python
# By domain
history = wxa.dns.chronicle.get("example.com", record_type="A")

# By IP
history = wxa.dns.chronicle.get(ip_address="93.184.216.34")
```

#### `wxa.dns.reverse_dns` — Reverse DNS (PTR)

```python
ptr = wxa.dns.reverse_dns.get("8.8.8.8")
```

#### `wxa.dns.reverse_ip` — Domains on an IP

```python
domains = wxa.dns.reverse_ip.get("93.184.216.34")
```

#### `wxa.dns.reverse_mx` — Domains using an MX server

```python
domains = wxa.dns.reverse_mx.get("mail.example.com")
```

#### `wxa.dns.reverse_ns` — Domains using a nameserver

```python
domains = wxa.dns.reverse_ns.get("ns1.cloudflare.com")
```

#### `wxa.dns.subdomains` — Subdomains Lookup

```python
subs = wxa.dns.subdomains.get("github.com", max_count=500)
```

---

### IP Intelligence APIs

#### `wxa.ip.geolocation` — Single IP Geolocation

```python
geo = wxa.ip.geolocation.get("8.8.8.8")
# Returns: city, country, lat/lng, ISP, ASN, timezone, connection type, ...
```

#### `wxa.ip.bulk_geolocation` — Bulk IP Geolocation

```python
results = wxa.ip.bulk_geolocation.get(["8.8.8.8", "1.1.1.1", "208.67.222.222"])
```

#### `wxa.ip.netblocks` — IP Netblocks WHOIS

```python
# By IP (with optional CIDR mask)
netblock = wxa.ip.netblocks.get_by_ip("8.8.8.0", mask=24)

# By ASN
netblocks = wxa.ip.netblocks.get_by_asn("AS15169")

# By organization
netblocks = wxa.ip.netblocks.get_by_org("Google LLC")
```

---

### Domain APIs

#### `wxa.domains.availability` — Domain Availability

```python
check = wxa.domains.availability.get("mynewstartup.io")
is_available = check["DomainInfo"]["domainAvailability"] == "AVAILABLE"
```

#### `wxa.domains.discovery` — Domains & Subdomains Discovery

```python
results = wxa.domains.discovery.search(
    domains_include=["shop", "store"],
    domains_exclude=["adult"],
    date_from="2024-01-01",
    date_to="2024-12-31",
)
```

---

### Security APIs

#### `wxa.security.categorization` — Website Categorization

```python
cats = wxa.security.categorization.get("github.com")
# Returns IAB content categories for the domain
```

#### `wxa.security.reputation` — Domain Reputation

```python
rep = wxa.security.reputation.get("github.com", mode=0)
# mode=0: fast, mode=1: full analysis
score = rep["reputationScore"]  # 0–100, higher = more trusted
```

#### `wxa.security.brand_alert` — Brand Alert

```python
alerts = wxa.security.brand_alert.search(
    include_terms=["apple", "iphone"],
    exclude_terms=["snapple"],
    since_date="2024-01-01",
    with_typos=True,
    mode="purchase",
)
```

#### `wxa.security.registrant_alert` — Registrant Alert

```python
alerts = wxa.security.registrant_alert.search(
    include_terms=[{"field": "RegistrantContact.Organization", "term": "Evil Corp"}],
    mode="preview",
)
```

#### `wxa.security.threat_intelligence` — Threat Intelligence

```python
ioc = wxa.security.threat_intelligence.get("suspicious.example.com")
ioc = wxa.security.threat_intelligence.get("192.0.2.1")  # Also works with IPs
```

#### `wxa.security.first_watch` — First Watch Feed

```python
feed = wxa.security.first_watch.get(date="2024-06-01")
```

#### `wxa.security.typosquatting` — Typosquatting

```python
variants = wxa.security.typosquatting.get("github.com")
# Returns domain variants (gogithub.com, guthub.com, etc.)
```

---

### Email APIs

#### `wxa.email.verify` — Email Verification

```python
result = wxa.email.verify.get(
    "user@example.com",
    smtp_check=1,
    catch_all_check=1,
    free_email_check=1,
)
is_valid = result["smtpCheck"] == "true"
```

#### `wxa.email.bulk_verify` — Bulk Email Verification

```python
# Submit
job = wxa.email.bulk_verify.create(["user1@example.com", "user2@example.com"])
request_id = job["requestId"]

# Check status
status = wxa.email.bulk_verify.get_status(request_id)

# Retrieve results
results = wxa.email.bulk_verify.get_records(request_id)
```

---

### Utility APIs

#### `wxa.misc.mac_address` — MAC Address Lookup

```python
vendor = wxa.misc.mac_address.get("00:1A:2B:3C:4D:5E")
print(vendor["vendorDetails"]["companyName"])
```

#### `wxa.misc.screenshot` — Website Screenshot

```python
shot = wxa.misc.screenshot.get(
    "https://github.com",
    width=1280,
    height=800,
    full_page=1,
    image_output_format="png",
)
url = shot["screenshotPath"]
```

#### `wxa.misc.ssl_certificates` — SSL Certificates

```python
certs = wxa.misc.ssl_certificates.get(
    "github.com",
    from_date="2023-01-01",
    show_fingerprints=1,
)
```

---

## Error Handling

```python
from wxa import (
    WxaClient,
    WxaError,
    AuthenticationError,
    RateLimitError,
    QuotaExceededError,
    InvalidParameterError,
    NotFoundError,
    ServerError,
    TimeoutError,
)

wxa = WxaClient(api_key="YOUR_KEY")

try:
    result = wxa.whois.get("github.com")
except AuthenticationError:
    print("Invalid API key")
except RateLimitError as e:
    print(f"Rate limited — retry after {e.retry_after}s")
except QuotaExceededError:
    print("Account query quota exhausted")
except ServerError as e:
    print(f"Server error {e.status_code}")
except WxaError as e:
    print(f"Unexpected error: {e}")
```

---

## Response Format

All methods return the raw parsed JSON response as a Python `dict`, giving you
direct access to all fields documented in the WhoisXML API docs.
Use `output_format="XML"` on the client if you need XML strings instead.

---

## Development

```bash
git clone https://github.com/whoisxmlapi/wxa-python
cd wxa-python
pip install -e ".[dev]"

# Run tests
pytest

# Lint
ruff check src/
black --check src/
```

---

## License

MIT — see [LICENSE](LICENSE).
