Google-RestApi

 view release on metacpan or  search on metacpan

lib/Google/RestApi.pm  view on Meta::CPAN

    timeout      => Int, { default => 120 },
    max_attempts => PositiveInt->where(sub { $_ < 10; }), { default => 4 },
  );
  $self = $check->(%$self);

  $self->{ua} = Furl->new(timeout => $self->{timeout});

  return bless $self, $class;
}

# this is the actual call to the google api endpoint. handles retries, error checking etc.
# this would normally be called via Drive or Sheets objects.
sub api {
  my $self = shift;

  state $check = compile_named(
    uri     => StrMatch[qr(^https://)],
    method  => StrMatch[qr/^(get|head|put|patch|post|delete)$/i], { default => 'get' },
    params  => HashRef[Str|ArrayRef[Str]], { default => {} },   # uri param string.
    headers => ArrayRef[Str], { default => [] },                # http headers.
    content => 0,                                               # rest payload.

lib/Google/RestApi.pm  view on Meta::CPAN

}

sub _caller_external {
  my ($package, $subroutine, $line, $i) = ('', '', 0);
  do {
    ($package, undef, $line, $subroutine) = caller(++$i);
  } while($package && $package =~ m[^(Google::RestApi|Cache|Try)]);
  return "$package:$line => $subroutine";
}

# the maximum number of attempts to call the google api endpoint before giving up.
# undef returns current value. postitive int sets and returns new value.
# 0 sets and returns default value.
sub max_attempts {
  my $self = shift;
  state $check = compile(PositiveOrZeroInt->where(sub { $_ < 10; }), { optional => 1 });
  my ($max_attempts) = $check->(@_);
  $self->{max_attempts} = $max_attempts if $max_attempts;
  $self->{max_attempts} = 4 if defined $max_attempts && $max_attempts == 0;
  return $self->{max_attempts};
}

lib/Google/RestApi.pm  view on Meta::CPAN

  $file = $drive->file(id => 'xxxx');
  $copy = $file->copy(title => 'my-copy-of-xxx');

  print YAML::Any::Dump($rest_api->stats());

=back

=head1 DESCRIPTION

Google Rest API is the foundation class used by the included Drive (L<Google::RestApi::DriveApi3>) and Sheets (L<Google::RestApi::SheetsApi4>) APIs. It is used
to send API requests to the Google API endpoint on behalf of the underlying API classes.

=head1 NAVIGATION

=over

=item * L<Google::RestApi::DriveApi3>

=item * L<Google::RestApi::DriveApi3::File>

=item * L<Google::RestApi::SheetsApi4>

lib/Google/RestApi.pm  view on Meta::CPAN

    config_file: <path_to_oauth_config_file>

This allows you the option to keep the auth file in a separate, more secure place.

=item api(%args);

The ultimate Google API call for the underlying classes. Handles timeouts and retries etc. %args consists of:

=over

=item * C<uri> <uri_string>: The Google API endpoint such as https://www.googleapis.com/drive/v3 along with any path segments added.

=item * C<method> <http_method_string>: The http method being used get|head|put|patch|post|delete.

=item * C<headers> <headers_string_array>: Array ref of http headers.

=item * C<params> <query_parameters_hash>: Http query params to be added to the uri.

=item * C<content> <payload hash>: The body being sent for post/put etc. Will be encoded to JSON.

=back

lib/Google/RestApi/DriveApi3.pm  view on Meta::CPAN

# TODO: switch to ReadOnly
use constant {
  Drive_Endpoint => "https://www.googleapis.com/drive/v3",
  Drive_File_Id  => "[a-zA-Z0-9-_]+",
};

sub new {
  my $class = shift;
  state $check = compile_named(
    api      => HasApi,
    endpoint => Str, { default => Drive_Endpoint },
  );
  return bless $check->(@_), $class;
}

sub api {
  my $self = shift;
  state $check = compile_named(
    uri     => Str, { optional => 1 },
    _extra_ => slurpy Any,
  );
  my $p = named_extra($check->(@_));
  my $uri = "$self->{endpoint}/";
  $uri .= delete $p->{uri} if defined $p->{uri};
  return $self->{api}->api(%$p, uri => $uri);
}

sub filter_files {
  my $self = shift;
  state $check = compile(Str, HashRef, { default => {} });
  my ($filter, $params) = $check->(@_);
  $params->{'q'} = $filter;
  return $self->api(params => $params, uri => 'files');
}

sub upload_endpoint {
  my $self = shift;
  my $upload = $self->{endpoint};
  $upload =~ s|googleapis.com/|googleapis.com/upload/|;
  return $upload;
}

sub file { File->new(drive => shift, @_); }

1;

__END__

lib/Google/RestApi/SheetsApi4.pm  view on Meta::CPAN

  Worksheet_Id       => "[0-9]+",
  Worksheet_Uri      => "[#&]gid=([0-9]+)",
};

sub new {
  my $class = shift;

  state $check = compile_named(
    api           => HasApi,                                           # the G::RestApi object that will be used to send http calls.
    drive         => HasMethods[qw(filter_files)], { optional => 1 },  # a drive instnace, could be your own, defaults to G::R::DriveApi3.
    endpoint      => Str, { default => Sheets_Endpoint },              # this gets tacked on to the api uri to reach the sheets endpoint.
  );
  my $self = $check->(@_);

  return bless $self, $class;
}

# this gets called by lower-level classes like worksheet and range objects. they
# will have passed thier own uri with params and possible body, we tack on the
# sheets endpoint and pass it up the line to G::RestApi to make the actual call.
sub api {
  my $self = shift;
  state $check = compile_named(
    uri     => Str, { default => '' },
    _extra_ => slurpy Any,              # just pass through any extra params to G::RestApi::api call.
  );
  my $p = named_extra($check->(@_));
  my $uri = $self->{endpoint};          # tack on the uri endpoint and pass the buck.
  $uri .= "/$p->{uri}" if $p->{uri};
  return $self->rest_api()->api(%$p, uri => $uri);
}

sub create_spreadsheet {
  my $self = shift;

  state $check = compile_named(
    title   => Str, { optional => 1 },
    name    => Str, { optional => 1 },

lib/Google/RestApi/SheetsApi4.pm  view on Meta::CPAN

=item C<api> L<<Google::RestApi>>: A reference to a configured L<Google::RestApi> instance.

=back

=item api(%args);

%args consists of:

=over

=item * C<uri> <path_segments_string>: Adds this path segment to the Sheets endpoint and calls the L<Google::RestApi>'s C<api> subroutine.

=item * C<%args>: Passes any extra arguments to the L<Google::RestApi>'s C<api> subroutine (content, params, method etc).

=back

This is essentially a pass-through method between lower-level Worksheet/Range objects and L<Google::RestApi>, where this method adds in the Sheets endpoint.
See <Google::RestApi::SheetsApi4::Worksheet>'s C<api> routine for how this is called. You would not normally call this directly unless you were making a Google API call not currently
supported by this API framework.

Returns the response hash from Google API.

=item create_spreadsheet(%args);

Creates a new spreadsheet.

%args consists of:

lib/Google/RestApi/SheetsApi4/Range.pm  view on Meta::CPAN


=back

You would not normally call this directly, you'd use Worksheet::range* methods to create the range object for you. It is recommended and safer to use
the Worksheet's methods to create ranges.

=item api(%args);

Calls the parent Worksheet's 'api' routine with the range added into the URI or content appropriately. This then get's passed to the
Spreadsheet's C<api> routine where the spreadsheet ID is tacked on to the URI. This then gets passed to the SheetsApi4's C<api>
routine where the Sheets endpoint is tacked on to the URI. This then gets passed to RestApi's api routine for actual execution.

You would not normally call this directly unless you were making a Google API call not currently supported by this API framework.

=item clear();

Clears the values using Google API's 'A1:clear' call.

=item refresh_values();

Immediately refreshes and returns the values from the spreadsheet.

lib/Google/RestApi/SheetsApi4/Spreadsheet.pm  view on Meta::CPAN

  $self = bless $self, $class;
  $self->{name} ||= $self->{title};
  delete $self->{title};

  $self->{id} || $self->{name} || $self->{uri} or LOGDIE "At least one of id, name, or uri must be specified";

  return $self;
}

# take the passed uri from worksheet/range/rangegroup etc, and tack on the spreadsheet id,
# then pass it up to G::R::SheetsApi4 which will tack on the endpoint.
sub api {
  my $self = shift;
  state $check = compile_named(
    uri     => Str, { default => '' },
    _extra_ => slurpy Any,             # we'll just pass the params/content etc up for processing.
  );
  my $p = named_extra($check->(@_));
  $p->{uri} = $self->spreadsheet_id() . $p->{uri};
  return $self->sheets_api()->api(%$p);
}

t/lib/Test/Unit/Utils.pm  view on Meta::CPAN

use File::Spec::Functions qw( catfile );
use Module::Load qw( load );

use Exporter qw(import);
our @EXPORT_OK = qw(
  fake_uri_responses_file fake_response_json_file fake_config_file fake_token_file
  fake_spreadsheet_id fake_spreadsheet_name fake_spreadsheet_name2
  fake_worksheet_id fake_worksheet_name
  fake_rest_api fake_sheets_api fake_spreadsheet_uri fake_spreadsheet
  fake_worksheet_uri fake_worksheet
  drive_endpoint sheets_endpoint
);
our %EXPORT_TAGS = (all => [ @EXPORT_OK ]);

sub fake_uri_responses_file { catfile( $FindBin::RealBin, qw(etc uri_responses), (shift . ".yaml") ); }
sub fake_response_json_file { catfile( $FindBin::RealBin, qw(etc uri_responses), (shift . ".json") ); }
sub fake_config_file { catfile($FindBin::RealBin, qw(etc rest_config.yaml)); }
sub fake_token_file { catfile($FindBin::RealBin, qw(etc rest_config.token)); }
sub fake_spreadsheet_id { 'fake_spreadsheet_id1'; }
sub fake_spreadsheet_name { 'fake_spreadsheet1'; }
sub fake_spreadsheet_name2 { 'fake_spreadsheet2'; }

t/lib/Test/Unit/Utils.pm  view on Meta::CPAN


# require these ones so that errors in them don't prevent other tests from running.
sub fake_rest_api { _load_and_new('Google::RestApi', config_file => fake_config_file(), @_); }
sub fake_sheets_api { _load_and_new('Google::RestApi::SheetsApi4', api => fake_rest_api(), @_); }
sub fake_spreadsheet { _load_and_new('Google::RestApi::SheetsApi4::Spreadsheet', sheets_api => fake_sheets_api(), id => fake_spreadsheet_id(), @_); }
sub fake_worksheet { _load_and_new('Google::RestApi::SheetsApi4::Worksheet', spreadsheet => fake_spreadsheet(), id => fake_worksheet_id(), @_); }

sub fake_spreadsheet_uri { load('Google::RestApi::SheetsApi4'); Google::RestApi::SheetsApi4->Spreadsheet_Uri . '/' . fake_spreadsheet_id(); }
sub fake_worksheet_uri { fake_spreadsheet_uri() . "&gid=" . fake_worksheet_id(); }

sub drive_endpoint { Google::RestApi::DriveApi3->Drive_Endpoint; }
sub sheets_endpoint { Google::RestApi::SheetsApi4->Sheets_Endpoint; }

sub _load_and_new {
  my $class = shift;
  load $class;
  return $class->new(@_);
}

1;

t/unit/Test/Google/RestApi/SheetsApi4.pm  view on Meta::CPAN

}

sub api : Tests(4) {
  my $self = shift;

  my $sheets_api = fake_sheets_api();
  $self->_fake_http_response();

  is_valid $sheets_api->api(), EmptyHashRef, 'Empty get';
  my $transaction = $sheets_api->rest_api()->transaction();
  is $transaction->{request}->{uri}, sheets_endpoint(), "Request base uri string is valid";

  is_valid $sheets_api->api(uri => 'x'), EmptyHashRef, 'Get with URI';
  $transaction = $sheets_api->rest_api()->transaction();
  is $transaction->{request}->{uri}, sheets_endpoint() . '/x', "Request extra uri string is valid";

  return;
}

sub spreadsheets : Tests(1) {
  my $self = shift;

  my $sheets_api = fake_sheets_api();
  $self->_fake_http_response_by_uri();

t/unit/Test/Google/RestApi/SheetsApi4/Spreadsheet.pm  view on Meta::CPAN

  return;
}

sub api : Tests(2) {
  my $self = shift;

  $self->_fake_http_response();
  my $ss = $self->_fake_spreadsheet();
  is_valid $ss->api(), EmptyHashRef, 'Empty get';
  my $transaction = $ss->rest_api()->transaction();
  is $transaction->{request}->{uri}, sheets_endpoint() . "/" . fake_spreadsheet_id(),
    'Request base spreadsheet uri string is valid';

  return;
}

sub spreadsheet_id : Tests(5) {
  my $self = shift;

  my $ss = $self->_fake_spreadsheet();
  $self->_fake_http_response(response => 'die');  # should not have to make a call.



( run in 0.425 second using v1.01-cache-2.11-cpan-2b1a40005be )