Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raku module fails to work with Google Sheets .clear API function

Apologies for the long question. I am working on the raku Net::Google::Sheets module.

Currently it does a good job of successfully using OAuth2::Client::Google and getting and putting a 2D Array from/to a Google Sheet.

I want to add a $sheet.clear method in line with the Google Sheets API.

Here is the relevant class in /lib/Net/Google/Sheets.rakumod:

class Sheet is export {
    has $.session;
    has $.id;
    has $.range;

    method url {
        "$sheet-base/{$!id}/values/{$!range}"
    }

    method clear {
        my $request = HTTP::Request.new(
            POST => ($.url ~ ':clear'),
            Authorization => "Bearer {$.session.token}",
            Content-length => 0,
        );

        $ua.request($request).decoded-content.&from-json;
    }
}

And here is the script that calls it:

#!/usr/bin/env raku 

use Net::Google::Sheets;

my $session = Session.new;
my %sheets = $session.sheets;
my $id = %sheets<AWS_EC2_Sizes_test>;

$sheet2.clear;            # <=== gives error

And here is the output and error that I am getting...

The requested URL <code>/v4/spreadsheets/{SheetId}/values/Sheet2%3Aclear</code> was not found on this server.  <ins>That’s all we know.</ins>

The Oauth access is working fine for read and write and the sheet ID is correct. I have also got a successful .clear action via the Google reference doc "Try It" box.

I suspect that there is some subtlety around gRPC that I am not following (maybe I need to encode the ':' colon character another way?).

Please can you help?


Thanks to @raiph answer, see below, the problem was that handing URI a string for the entire url means that it is all url-encoded and (as raiph points out) Google wants the colon : as is. The following code works fine:

   method uri( :$cmd ) {
        my $uri = URI.new: $sheet-url;

        my $path = "$sheet-path/{$!id}/values/{$!range}";
        $path ~= ":$cmd" if $cmd;
        $uri.path: $path;

        $uri;
    }

    method clear {
        my $cmd = 'clear';

        my $request = HTTP::Request.new(
            POST => $.uri( :$cmd ),
            Authorization => "Bearer {$.session.token}",
            Content-length => 0,
        );

        $ua.request($request).decoded-content.&from-json;
    }

Thanks for deconfusing me!

like image 536
p6steve Avatar asked Oct 16 '25 00:10

p6steve


1 Answers

You could try Raku's URI::Encode module:

"Encode and decode URI strings as defined by RFC 3986"

https://raku.land/zef:raku-community-modules/URI::Encode


Or (more directly), you could try ord and chr:

in the Raku REPL:

[0] > say "\c[COLON]".ord;
58
[0] > say "\c[COLON]".ord.chr;
:

Or just chr alone:

[0] > say "58".chr;
:

https://unix.stackexchange.com/a/746206/227738

like image 186
jubilatious1 Avatar answered Oct 17 '25 15:10

jubilatious1



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!