Correct formatting to send a list in Python as a parameter to the Google Web App in order to send the data to Google Sheets
Question:
I have a Python code in which I want to pass a DataFrame Pandas as a parameter and a URL also as a parameter in my request to the Web App of Google Apps Script:
import pandas as pd
import requests
UAGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'
headers = {
'User-Agent': UAGENT
}
df = pd.DataFrame({'Col A': [1,2,3,4,5],'Col B': ['A','B','C','D','E']})
df_list = df.values.tolist()
url = 'https://stackoverflow.com'
webAppsUrl = "https://script.google.com/macros/s/XXXXXXXX/exec"
params = {
'pylist': df_list,
'okgo': url
}
web_app_response = requests.get(
webAppsUrl, headers=headers, params=params, timeout=360
)
In my Web App code I tried to send it to the spreadsheet like this:
function doGet(e) {
var pylist = e.parameter.pylist;
var sheet = SpreadsheetApp.getActive().getSheetByName('All Python');
sheet.getRange(1, 1, pylist.length, pylist[0].length).setValues(pylist);
My expected result in Google Sheets All Python
page:
1
A
2
B
3
C
4
D
5
E
But I received a Bad Request Error 400
when making the request.
In this case, what is the correct way to achieve what I want?
Answers:
From your question, I cannot know your expected result. But, I think that the reason for your current issue is due to that e.parameter.pylist
is an object. When your python request is used, e.parameter.pylist
is {"okgo":"###","pylist":"###"}
. When this value is used for setValues(pylist)
, an error like The parameters (String) don't match the method signature for SpreadsheetApp.Range.setValues.
occurs. I thought that this might be the reason for your current issue.
If you want to put the values without the error, how about the following modification?
Modified script:
In this modification, doGet
is modified as follows.
From:
var pylist = e.parameter.pylist;
To:
var header = ['pylist', 'okgo'];
var pylist = [header, header.map(h => e.parameters[h].join(","))];
or, if you want to put both keys and values in the row, how about the following modification?
var pylist = Object.entries(e.parameters).map(([k, v]) => [k, v.join(",")]);
Note:
-
When you modified the Google Apps Script of Web Apps, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful about this.
-
You can see the detail of this in my report "Redeploying Web Apps without Changing URL of Web Apps for new IDE (Author: me)".
Added:
From your updated question, the reason for your current issue is due to that e.parameter.pylist
is an object. So, how about the following modification? In this modification, df_list
is sent as a string.
Google Apps Script side:
Please modify as follows.
From:
var pylist = e.parameter.pylist;
To:
var pylist = JSON.parse(e.parameter.pylist);
Python script:
Please modify as follows.
From:
params = {
'pylist': df_list,
'okgo': url
}
To:
Please include import json
.
params = {"pylist": json.dumps(df_list), "okgo": url}
I have a Python code in which I want to pass a DataFrame Pandas as a parameter and a URL also as a parameter in my request to the Web App of Google Apps Script:
import pandas as pd
import requests
UAGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'
headers = {
'User-Agent': UAGENT
}
df = pd.DataFrame({'Col A': [1,2,3,4,5],'Col B': ['A','B','C','D','E']})
df_list = df.values.tolist()
url = 'https://stackoverflow.com'
webAppsUrl = "https://script.google.com/macros/s/XXXXXXXX/exec"
params = {
'pylist': df_list,
'okgo': url
}
web_app_response = requests.get(
webAppsUrl, headers=headers, params=params, timeout=360
)
In my Web App code I tried to send it to the spreadsheet like this:
function doGet(e) {
var pylist = e.parameter.pylist;
var sheet = SpreadsheetApp.getActive().getSheetByName('All Python');
sheet.getRange(1, 1, pylist.length, pylist[0].length).setValues(pylist);
My expected result in Google Sheets All Python
page:
1 | A |
---|---|
2 | B |
3 | C |
4 | D |
5 | E |
But I received a Bad Request Error 400
when making the request.
In this case, what is the correct way to achieve what I want?
From your question, I cannot know your expected result. But, I think that the reason for your current issue is due to that e.parameter.pylist
is an object. When your python request is used, e.parameter.pylist
is {"okgo":"###","pylist":"###"}
. When this value is used for setValues(pylist)
, an error like The parameters (String) don't match the method signature for SpreadsheetApp.Range.setValues.
occurs. I thought that this might be the reason for your current issue.
If you want to put the values without the error, how about the following modification?
Modified script:
In this modification, doGet
is modified as follows.
From:
var pylist = e.parameter.pylist;
To:
var header = ['pylist', 'okgo'];
var pylist = [header, header.map(h => e.parameters[h].join(","))];
or, if you want to put both keys and values in the row, how about the following modification?
var pylist = Object.entries(e.parameters).map(([k, v]) => [k, v.join(",")]);
Note:
-
When you modified the Google Apps Script of Web Apps, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful about this.
-
You can see the detail of this in my report "Redeploying Web Apps without Changing URL of Web Apps for new IDE (Author: me)".
Added:
From your updated question, the reason for your current issue is due to that e.parameter.pylist
is an object. So, how about the following modification? In this modification, df_list
is sent as a string.
Google Apps Script side:
Please modify as follows.
From:
var pylist = e.parameter.pylist;
To:
var pylist = JSON.parse(e.parameter.pylist);
Python script:
Please modify as follows.
From:
params = {
'pylist': df_list,
'okgo': url
}
To:
Please include import json
.
params = {"pylist": json.dumps(df_list), "okgo": url}