403 在调用 fork() 后使用 Python SDK 将数据上传到 Google 存储时出错
403 Error uploading data to Google Storage with Python SDK after calling fork()
我正在尝试在 Linux 主机 (Ubuntu 18.04) 的分叉进程中使用 Python SDK 将内容上传到 Google 存储桶
操作失败,状态码为 403:
google.api_core.exceptions.Forbidden: 403 POST https://www.googleapis.com/upload/storage/v1/b/temp-compare/o?uploadType=multipart: ('Request failed with status code', 403, 'Expected one of', )
示例代码:
import random
import string
import json
import os
import requests
from datetime import datetime, timedelta
from google.cloud import storage
def upload_to_bucket(plainText):
gcp_client = storage.Client.from_service_account_json("/path/to/google-bucket-credentials.json")
bucket = gcp_client.get_bucket('bucket_name')
bucket_file_name = random_file_name('json', 10)
blob = bucket.blob(bucket_file_name)
blob.upload_from_string(plainText)
url = blob.generate_signed_url(expiration=datetime.utcnow() + timedelta(hours=48), method="GET")
return url
def random_file_name(ext, length):
return "%s.%s" % (''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(length)), ext)
if __name__ == "__main__":
os.fork()
url = upload_to_bucket("just for test")
res = requests.get(url)
print(res.content.decode('utf8'))
我试过使用 google-api-python-client broken because of OAuth2? 中提供的解决方案,没有锁定。
如何解决?
问题似乎与 fork()
无关,而与服务帐户的身份验证有关。如果没有 fork()
,它对你有用吗?
我 运行 你的代码并设法上传和读取文件的内容,有和没有 fork()
。
为了使用服务帐户 json 密钥进行身份验证,我执行了以下操作:
- 转到控制台 -> IAM 和管理 -> 服务帐户 -> 创建服务帐户
- G运行存储 -> 存储管理员角色
- 创建密钥 (json) 并将其保存在与我的代码相同的文件夹中的文件
key.json
中
- 配置代码以通过读取该文件的密钥进行身份验证
client = storage.Client.from_service_account_json("key.json")
它奏效了。当我将服务帐户的角色更改为具有更少的权限时,它没有给我一个与您类似的错误,只是它还告诉我我使用的服务帐户没有对该存储桶的 storage.buckets.get
访问权限。
毫不奇怪,事实证明我是问题的根源。
分叉过程后,random_file_name
创建的随机文件名是相同的(可能与生成种子的方式有关)
由于该帐户没有覆盖该文件的权限,因此它收到 403 响应。
如果我将 random_file_name
更改为:
def random_file_name(ext, length):
import uuid
return str(uuid.uuid4())[0:length]+"."+ext
一切正常。
如果不是 @TasosZG 建议使用云,我可能仍在寻找解决方案 shell。
我正在尝试在 Linux 主机 (Ubuntu 18.04) 的分叉进程中使用 Python SDK 将内容上传到 Google 存储桶 操作失败,状态码为 403:
google.api_core.exceptions.Forbidden: 403 POST https://www.googleapis.com/upload/storage/v1/b/temp-compare/o?uploadType=multipart: ('Request failed with status code', 403, 'Expected one of', )
示例代码:
import random
import string
import json
import os
import requests
from datetime import datetime, timedelta
from google.cloud import storage
def upload_to_bucket(plainText):
gcp_client = storage.Client.from_service_account_json("/path/to/google-bucket-credentials.json")
bucket = gcp_client.get_bucket('bucket_name')
bucket_file_name = random_file_name('json', 10)
blob = bucket.blob(bucket_file_name)
blob.upload_from_string(plainText)
url = blob.generate_signed_url(expiration=datetime.utcnow() + timedelta(hours=48), method="GET")
return url
def random_file_name(ext, length):
return "%s.%s" % (''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(length)), ext)
if __name__ == "__main__":
os.fork()
url = upload_to_bucket("just for test")
res = requests.get(url)
print(res.content.decode('utf8'))
我试过使用 google-api-python-client broken because of OAuth2? 中提供的解决方案,没有锁定。
如何解决?
问题似乎与 fork()
无关,而与服务帐户的身份验证有关。如果没有 fork()
,它对你有用吗?
我 运行 你的代码并设法上传和读取文件的内容,有和没有 fork()
。
为了使用服务帐户 json 密钥进行身份验证,我执行了以下操作:
- 转到控制台 -> IAM 和管理 -> 服务帐户 -> 创建服务帐户
- G运行存储 -> 存储管理员角色
- 创建密钥 (json) 并将其保存在与我的代码相同的文件夹中的文件
key.json
中 - 配置代码以通过读取该文件的密钥进行身份验证
client = storage.Client.from_service_account_json("key.json")
它奏效了。当我将服务帐户的角色更改为具有更少的权限时,它没有给我一个与您类似的错误,只是它还告诉我我使用的服务帐户没有对该存储桶的 storage.buckets.get
访问权限。
毫不奇怪,事实证明我是问题的根源。
分叉过程后,random_file_name
创建的随机文件名是相同的(可能与生成种子的方式有关)
由于该帐户没有覆盖该文件的权限,因此它收到 403 响应。
如果我将 random_file_name
更改为:
def random_file_name(ext, length):
import uuid
return str(uuid.uuid4())[0:length]+"."+ext
一切正常。
如果不是 @TasosZG 建议使用云,我可能仍在寻找解决方案 shell。