根据cron样式部署设置发布/订阅以调用google函数,该函数将检查新数据,然后将其通过管道推送。该管道的一部分要求提交带有身份标识的授权标头的curl调用。我还没有找到生成此身份令牌的好方法。
我目前已尝试将云功能的所有者更改为对存储/数据标签/云功能具有权限的服务帐户,并且我还使用了存储的凭证文件(即access.json
)和私有文件。键。我有一个环境变量集(GOOGLE_APPLICATION_CREDENTIALS
)指向此私钥,并尝试通过$(gcloud auth application-default print-access-token)
在Google Cloud函数中提取一个身份令牌-这将返回没有错误的空字符串。
# I have tried something very similar to this
command = "echo $(gcloud auth application-default print-access-token)"
p = subprocess.Popen(command, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
p.wait()
out = p.communicate()
print("OUT_CODE: ", out)
我只是想提交带有正确获得的令牌的curl命令。
command = "GOOGLE_APPLICATION_CREDENTIALS=/user_code/dl_access.json bash -c 'gcloud auth activate-service-account --key-file=/user_code/dl_access.json; echo $(gcloud auth application-default print-access-token)'"
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
p.wait()
out, err = p.communicate()
auth = out.decode().rstrip()
print("OUT_CODE: ", out, err)
command = "curl -X POST "
command += '-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" '
command += '-H "Content-Type: application/json" '
command += 'https://datalabeling.googleapis.com/v1beta1/projects/'
command += '{}/datasets/{}/image:label '.format(PROJECT_ID, dataset.name.split("/")[-1])
command += "-d '{"
command += '"basicConfig": {'
command += '"labelGroup": "{}", '.format("test_label_group")
command += '"instruction": "{}", '.format("projects/cv/instructions/5cd5da11_0sdfgsdfgsdfg2c0b8eb8")
command += '"annotatedDatasetDisplayName": "{}", '.format(dataset.display_name)
command += '"replica_count": 3 '
command += '}, '
command += '"feature": "BOUNDING_BOX", '
command += '"boundingPolyConfig": { '
command += '"annotationSpecSet": "{}", '.format(
"projects/cv/annotationSpecSets/_b3b1_005csdfgc6_0000_297e1a11439bdc")
command += '}, '
command += "}' "
print(command)
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
p.wait()
out, err = p.communicate()
print("out:", out)
print("err:", err)
由于Authorization: Bearer <ID_Token>
是ID_Token
的空字符串,因此上述操作失败。
答案 0 :(得分:1)
您的云功能已沙盒化,您无法执行系统调用。记住,您处于无服务器模式,您不知道底层服务器是什么问题:它本身是什么?是否安装了gcloud和curl?哪个版本?...
因此,您必须编写代码并进行Python调用。检出libraries for data labeling。 如果您更喜欢直接调用API,也可以从function to function代码中获得启发。
答案 1 :(得分:1)
请勿在Cloud Functions中使用外壳程序脚本,外部命令等。
以下是在Cloud Functions中运行时如何获取OAuth 2.0身份令牌的示例。在您的真实代码中,您将需要将“受众”值更改为要调用的服务所需的任何值。如果调用此函数,它将在浏览器中显示“ SUCCESS”或“ FAILURE”。此代码还演示了如何使用Python请求库发出HTTP请求。使用此库,而不要尝试执行程序CURL。
import requests
import json
def entry(request):
id_token = requestIdentityToken('http://www.example.com')
if id_token is not None:
print('ID Token', id_token)
return f'SUCCESS'
else:
return f'FAILURE'
def requestIdentityToken(audience=None):
host = 'http://metadata.google.internal'
header = {'Metadata-Flavor': 'Google'}
if audience is None:
audience = 'http://example.com'
url = '{}/computeMetadata/v1/instance/service-accounts/default/identity?audience={}'.format(host, audience)
try:
r = requests.get(url=url, headers=header)
if r.status_code < 200 or r.status_code >= 300:
print('Error:', r.reason)
return None
return r.text
except Exception as e:
print(str(e))
return None
部署此功能的示例命令:
gcloud functions deploy requestIdentityToken --runtime python37 --trigger-http --entry-point entry
此命令将“打印”您将在Stackdriver日志中找到的用于此功能的身份令牌。
其他信息: