我已经实现了一个Web应用程序脚本,它可以执行各种操作,包括对Google Sheet进行更改,这通常需要60秒多一点的时间。
然而,尽管设置了timeout=360
或timeout=None
,我有时会在不到30秒的时间内遇到TimeoutError
:
webAppsUrl = "https://script.google.com/macros/s/xxxxxxx/exec"
web_app_response = requests.get(webAppsUrl, headers=headers, timeout=360)
if web_app_response.text == 'Done':
...
else:
print('Try Again!')
Google Apps脚本中的我的WebApp脚本:
function doGet(e) {
const lock = LockService.getDocumentLock();
if (lock.tryLock(360000)) {
try {
All_Leagues_Funct();
lock.releaseLock();
return ContentService.createTextOutput('Done');
} catch (error) {
lock.releaseLock();
const errorObj = {
message: error.message,
stack: error.stack
};
const folder = DriveApp.getFoldersByName("Error GAS").next();
const file = folder.createFile(
new Date().toString() + '.txt',
JSON.stringify(errorObj, null, 2)
);
return ContentService.createTextOutput(error);
}
} else {
return ContentService.createTextOutput('LockService Limit!');
}
}
问题是,即使我收到TimeoutError
,Web应用程序脚本仍会继续运行并对电子表格进行更改。但是,由于request
已经超时,我无法确定Web应用程序是否成功完成其操作并返回"Done"
,或者是否发生错误。
更糟糕的是,由于我已经收到了一个TimeoutError
,我不再知道Web应用程序完成的剩余时间。这种不确定性使得很难确定是否进行另一次调用以防止重复执行。
解决这种情况的最佳解决方案或变通办法是什么?
Traceback (most recent call last):
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connection.py", line 174, in _new_conn
conn = connection.create_connection(
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\util\connection.py", line 95, in create_connection
raise err
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\util\connection.py", line 85, in create_connection
sock.connect(sa)
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 703, in urlopen
httplib_response = self._make_request(
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 386, in _make_request
self._validate_conn(conn)
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 1040, in _validate_conn
conn.connect()
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connection.py", line 358, in connect
self.sock = conn = self._new_conn()
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connection.py", line 179, in _new_conn
raise ConnectTimeoutError(
urllib3.exceptions.ConnectTimeoutError: (<urllib3.connection.HTTPSConnection object at 0x000001484196FCD0>, 'Connection to script.googleusercontent.com timed out. (connect timeout=360)')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\adapters.py", line 440, in send
resp = conn.urlopen(
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 785, in urlopen
retries = retries.increment(
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\util\retry.py", line 592, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='script.googleusercontent.com', port=443): Max retries exceeded with url: /macros/echo?user_content_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001484196FCD0>, 'Connection to script.googleusercontent.com timed out. (connect timeout=360)'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "c:\Users\Computador\Desktop\Squads Python\squads_sw.py", line 539, in matches_infos
web_app_response = requests.get(url, headers=headers, timeout=360)
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\api.py", line 75, in get
return request('get', url, params=params, **kwargs)
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 529, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 667, in send
history = [resp for resp in gen]
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 667, in <listcomp>
history = [resp for resp in gen]
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 237, in resolve_redirects
resp = self.send(
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 645, in send
r = adapter.send(request, **kwargs)
File "C:\Users\Computador\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\adapters.py", line 507, in send
raise ConnectTimeout(e, request=request)
requests.exceptions.ConnectTimeout: HTTPSConnectionPool(host='script.googleusercontent.com', port=443): Max retries exceeded with url: /macros/echo?user_content_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001484196FCD0>, 'Connection to script.googleusercontent.com timed out. (connect timeout=360)'))
1条答案
按热度按时间iklwldmw1#
考虑到这种情况并不经常发生,因此可以合理地认为这可能是您或Google的连接问题。无论哪种方式,都不可能期望服务器100%可靠,因此我的建议是采取不同的方法。
你可以直接发送一个信号给服务器,让它执行操作,然后在
n
秒后检查操作是否完成。要持久化数据,你可以使用Properties Service,在这里你可以无限期地存储变量,你可以定义一个status
键来知道操作是否完成。以及用于存储时间戳、错误消息等的其他密钥。例如,您可以设置一个
doPost()
函数,当您需要更改数据时,您的Python脚本会调用该函数,然后Apps Script会设置一个status
属性in_progress
,如果它完成,则更改为Done
,如果没有,则更改为Error GAS
,然后几秒钟后,您可以从Python调用一个doGet()
,它只返回Properties,你可以分析一下,判断脚本是否做了该做的,general convention就是你需要修改数据的时候用POST
,你只需要读取的时候用GET
,现在你的脚本在浏览器打开脚本URL就可以运行了,因此,从长远来看,应用此更改可能会更好。如果您的Python脚本可以从Web上看到,您还可以考虑在完成时使用Apps Script中的
UrlFetchApp()
将POST
请求发送回Python脚本,以便它通知您。作为替代方案,您可以使用
requests.Session().get()
而不是使用requests.get()
,我理解它试图创建持久连接。我对此不是很了解,所以我真的不知道它是否会有所作为,但它可能对您有用。无论哪种方式,我推荐其他方法。