NAME

VPNDetection::Database - the licensed dataset downloads

SYNOPSIS

my $db = $client->database;

my $datasets = $db->list;
my $id = $datasets->[0]{versions}[0]{id};       # e.g. 'vpn_ip_v1'

my $meta = $db->metadata($id);
my $sums = $db->checksums($id, 'mmdb');

my $url = $db->download_url($id, 'mmdb');       # transfer it yourself
my $bytes = $db->download_bytes('cdn_ip_v1', 'csvgz');
my $written = $db->download($id, 'mmdb', "./$id.mmdb");

DESCRIPTION

Access is granted by contract rather than self-serve, and needs a key carrying the db.download scope. Reached through "database" in VPNDetection.

Every method has a _p twin returning a Mojo::Promise, and every method takes a per-call retries option.

METHODS

list

An array reference of the dataset families your organization may download. A license is held against a family, and each family carries every version of itself:

{
    base => 'vpn_ip',               # what the license is held against
    name => 'VPN IP',
    summary => 'IP ranges observed as VPN infrastructure.',
    redistribution => 'internal',   # evaluation, internal or redistribute
    starts => '2026-09-04T07:49:45.118Z',
    expires => undef,               # undef when the license does not expire
    in_term => 1,                   # false once the term has ended
    standing => 'licensed',         # licensed, expired or unlicensed
    versions => [
        {
            id => 'vpn_ip_v1',      # this is what you download
            version => 1,
            summary => 'IP ranges observed as VPN infrastructure.',
            formats => [{ format => 'csvgz', bytes => 111013959 }, ...],
            sampleFormats => ['csvgz', 'mmdb'],
        },
    ],
}

The id every other method takes is $version->{id}, never $family->{base}.

metadata($id)

One dataset's document: updated, entries, per-format schema, sample and size. Poll it to decide whether today's build is worth fetching, and read $meta->{size}{$format} to size a transfer before starting it.

checksums($id, $format)

The whole digest set for one published file, as a hash reference keyed by algorithm. Which algorithms appear varies by dataset, so read the one you want off the hash rather than expecting a fixed set.

downloads(%options)

Your organization's recent download attempts, newest first. limit caps the number returned.

download_url($id, $format)

A time-limited URL for one dataset file. The API answers 302 and this returns the Location; the bytes are yours to transfer however suits a file that can run to gigabytes. The link authorizes the START of a transfer, so one already running is not interrupted when it lapses.

download($id, $format, $path)

Streams one dataset file to $path and returns the bytes written. Nothing beyond one chunk is ever held, whatever the dataset weighs.

The bytes land in a neighboring .part file that is renamed on completion, so a transfer that dies half way leaves nothing behind that reads as a whole dataset. A body that stops early is raised rather than accepted: the file is never left short and silent.

download_bytes($id, $format)

Downloads one dataset file and returns its bytes.

This holds the entire file in memory, and the catalog spans five orders of magnitude, from cdn_ip_v1 at 10 KB to resproxy_ip_90d_v1 at 1.79 GB. Reach for it at the small end, where the bytes go straight into a parser, and use download for anything you have not measured.

TRANSFERS

download_url hands out a presigned link, and download and download_bytes follow it as a second request carrying no credential: the link authorizes itself, so forwarding the API key would hand it to a host with no business holding it.

That transfer is issued exactly once. retries covers the API call that hands out the link, not a transfer that may already have moved gigabytes before it failed, and the per-request timeout that bounds a lookup is lifted for it.