API-Octopart
view release on metacpan or search on metacpan
# METHODS
- $o = API::Octopart->new(%opts) - Returns new Octopart object.
Object Options (%opt):
- token => 'abcdefg-your-octopart-token-here',
This is your Octopart API token. You could do something like this to read the token from a file:
token => (sub { my $t = `cat ~/.octopart/token`; chomp $t; return $t})->(),
- include\_specs => 1
If you have a PRO account then you can include product specs:
- cache => "$ENV{HOME}/.octopart/cache"
An optional (but recommended) cache directory to minimize requests to Octopart:
- cache\_age => 3
lib/API/Octopart.pm view on Meta::CPAN
=item * $o = API::Octopart->new(%opts) - Returns new Octopart object.
Object Options (%opt):
=over 4
=item * token => 'abcdefg-your-octopart-token-here',
This is your Octopart API token. You could do something like this to read the token from a file:
token => (sub { my $t = `cat ~/.octopart/token`; chomp $t; return $t})->(),
=item * include_specs => 1
If you have a PRO account then you can include product specs:
=item * cache => "$ENV{HOME}/.octopart/cache"
An optional (but recommended) cache directory to minimize requests to Octopart:
=item * cache_age => 3
lib/API/Octopart.pm view on Meta::CPAN
JSON response debugging. This is very verbose and dumps the Octopart response
in JSON.
=back
=cut
our %valid_opts = map { $_ => 1 } qw/token include_specs cache cache_age ua_debug query_limit json_debug/;
sub new
{
my ($class, %args) = @_;
foreach my $arg (keys %args)
{
die "invalid option: $arg => $args{$arg}" if !$valid_opts{$arg};
}
$args{api_queries} = 0;
$args{cache_age} //= 30;
lib/API/Octopart.pm view on Meta::CPAN
number is similar to those of other manufacturers.
=item * currency => <s> - eg, 'USD' for US dollars
Defaults to include all currencies
=back
=cut
sub has_stock
{
my ($self, $part, %opts) = @_;
my $parts = $self->get_part_stock_detail($part, %opts);
my $stock = 0;
foreach my $p (@$parts)
{
foreach my $s (values(%{ $p->{sellers} }))
{
lib/API/Octopart.pm view on Meta::CPAN
},
'Digi-Key' => {
'moq_price' => '0.2',
'moq' => 1,
'stock' => 10000
}
};
=cut
sub get_part_stock
{
my ($self, $part, %opts) = @_;
my $results = $self->get_part_stock_detail($part, %opts);
my %ret;
foreach my $result (@$results)
{
my $sellers = $result->{sellers};
foreach my $s (keys %$sellers)
lib/API/Octopart.pm view on Meta::CPAN
'voltagerating_dc_' => '150V',
'width' => '1.25mm',
...
}
},
...
]
=cut
sub get_part_stock_detail
{
my ($self, $part, %opts) = @_;
my $p = $self->query_part_detail($part);
return $self->_parse_part_stock($p, %opts);
}
=item * $o->octo_query($q) - Queries the Octopart API
Return the JSON response structure as a perl ARRAY/HASH given a query meeting Octopart's
API specification.
=cut
sub octo_query
{
my ($self, $q) = @_;
my $part = shift;
my ($content, $hashfile);
if ($self->{cache})
{
system('mkdir', '-p', $self->{cache}) if (! -d $self->{cache});
lib/API/Octopart.pm view on Meta::CPAN
die "query limit exceeded: $self->{api_queries} >= $self->{query_limit}";
}
$self->{api_queries}++;
if ($self->{ua_debug})
{
$ua->add_handler(
"request_send",
sub {
my $msg = shift; # HTTP::Request
print STDERR "SEND >> \n"
. $msg->headers->as_string . "\n"
. "\n";
return;
}
);
$ua->add_handler(
"response_done",
sub {
my $msg = shift; # HTTP::Response
print STDERR "RECV << \n"
. $msg->headers->as_string . "\n"
. $msg->status_line . "\n"
. "\n";
return;
}
);
}
lib/API/Octopart.pm view on Meta::CPAN
print STDERR Dumper $j;
}
return $j;
}
=item * $o->octo_query_count() - Return the number of API calls so far.
=cut
sub octo_query_count
{
my $self = shift;
return $self->{api_queries};
}
=item * $o->query_part_detail($part)
Return the JSON response structure as a perl ARRAY/HASH given a part search term
shown as "$part". This function calls $o->octo_query() with a query from Octopart's
"Basic Example" so you can easily lookup a specific part number. The has_stock()
and get_part_stock_detail() methods use this query internally.
=cut
sub query_part_detail
{
my ($self, $part) = @_;
# Specs require a pro account:
my $specs = '';
if ($self->{include_specs})
{
$specs = q(
specs {
units
lib/API/Octopart.pm view on Meta::CPAN
}
}
}
}
}
}
));
}
our %_valid_filter_opts = ( map { $_ => 1 } (qw/currency max_moq min_qty max_price mfg seller/) );
sub _parse_part_stock
{
my ($self, $resp, %opts) = @_;
foreach my $o (keys %opts)
{
die "invalid filter option: '$o'" if (!$_valid_filter_opts{$o});
}
my @results;
foreach my $r (@{ $resp->{data}{search}{results} })
xt/boilerplate.t view on Meta::CPAN
#!perl
use 5.006;
use strict;
use warnings;
use Test::More;
plan tests => 3;
sub not_in_file_ok {
my ($filename, %regex) = @_;
open( my $fh, '<', $filename )
or die "couldn't open $filename for reading: $!";
my %violated;
while (my $line = <$fh>) {
while (my ($desc, $regex) = each %regex) {
if ($line =~ $regex) {
push @{$violated{$desc}||=[]}, $.;
xt/boilerplate.t view on Meta::CPAN
}
if (%violated) {
fail("$filename contains boilerplate text");
diag "$_ appears on lines @{$violated{$_}}" for keys %violated;
} else {
pass("$filename contains no boilerplate text");
}
}
sub module_boilerplate_ok {
my ($module) = @_;
not_in_file_ok($module =>
'the great new $MODULENAME' => qr/ - The great new /,
'boilerplate description' => qr/Quick summary of what the module/,
'stub function definition' => qr/function[12]/,
);
}
TODO: {
local $TODO = "Need to replace the boilerplate text";
( run in 0.426 second using v1.01-cache-2.11-cpan-a5abf4f5562 )