Skip to content
tn3wPublic

Latest commit

 

History

77 Commits

Folders and files

Repository files navigation

plevin

Location, network and abuse information for any IP address in one offline file.
No API, no rate limit, no lookup leaving the machine.

PyPI npm License Fields Boundaries Warm

Python · JavaScript · Builder · Lookup page · API

Quick start

pip install "plevin[db,full]"               # Python
npm install plevinjs                        # Node, Deno, Bun, Workers, browsers
curl https://plevin.tn3w.dev/api/1.1.1.1    # HTTP, nothing to install
>>> import plevin
>>> found = plevin.lookup("1.1.1.1")
>>> found.place.city.name, found.network.operator.brand, found.network.cidr
('Brisbane', 'Cloudflare', '1.1.1.0/24')

>>> plevin.lookup("185.220.101.1").abuse.service
'tor_exit_node'
import { open } from "plevinjs";

const db = await open("https://plevin.tn3w.dev/db/plevin.plv");
db.lookup("1.1.1.1").network.operator.brand;   // 'Cloudflare'

Databases

One file per build, rebuilt daily. Pick the smallest one that answers your question.

build pip extra size carries
full plevin[db] 19.2 MB every field
place plevin[place] 6.3 MB city, region, postal, coordinates, metro
network plevin[network] 7.4 MB ASN, operator, routing, registry
abuse plevin[abuse] 4.2 MB abuse level, service and provider
country plevin[country] 378 KB country code

Download from the latest release, or from plevin.tn3w.dev/db with open CORS. Need another cut? plevinjs/slim rebuilds any selection in JavaScript from plevin.raw, 30 MB, with the sections the builder would write.

Fields

address to place, network and abuse
group answers
place coordinates, accuracy, city, region, district, metro, local time, country with continent, currency, calling code, languages
network ASN, handle, CIDR, registry with its country and year, RPKI, operator with address and customer cone, mobile carrier
abuse risk, level, service (Tor, VPN, proxy, relay), threat, evidence, provider, crawler and other flags
address spellings, special ranges, tunnels, embedded IPv4, no database needed
dns PTR, forward-confirmed name, SOA, DNSSEC, only when asked

A missing value is None/null, never "" or 0, and no value is given twice: an ascii name appears only where it differs from the name, expanded only for v6, a range's type only through the operator's category unless a feed names the range itself. Reserved space (private, loopback, documentation, …) answers from the address alone: no place, network or abuse. A point known only to a region or country names no town. Full reference with every field: Python · JavaScript.

Blocklist

blocklist.netset holds 619k CIDRs, 9.4 MB: every address feeds reported at 40 or above, plus every address a current list names as an anonymising service. Per-address only: no ASN-wide scores, no reserved space.

ipset create plevin hash:net
awk '!/^#/' blocklist.netset | xargs -n1 ipset add plevin

Lookup page

plevin.tn3w.dev runs the database inside the browser tab. Type an address, a hostname, an ASN (AS13335) or a network name. Only your own address and DNS questions leave the tab. Source: site/.

HTTP API

worker/ is a Cloudflare Worker answering the same JSON as the readers:

curl https://plevin.tn3w.dev/api/1.1.1.1          # any address
curl https://plevin.tn3w.dev/api/me               # the caller
curl https://plevin.tn3w.dev/api/about            # build and fields
curl "https://plevin.tn3w.dev/api/1.1.1.1?dns=1"  # with DNS
  • CORS open, no key.
  • Cached 5 min, 1 min with DNS.
  • 400 for a bad or missing address, 503 without a database.
Deploy your own
cd worker && npm install
npx wrangler kv namespace create PLEVIN   # id → KV_NAMESPACE_ID secret
npx wrangler kv key put --binding PLEVIN --remote plevin.plv --path ../plevin.plv
npx wrangler deploy

deploy-worker.yml deploys on a push to worker/ or js/ and refreshes KV on every release.

  • Secrets: KV_NAMESPACE_ID, ZONE_ID, CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN.
  • Variable: WORKER_ROUTE.
  • Token needs: Workers Scripts, Workers KV Storage and Workers Routes edit rights.
  • Smaller build: set DATABASE to a file other than plevin.plv.

Mini file

plevin_mini.py: the lookup without the package. 280 lines, standard library only. Plain dictionaries, no derived fields.

python plevin_mini.py plevin.plv 8.8.8.8

golf/: the same reader ported, one file each, standard library only, LZMA decoder included. C, C++, Rust, Go, Java, Kotlin, C#, PHP, Perl, Ruby, Lua 5.4 and Elixir.

lua golf/plevin.lua plevin.plv 8.8.8.8        # or: elixir golf/plevin.exs, ruby …
python golf/compare.py plevin.plv             # every port against plevin_mini.py
python golf/compare.py plevin.plv lua --count 50

compare.py builds each port into golf/build/, looks up fixed and seeded random v4/v6 addresses and diffs the JSON field for field. Needs the matching toolchains: gcc, g++ (C++23), rustc, go, javac, kotlinc, dotnet 10, php, perl, ruby, lua5.4, elixir.

Data

rows count
v4 boundaries 3,172,791, plus 4,841,264 host overrides
v6 boundaries 925,376
cities 81,669 in 3,220 regions
districts, metros 20,591 and 210
ASNs, networks 86,163 and 148,762 (registry holders included)
timezones 394
abuse records 7,226 from 271 feeds

Sources: MaxMind GeoLite2, IP2Location LITE, DB-IP Lite, GeoNames, Natural Earth, RIPE RIS, RPKI, NRO, RIPE/APNIC/AFRINIC/LACNIC whois, operator geofeeds, CAIDA (relationships, organisations, AS Rank), PeeringDB, asn-abuse and 271 feeds. Readers derive country facts from pycountry, Babel and phonenumbers.

Development

cd python && uv run pytest && uv run mypy && uv run basedpyright
uvx ruff check . ../plevin_mini.py --config pyproject.toml

cd ../js && npm ci && npm test && npm run lint && npm run typecheck

cd ../builder && cargo fmt --check && cargo clippy && cargo test

js/test/compare.ts checks both readers field for field; js/test/blocks.ts checks the JavaScript LZMA decoder against liblzma on every block. js/test/countries.py regenerates js/src/countries.ts from the libraries the Python full extra uses.

License

Apache 2.0 for code (LICENSE). The database carries the licenses of its sources.

Releases

Sponsor this project

Contributors

Languages