如何在google ml api python客户端设置请求超时?

时间:2018-02-25 00:43:32

标签: python gcloud google-cloud-ml

我正在谷歌云机器学习API上运行在线预测,使用谷歌api python客户端和谷歌云托管的模型。 当我预测发送一个图像时,服务器(包括所有流量)大约需要40秒。当我发送两张图片时,一段时间后,我会收到消息:

timeout: The read operation timed out

我想将超时设置为其他值,但我没有找到。

这是我的代码:

import base64
import io
import time
from PIL import Image    

from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient import discovery

SCOPES = ['https://www.googleapis.com/auth/cloud-platform']
SERVICE_ACCOUNT_FILE = 'mycredentialsfile.json'

credentials = ServiceAccountCredentials.from_json_keyfile_name(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

ml = discovery.build('ml', 'v1', credentials=credentials)

projectID = 'projects/{}'.format('projectID') + '/models/{}'.format('modelID')

width = 640
height = 480

instances = []

for image in ["image5.jpg", "image6.jpg"]:
    img = Image.open(image)
    img = img.resize((width, height), Image.ANTIALIAS)
    output_str = io.BytesIO()
    img.save(output_str, "JPEG")
    instance = {"b64": base64.b64encode(output_str.getvalue()).decode("utf-8") }
    output_str.close()
    instances.append(instance)  

input_json = {"instances": instances }

request = ml.projects().predict(body=input_json, name=projectID)

print("Starting prediction")
start_time = time.time()
response = request.execute()

print("%s seconds" % (time.time() - start_time))

3 个答案:

答案 0 :(得分:3)

我找到了一种研究github上google api python客户端的样本并尝试相同更改的方法。

使用httplib2进行身份验证可以设置超时。

遵循修改后的代码:

import base64
import io
import time
from PIL import Image

# Need: pip install google-api-python-client

import httplib2
from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient import discovery

SCOPES = ['https://www.googleapis.com/auth/cloud-platform']
# API & Services -> Credentials -> Create Credential -> service account key
SERVICE_ACCOUNT_FILE = 'mycredentialsfile.json'

credentials = ServiceAccountCredentials.from_json_keyfile_name(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

http = httplib2.Http(timeout=200)
http = credentials.authorize(http)

ml = discovery.build('ml', 'v1', http=http)

projectID = 'projects/{}'.format('projectID ') + '/models/{}'.format('modelID')

width = 640
height = 480

instances = []

for image in ["image5.jpg", "image6.jpg"]:
    img = Image.open(image)
    img = img.resize((width, height), Image.ANTIALIAS)
    output_str = io.BytesIO()
    img.save(output_str, "JPEG")
    instance = {"b64": base64.b64encode(output_str.getvalue()).decode("utf-8") }
    output_str.close()
    instances.append(instance)  

input_json = {"instances": instances }

request = ml.projects().predict(body=input_json, name=projectID)

print("Starting prediction")
start_time = time.time()
response = request.execute()

print("%s seconds" % (time.time() - start_time))

我认为通过一些修改,你可以使用它来设置python客户端中几乎任何谷歌云API的超时。

我希望这会有所帮助。

答案 1 :(得分:2)

您已经解决了问题,但是我找到了另一种方法。

import socket    
socket.setdefaulttimeout(150)

如果在没有http的情况下调用discovery.build,则build_http将以build方法实例化http客户端。

https://googleapis.github.io/google-api-python-client/docs/epy/googleapiclient.http-pysrc.html#build_http

如您在此处看到的,build_http创建一个带有超时的http客户端实例(如果在创建http客户端之前设置了超时)。

因此您所要做的就是通过socket.setdefaulttimeout设置此值:)

答案 2 :(得分:1)

是的。我同意Shohei的上述回答。我花了一段时间才找到这个简单而优雅的解决方案。您只需要在代码中添加以下内容

import socket
timeout_in_sec = 60*3 # 3 minutes timeout limit
socket.setdefaulttimeout(timeout_in_sec)

# then you could create your ML service object as usually, and it will have the extended timeout limit.
ml_service = discovery.build('ml', 'v1')