NAME

InternetData::Database - the licensed database downloads

SYNOPSIS

my $db = $client->database;

my $databases = $db->list;
my $id = $databases->[0]{versions}[-1]{id};      # e.g. 'bogon_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('bogon_asn_v1', 'csvgz');
my $written = $db->download($id, 'mmdb', "./$id.mmdb");

DESCRIPTION

Every call this API has, reached through "database" in InternetData. Access is granted by contract rather than self-serve, and needs a key carrying the db.download scope.

The downloads are the whole of this API today, so this namespace covers one domain rather than several. It is here because the sibling VPNDetection client spells the same seven calls the same way, and a program holding both should not have to remember which one is flat.

Every method has a _p twin returning a Mojo::Promise, and every method takes a per-call retries option. Every method but the two transfers also takes a per-call timeout in seconds, replacing the client's for each attempt of that call. Failures die with an InternetData::Error.

METHODS

FORMATS

my @formats = InternetData::Database::FORMATS;    # ('csvgz', 'mmdb')

The formats a database is published in. A method taking a $format croaks on anything else before it makes a request.

STANDINGS

my @standings = InternetData::Database::STANDINGS;    # ('licensed', 'expired', 'unlicensed')

Every standing "list" reports.

LICENSE_TYPES

my @types = InternetData::Database::LICENSE_TYPES;    # ('evaluation', 'standard', 'redistribute')

Every license_type "list" reports. A family you hold no license for carries undef instead, which is not a member.

list

my $databases = $client->database->list;

An array reference of the database families this organization may see. A license is held against a family, and each family carries every published version of itself:

{
    base => 'bogon_ip',              # what a license is held against
    name => 'Bogon IP',
    summary => 'IP ranges that cannot legitimately appear on the internet.',
    standing => 'licensed',          # licensed, expired or unlicensed
    license_type => 'standard',    # evaluation, standard, redistribute or undef
    starts => '2026-09-04T07:49:45.118Z',
    expires => undef,                # undef when the license has no end date
    renews_at => undef,              # when a rolling license next turns over
    notice_due_at => undef,          # last day to give notice for that term
    versions => [
        {
            id => 'bogon_ip_v1',     # this is what you download
            version => 1,
            summary => 'IP ranges that cannot legitimately appear on the internet.',
            formats => ['csvgz', 'mmdb'],
            sample_formats => ['csvgz'],   # an evaluation sample's; absent when none
        },
    ],
}

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

metadata($id)

One database's build document: updated, entries, per-format schema, sample and size, and sample_size and sample_entries where an evaluation sample is published. 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.

downloads(%options)

Your organization's recent download attempts, newest first, refusals included. sample is true on an attempt at the evaluation sample rather than the database itself. limit caps the number returned.

download_url($id, $format)

A time-limited URL for one file. The API answers 302 and this returns the Location without following it. The link carries its own authorization and names no credential of yours, so it is safe to hand to another process; it authorizes the START of a transfer, so one already running is not interrupted when it lapses.

download($id, $format, $path)

Streams one file to $path and returns the bytes written. Nothing beyond one chunk is ever held, whatever the database 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 database. A body that stops early is raised rather than accepted: the file is never left short and silent.

download_bytes($id, $format)

Downloads one file and returns its bytes.

This holds the entire file in memory, and the catalog spans seven orders of magnitude, from bogon_asn_v1 at 264 bytes to resproxy_ip_14d_v1 at 5.34 GiB. Reach for it at the small end, where the bytes go straight into a parser, and use download for anything you have not measured; metadata publishes the size per format without transferring anything, which is how you find out which end you are at.

TRANSFERS

download and download_bytes follow the redirect 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 - and object storage answers 400 to a presigned GET that also carries an Authorization header, so it would break the download too.

retries covers that transfer only until its first byte reaches you: object storage failing before then is retried like any server error, but a transfer that dies part way is not repeated, since a second copy would append to the bytes already written. The per-request timeout that bounds an API call is lifted for it, which is why download and download_bytes refuse a per-call timeout.

SEE ALSO

InternetData, InternetData::Error.

LICENSE

MIT. Copyright Mslm Dev.