Python-native bindings for roto-api longest-prefix lookups
Project description
roto-api-native
roto-api-native exposes the roto-api Rust lookup engine as an installable Python package for high-volume longest-prefix ASN/prefix enrichment.
This package is an unofficial Python binding based on NLnetLabs/roto-api. It is not affiliated with or endorsed by NLnet Labs. The original project is licensed under BSD-3-Clause, and that upstream license is preserved here.
Install name:
roto-api-native
Import name:
roto_api
Overview
The package can:
- download and prepare a local routing snapshot when you explicitly call
ensure_data(...) - load that snapshot into the Rust lookup engine
- run longest-prefix lookups entirely in-process from Python
The package does not:
- install routing dumps at package install time
- fetch data on plain
import roto_api - provide the original HTTP API server
- watch upstream dumps in the background or hot-reload automatically
Install
From PyPI:
pip install roto-api-native
Build locally:
maturin build --release
$wheel = Get-ChildItem .\target\wheels\*.whl | Select-Object -First 1
python -m pip install --force-reinstall $wheel.FullName
Quick Start
One-step bootstrap and open:
from roto_api import open_lookup
lookup = open_lookup("./data")
print(lookup.lookup_ip("8.8.8.8"))
print(lookup.lookup_ips(["8.8.8.8", "1.1.1.1"]))
print(lookup.source_status())
Explicit bootstrap and later load:
from roto_api import ensure_data, load_lookup
data_dir = ensure_data("./data", refresh=False)
lookup = load_lookup(data_dir)
print(lookup.lookup_ip("8.8.8.8"))
Force a refresh:
from roto_api import open_lookup
lookup = open_lookup("./data", refresh=True)
Snapshot Layout
The convenience loaders expect a directory containing these filenames:
delegated_all.csvpfx_asn_dfz_v4.csvand/orpfx_asn_dfz_v6.csv- optional metadata files:
del_ext.timestamps.jsonriswhois.timestamps.json
If you use:
load_lookup(data_dir), orRotoLookup.from_data_dir(data_dir)
then those filenames matter. The loader does not search arbitrary names.
If you need custom filenames, use:
from roto_api import RotoLookup
lookup = RotoLookup(
prefixes_file="./custom/delegated.csv",
ris_files=["./custom/ris_v4.csv", "./custom/ris_v6.csv"],
timestamps_dir="./custom",
)
Manual File Format
If you build the snapshot yourself:
delegated_all.csv
- pipe-delimited delegated-extended records
- no header row required
- first row is treated as data
pfx_asn_dfz_v4.csv
- comma-separated
- format per row:
prefix,length,asn - example:
8.8.8.0,24,15169 - no header row required
pfx_asn_dfz_v6.csv
- comma-separated
- format per row:
prefix,length,asn - example:
2001:4860::,32,15169 - no header row required
del_ext.timestamps.json and riswhois.timestamps.json
- optional metadata files
- despite the
.jsonextension, these are CSV-formatted text files for compatibility with the original naming
Public API
ensure_data
Download and build the local routing snapshot if needed.
ensure_data(data_dir, refresh=False, del_ext_sources=None, riswhois_sources=None)
Parameters
data_dir
The directory where snapshot files and cached downloads are stored.
Type: str | os.PathLike
refresh
When enabled, re-download upstream sources and rebuild the snapshot even if the expected files already exist.
Type: bool
Default: False
del_ext_sources
Optional delegated-extended source URL overrides.
Type: Mapping[str, str] | None
Default: None
riswhois_sources
Optional RIS Whois source URL overrides.
Type: Mapping[str, str] | None
Default: None
Return value
A pathlib.Path pointing to the prepared data directory.
Exceptions
OSError
If files cannot be created, replaced, or written.
urllib.error.URLError
If an upstream download fails.
Example
from roto_api import ensure_data
data_dir = ensure_data("./data")
load_lookup
Load the native lookup engine from a prepared local data directory.
load_lookup(data_dir)
Parameters
data_dir
The path to a directory containing a prepared routing snapshot.
Required filenames:
delegated_all.csv- at least one of
pfx_asn_dfz_v4.csvorpfx_asn_dfz_v6.csv
Optional filenames:
del_ext.timestamps.jsonriswhois.timestamps.json
Type: str | os.PathLike
Return value
A RotoLookup object.
Exceptions
RuntimeError
If a required data file cannot be opened or parsed.
ValueError
If no RIS Whois CSV files are present in the data directory.
Example
from roto_api import load_lookup
lookup = load_lookup("./data")
open_lookup
Ensure the snapshot exists, then load the native lookup engine.
open_lookup(data_dir, refresh=False, del_ext_sources=None, riswhois_sources=None)
Parameters
data_dir
Target data directory used for snapshot preparation and loading.
Type: str | os.PathLike
refresh
When enabled, re-download upstream sources before loading the snapshot.
Type: bool
Default: False
del_ext_sources
Optional delegated-extended source URL overrides.
Type: Mapping[str, str] | None
Default: None
riswhois_sources
Optional RIS Whois source URL overrides.
Type: Mapping[str, str] | None
Default: None
Return value
A RotoLookup object.
Exceptions
OSError
If snapshot files cannot be created or written during preparation.
urllib.error.URLError
If an upstream download fails during preparation.
RuntimeError
If the prepared data files cannot be opened or parsed.
Example
from roto_api import open_lookup
lookup = open_lookup("./data", refresh=True)
RotoLookup
Build a lookup object from explicit file paths.
RotoLookup(prefixes_file, ris_files, timestamps_dir=None)
Parameters
prefixes_file
Path to the delegated allocations file, usually delegated_all.csv.
Type: str
ris_files
One or more RIS Whois CSV files, typically one or both of:
pfx_asn_dfz_v4.csvpfx_asn_dfz_v6.csv
Type: list[str]
timestamps_dir
Directory containing optional timestamp metadata files. Defaults to the parent directory of prefixes_file.
Type: str | None
Default: None
Return value
A RotoLookup object.
Exceptions
RuntimeError
If a required file cannot be opened or parsed.
ValueError
If ris_files is empty.
Example
from roto_api import RotoLookup
lookup = RotoLookup(
prefixes_file="./data/delegated_all.csv",
ris_files=["./data/pfx_asn_dfz_v4.csv", "./data/pfx_asn_dfz_v6.csv"],
timestamps_dir="./data",
)
RotoLookup.from_data_dir
Build a lookup object from a prepared data directory.
RotoLookup.from_data_dir(data_dir)
Parameters
data_dir
Directory containing:
delegated_all.csv- at least one of
pfx_asn_dfz_v4.csvorpfx_asn_dfz_v6.csv
May also contain:
del_ext.timestamps.jsonriswhois.timestamps.json
Type: str
Return value
A RotoLookup object.
Exceptions
RuntimeError
If the data files cannot be opened or parsed.
ValueError
If no RIS Whois CSV files are found.
Example
from roto_api import RotoLookup
lookup = RotoLookup.from_data_dir("./data")
RotoLookup.lookup_ip
Run a single-IP longest-prefix lookup.
lookup_ip(ip)
Parameters
ip
IPv4 or IPv6 address to look up.
Type: str
Return value
A dictionary with:
ipprefixorigin_asnsmatch_type
Exceptions
ValueError
If ip is not a valid IPv4 or IPv6 address.
Example
result = lookup.lookup_ip("8.8.8.8")
print(result["prefix"])
print(result["origin_asns"])
RotoLookup.lookup_ips
Run longest-prefix lookup for multiple IPs in one Rust call.
lookup_ips(ips)
Parameters
ips
IPv4 and/or IPv6 addresses to look up.
Type: list[str]
Return value
A list of dictionaries with the same schema as lookup_ip. Result order matches input order.
Exceptions
ValueError
If any input IP is invalid.
Example
results = lookup.lookup_ips(["8.8.8.8", "1.1.1.1"])
for row in results:
print(row["ip"], row["prefix"], row["origin_asns"])
RotoLookup.source_status
Return source metadata for the loaded snapshot.
source_status()
Return value
A list of dictionaries containing:
typeidseriallast_updated
If timestamp metadata files are absent, this returns an empty list.
Example
for source in lookup.source_status():
print(source["id"], source["serial"], source["last_updated"])
The detailed reference is in API.md in the source repository.
Upstream Sources
Delegated RIR files:
https://ftp.afrinic.net/pub/stats/afrinic/delegated-afrinic-extended-latesthttps://ftp.apnic.net/stats/apnic/delegated-apnic-extended-latesthttps://ftp.arin.net/pub/stats/arin/delegated-arin-extended-latesthttps://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-extended-latesthttps://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-extended-latest
RIS Whois dumps:
https://www.ris.ripe.net/dumps/riswhoisdump.IPv4.gzhttps://www.ris.ripe.net/dumps/riswhoisdump.IPv6.gz
You can override these URLs via ensure_data(...) / open_lookup(...) parameters or environment variables.
Why It Is Fast
Compared with sending one HTTP request per IP, this package avoids:
- socket I/O per lookup
- HTTP parsing and response generation
- JSON serialization/deserialization per lookup
- Python-to-server process overhead
The hot lookup path stays inside one in-process Rust engine.
Platform Support
Native wheels are platform-specific.
This repo is currently set up to publish wheels for:
- Linux x86_64
- Windows x86_64
An sdist can also be published so unsupported platforms may build locally if they have a suitable Rust toolchain.
Publishing
Release and PyPI steps are documented in PUBLISHING.md in the source repository.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file roto_api_native-0.2.3.tar.gz.
File metadata
- Download URL: roto_api_native-0.2.3.tar.gz
- Upload date:
- Size: 32.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2437bc3d2414ad7006bee5b4e379a29dd474e1a33bb70fc24c029d89a6bbdeb7
|
|
| MD5 |
acb41c19f268164ad919acd69bc86b9c
|
|
| BLAKE2b-256 |
ed062fa87c9e11d6854696fff2191a5c726bb4ffed8d1d9956c5f0885cdbf974
|
Provenance
The following attestation bundles were made for roto_api_native-0.2.3.tar.gz:
Publisher:
publish.yml on AMM48/roto-api-native
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
roto_api_native-0.2.3.tar.gz -
Subject digest:
2437bc3d2414ad7006bee5b4e379a29dd474e1a33bb70fc24c029d89a6bbdeb7 - Sigstore transparency entry: 1279589840
- Sigstore integration time:
-
Permalink:
AMM48/roto-api-native@2ab83bf5e86e6b690bbc12d9f9258b6079330db8 -
Branch / Tag:
refs/tags/v0.2.3 - Owner: https://github.com/AMM48
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2ab83bf5e86e6b690bbc12d9f9258b6079330db8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file roto_api_native-0.2.3-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: roto_api_native-0.2.3-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 268.4 kB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bf756b5679c0f9e61551e018770b751f5bf6fa7a40ddfef36d9ed632ecfdb627
|
|
| MD5 |
f21c3fd545f14a2253bfb25fd55d2456
|
|
| BLAKE2b-256 |
9dcfa634707adcb2f7252d2c26612b89345217ff7b2993eb5d634c967435e2a3
|
Provenance
The following attestation bundles were made for roto_api_native-0.2.3-cp39-abi3-win_amd64.whl:
Publisher:
publish.yml on AMM48/roto-api-native
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
roto_api_native-0.2.3-cp39-abi3-win_amd64.whl -
Subject digest:
bf756b5679c0f9e61551e018770b751f5bf6fa7a40ddfef36d9ed632ecfdb627 - Sigstore transparency entry: 1279589927
- Sigstore integration time:
-
Permalink:
AMM48/roto-api-native@2ab83bf5e86e6b690bbc12d9f9258b6079330db8 -
Branch / Tag:
refs/tags/v0.2.3 - Owner: https://github.com/AMM48
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2ab83bf5e86e6b690bbc12d9f9258b6079330db8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file roto_api_native-0.2.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: roto_api_native-0.2.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 408.9 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd08d47c3e0a61384c36955f1c86b374cf0bae27cc59d150d16630cd78fc5556
|
|
| MD5 |
103542a0cb6743645e8892714622d2d5
|
|
| BLAKE2b-256 |
398d1f42cd081b2e3a7ce2178500773ec0e12c5c22d2b36bbc6e7b90a69d30d6
|
Provenance
The following attestation bundles were made for roto_api_native-0.2.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
publish.yml on AMM48/roto-api-native
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
roto_api_native-0.2.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
dd08d47c3e0a61384c36955f1c86b374cf0bae27cc59d150d16630cd78fc5556 - Sigstore transparency entry: 1279590033
- Sigstore integration time:
-
Permalink:
AMM48/roto-api-native@2ab83bf5e86e6b690bbc12d9f9258b6079330db8 -
Branch / Tag:
refs/tags/v0.2.3 - Owner: https://github.com/AMM48
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2ab83bf5e86e6b690bbc12d9f9258b6079330db8 -
Trigger Event:
push
-
Statement type: