# ASNDB

[![Python Version](https://img.shields.io/badge/python-3.9+-FF8400)](https://www.python.org) ![PyPI - Version](https://img.shields.io/pypi/v/asndb) [![License](https://img.shields.io/badge/license-GPLv3-FF8400.svg)](https://github.com/blacklanternsecurity/radixtarget/blob/master/LICENSE) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![Tests](https://github.com/blacklanternsecurity/asndb/actions/workflows/tests.yml/badge.svg)](https://github.com/blacklanternsecurity/asndb/actions/workflows/tests.yml)

A simple Python CLI + library for instant lookup of ASN data by IP address, AS number, or organization. Uses BBOT.IO API (`asndb.api.bbot.io`).

ASNs are automatically cached for instant lookups and minimal network traffic.

## Installation

```
uv tool install asndb

# or quick run with uvx
uvx asndb

# or using pip
pip install asndb
```

## Usage (CLI)

Note: anonymous queries are limited to 10/minute. If you need more, you can purchase an API key at the [BBOT.IO Developer Portal](https://portal.api.bbot.io/). Export the key as an environment variable:
```bash
export BBOT_IO_API_KEY=<your_api_key>
```

### IP Lookup
```bash
asndb ip 1.1.1.1
```

Output:
```json
{
  "ip": "1.1.1.1",
  "asn": 13335,
  "asn_name": "CLOUDFLARENET",
  "org": "Cloudflare, Inc.",
  "org_id": "CLOUD14-ARIN",
  "country": "US",
  "rir": "ARIN",
  "subnets": null
}
```

To include subnets in the response, use the `--include-subnets` / `-s` flag:
```bash
asndb ip -s 1.1.1.1
```

Output:
```json
{
  "ip": "1.1.1.1",
  "asn": 13335,
  "asn_name": "CLOUDFLARENET",
  "org": "Cloudflare, Inc.",
  "org_id": "CLOUD14-ARIN",
  "country": "US",
  "rir": "ARIN",
  "subnets": [
    "1.0.0.0/24",
    "1.1.1.0/24",
    "..."
  ]
}
```

### AS Number Lookup

```bash
asndb asn 13335
```

### Organization Lookup

```bash
asndb org CLOUD14-ARIN
```

Output:
```json
{
  "org_id": "CLOUD14-ARIN",
  "org_name": "Cloudflare, Inc.",
  "country": "US",
  "asns": [
    {"asn": 13335, "name": "CLOUDFLARENET"},
    {"asn": 14789, "name": "CLOUDFLARENET"},
    {"asn": 394536, "name": "CLOUDFLARENET-SFO"},
    {"asn": 395747, "name": "CLOUDFLARENET-SFO05"},
    {"asn": 400095, "name": "CLOUDFLARENET"}
  ]
}
```

### Search

```bash
asndb search cloudflare
```

### CLI Help

```
$ asndb --help

 Usage: asndb [OPTIONS] COMMAND [ARGS]...

╭─ Options ──────────────────────────────────────────────────────────────────────────────────╮
│ --install-completion          Install completion for the current shell.                    │
│ --show-completion             Show completion for the current shell, to copy it or         │
│                               customize the installation.                                  │
│ --help                        Show this message and exit.                                  │
╰────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────────╮
│ ip      Lookup ASN by IP address                                                           │
│ asn     Lookup ASN by AS number                                                            │
│ org     Get all the ASNs for an organization, by its registered organization ID, e.g.      │
│         GOGL-ARIN                                                                          │
│ search  Search for ASNs by name or description                                             │
╰────────────────────────────────────────────────────────────────────────────────────────────╯
```

## Usage (Python)

```python
from asndb import ASNDB

# Create a new ASNDB client
asndb = ASNDB()

# Look up an IP address
asn = asndb.lookup_ip_sync("1.1.1.1")
# {
#   "ip": "1.1.1.1",
#   "asn": 13335,
#   "asn_name": "CLOUDFLARENET",
#   "org": "Cloudflare, Inc.",
#   "org_id": "CLOUD14-ARIN",
#   "country": "US",
#   "rir": "ARIN",
#   "subnets": null
# }

# Include subnets
asn = asndb.lookup_ip_sync("1.1.1.1", include_subnets=True)
# same as above, but with subnets populated

# Look up an AS number
asn = asndb.lookup_asn_sync(13335)

# Look up an organization
org = asndb.lookup_org_sync("CLOUD14-ARIN")
# {
#   "org_id": "CLOUD14-ARIN",
#   "org_name": "Cloudflare, Inc.",
#   "country": "US",
#   "asns": [
#     {"asn": 13335, "name": "CLOUDFLARENET"},
#     {"asn": 14789, "name": "CLOUDFLARENET"},
#     ...
#   ]
# }

# Search
results = asndb.search_sync("cloudflare")
```

## Environment Variables

You can customize the behavior of the ASNDB client by exporting the following environment variables:

- `BBOT_IO_API_KEY`: Your BBOT.IO API key.
- `ASNDB_BASE_URL`: The base URL of the ASNDB API (default: https://asndb.api.bbot.io/v1).
- `ASNDB_TIMEOUT`: The timeout for the ASNDB API requests (default: 60 seconds).
- `ASNDB_CACHE_SIZE`: The size of the cache for the ASNDB API requests (default: 10000).
