Metadata-Version: 2.5
Name: unmaskip
Version: 0.1.1
Summary: IP lookup with proxy, VPN, Tor and hosting detection, powered by checkip.me
Project-URL: Homepage, https://checkip.me
Project-URL: Documentation, https://checkip.me/api
Author: checkip.me
License-Expression: MIT
License-File: LICENSE
Keywords: checkip,datacenter,fraud,geoip,hosting,ip,ip-intelligence,ip-lookup,proxy-detection,risk-score,tor,vpn-detection
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
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: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Internet
Classifier: Topic :: Security
Classifier: Topic :: System :: Networking
Classifier: Typing :: Typed
Requires-Python: >=3.9
Provides-Extra: test
Requires-Dist: pytest>=7; extra == 'test'
Description-Content-Type: text/markdown

# unmaskip

**IP lookup with proxy, VPN, Tor and hosting detection, powered by [checkip.me](https://checkip.me).**

- Geolocation, ASN, ISP, connection type (Residential / Business / Wireless / Hosting)
- Detects **proxy**, **VPN**, **Tor**, **hosting/datacenter**, compromised hosts and scrapers
- **Risk score** from 0 to 100
- No API key, **zero dependencies**, fully typed
- Built-in cache and automatic retry on rate limits
- Command-line tool included

## Install

```bash
pip install unmaskip
```

Requires Python 3.9+.

## Quick start

```python
import unmaskip

info = unmaskip.lookup("8.8.8.8")
print(info.country, info.city, info.isp)   # United States Mountain View Google LLC
print(info.type)                           # Business
print(info.risk)                           # 0-100

if info.is_vpn or info.is_proxy or info.is_tor:
    print("Masked connection")

# One-liners
unmaskip.is_vpn("1.2.3.4")
unmaskip.is_proxy("1.2.3.4")
unmaskip.is_tor("1.2.3.4")
unmaskip.is_hosting("1.2.3.4")
unmaskip.risk("1.2.3.4")

# Your own IP
unmaskip.my_ip()
unmaskip.lookup()
```

### Example: block anonymous sign-ups

```python
import unmaskip

def is_suspicious(ip: str) -> bool:
    info = unmaskip.lookup(ip)
    return info.is_masked or info.is_hosting or (info.risk or 0) >= 80
```

## The `IPInfo` object

| Field | Type | Description |
|---|---|---|
| `ip` | `str` | The IP address |
| `hostname` | `str` | Reverse DNS |
| `asn`, `isp`, `organisation` | `str` | Network owner |
| `type` | `str` | `Residential`, `Business`, `Wireless` or `Hosting` |
| `range` | `str` | Network range (CIDR) |
| `continent`, `country`, `country_code` | `str` | Location |
| `region`, `region_code` | `str` | Location |
| `city`, `postal_code` | `str` | Location |
| `latitude`, `longitude` | `float` | Coordinates |
| `timezone`, `currency` | `str` | Time zone and local currency |
| `proxy`, `vpn`, `tor`, `hosting` | `bool` | Detections |
| `compromised`, `scraper`, `anonymous` | `bool` | Detections |
| `risk` | `int` | Risk score, 0 (clean) to 100 (very risky) |
| `operator` | `str` | VPN/proxy operator, when known |
| `raw` | `dict` | Full JSON response |

Every `str`, `int` and `float` field except `ip` is `None` when the value is unknown.

Helpers: `is_proxy`, `is_vpn`, `is_tor`, `is_hosting`, `is_anonymous`, and
`is_masked` (proxy **or** VPN **or** Tor). `to_dict()` returns a plain dict.

## Client options

```python
from unmaskip import Client

client = Client(
    timeout=10.0,         # seconds per request
    cache_ttl=3600,       # cache results for 1 hour (0 disables the cache)
    cache_size=1024,      # max cached IPs
    max_retries=2,        # retries on HTTP 429
    max_retry_wait=60,    # never sleep longer than this; raise instead
)
info = client.lookup("1.1.1.1")
```

The module-level functions (`unmaskip.lookup`, `unmaskip.is_vpn`, ...) share one
default client, so their results are cached too.

## Rate limits

The free API allows **120 lookups of other IPs per hour** per client; looking
up your own IP is unlimited and cached IPs do not count. When the limit is hit,
unmaskip waits for `Retry-After` and retries. If the wait is too long, it raises
`unmaskip.RateLimitError`, whose `retry_after` attribute tells you how long to wait.

## Errors

All errors inherit from `unmaskip.UnmaskIPError`:

| Exception | When |
|---|---|
| `InvalidIPError` | Not a valid IPv4/IPv6 address (raised before any request) |
| `PrivateIPError` | Private or reserved address such as `10.0.0.1` or `127.0.0.1` |
| `RateLimitError` | HTTP 429 and the retry budget is used up |
| `NetworkError` | DNS failure, timeout, connection refused, ... |
| `APIError` | Any other unexpected response |

`InvalidIPError` and `PrivateIPError` are also `ValueError`s.

## Command line

```bash
unmaskip                       # your own IP
unmaskip 8.8.8.8 1.1.1.1       # several IPs
unmaskip 8.8.8.8 --json        # raw JSON
unmaskip 8.8.8.8 -f vpn        # one field: true / false
unmaskip 8.8.8.8 -f country    # United States
unmaskip 1.2.3.4 --strict      # exit code 3 if proxy / VPN / Tor / hosting
```

```text
$ unmaskip 8.8.8.8
IP            8.8.8.8
Hostname      dns.google
ASN           AS15169
ISP           Google LLC
Organisation  Level 3
Type          Business
Range         8.8.8.0/24
Location      Mountain View, California, United States
Timezone      America/Los_Angeles
Proxy         no
VPN           no
Tor           no
Hosting       no
Anonymous     yes
Compromised   no
Scraper       no
Risk          100/100
```

Exit codes: `0` success, `1` lookup error, `2` bad arguments, `3` flagged IP (with `--strict`).

`python -m unmaskip` works too.

## Privacy

unmaskip sends the IP addresses you look up to the checkip.me API over HTTPS,
together with a `User-Agent` header (`unmaskip/<version>`). Nothing else is
collected or sent. Results are cached only in your process memory.

## Links

- API docs: <https://checkip.me/api>
- Website: <https://checkip.me>

## License

MIT
