Metadata-Version: 2.4
Name: masklen
Version: 1.0.0
Summary: Official Python SDK for the masklen.dev IP intelligence API
Project-URL: Homepage, https://masklen.dev
Project-URL: Repository, https://github.com/masklen-dev/masklen-python
License: MIT
Keywords: geolocation,ip,ip-intelligence,masklen
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# masklen

Official Python SDK for the [masklen.dev](https://masklen.dev) IP intelligence API.

Look up geolocation, network, privacy, and locale data for any IPv4 or IPv6 address using a simple, zero-dependency client.

## Installation

```bash
pip install masklen
```

Requires Python 3.9 or later. No third-party dependencies.

## Quick start

### Look up your own IP

```python
from masklen import MasklenClient

client = MasklenClient(api_key="your-api-key")

result = client.lookup_self()
print(result.ip)
print(result.location.city)
print(result.location.country_code)
```

### Look up a specific IP address

```python
from masklen import MasklenClient

client = MasklenClient(api_key="your-api-key")

result = client.lookup("8.8.8.8")
print(result.ip)                    # "8.8.8.8"
print(result.network.isp)           # "Google LLC"
print(result.privacy.vpn)           # False
print(result.locale.currency)       # "USD"
```

### Look up multiple IP addresses at once

```python
from masklen import MasklenClient

client = MasklenClient(api_key="your-api-key")

batch = client.lookup_batch(["8.8.8.8", "1.1.1.1", "9.9.9.9"])
for item in batch.results:
    print(item.ip, item.location.country if item.location else "N/A")
```

## Method signatures

```python
class MasklenClient:
    def __init__(self, api_key: str, base_url: str = "https://masklen.dev") -> None: ...

    def lookup_self(self, fields: list[str] | None = None) -> LookupResult: ...
    def lookup(self, ip: str, fields: list[str] | None = None) -> LookupResult: ...
    def lookup_batch(self, ips: list[str], fields: list[str] | None = None) -> BatchResult: ...
```

## Filtering fields

All three methods accept an optional `fields` parameter. Pass a list of one or more of the following group names to limit the data returned and reduce response size:

- `"location"` -- city, region, country, coordinates, postal code, timezone
- `"network"` -- ASN, ISP, organization, domain
- `"privacy"` -- VPN, proxy, Tor, hosting flags, threat level
- `"locale"` -- currency, calling code, languages, flag

```python
# Request only location and privacy data
result = client.lookup("8.8.8.8", fields=["location", "privacy"])
print(result.location.city)     # available
print(result.network)           # None (not requested)

# Same filtering works for batch lookups
batch = client.lookup_batch(["8.8.8.8", "1.1.1.1"], fields=["network"])
```

## Error handling

API errors are raised as `MasklenError`, which extends `Exception` and carries three attributes:

- `status_code` -- HTTP status code (e.g. 401, 429)
- `error_code` -- machine-readable error identifier (e.g. `"unauthorized"`)
- `error_message` -- human-readable description

```python
from masklen import MasklenClient, MasklenError

client = MasklenClient(api_key="your-api-key")

try:
    result = client.lookup("8.8.8.8")
except MasklenError as e:
    print(e.status_code)     # 401
    print(e.error_code)      # "unauthorized"
    print(e.error_message)   # "Invalid API key."
```

### Handling batch errors

Individual items within a batch may fail without failing the whole request. Check each result's type:

```python
from masklen import MasklenClient, LookupResult, BatchItemError

client = MasklenClient(api_key="your-api-key")

batch = client.lookup_batch(["8.8.8.8", "not-an-ip"])
for item in batch.results:
    if isinstance(item, LookupResult):
        print(f"{item.ip}: {item.location.country if item.location else 'no location'}")
    elif isinstance(item, BatchItemError):
        print(f"{item.ip}: ERROR {item.error_code} -- {item.error_message}")
```

## Response models

All models are Python dataclasses with full type annotations.

```
LookupResult
  ip: str
  location: Location | None
  network: Network | None
  privacy: Privacy | None
  locale: Locale | None

Location
  city: str | None
  region: str | None
  country: str | None
  country_code: str | None
  latitude: float | None
  longitude: float | None
  postal_code: str | None
  timezone: str | None

Network
  asn: str | None
  isp: str | None
  organization: str | None
  domain: str | None

Privacy
  vpn: bool
  proxy: bool
  tor: bool
  hosting: bool
  threat_level: str    ("low" or "medium")

Locale
  currency: str | None
  currency_symbol: str | None
  calling_code: str | None
  languages: list[str]
  flag: str | None

BatchResult
  results: list[LookupResult | BatchItemError]

BatchItemError
  ip: str
  error_code: str
  error_message: str
```

## License

MIT
