python - Google Photos API BatchRemoveMediaItems 适用于 Postman 但不适用于 Python
问题描述
我有一个脚本,它会定期将一些 Python 编辑的图像上传到 Google 相册。由于没有允许覆盖现有图像的公共 API,我必须
- 获取相册中图片的 MediaID,
- 从相册中删除它们并
- 上传新的。
脚本的上传和 GetMediaID 部分工作正常,但删除照片的脚本在 Postman 中测试时效果很好,但在 Python 中运行时,我收到 401 响应。
代码:
from GetMediaID import TACupdatemediaID, SeattleupdatemediaID, NorthupdatemediaID
import os
import pickle
from googlescript import Create_Service
import json
import requests
dir_path = os.path.join(os.getcwd())
API_NAME = 'photoslibrary'
API_VERSION = 'v1'
CLIENT_SECRET_FILE = dir_path + "\\" + "credentials.json"
print(CLIENT_SECRET_FILE)
SCOPES = ['https://www.googleapis.com/auth/photoslibrary.edit.appcreateddata',
'https://www.googleapis.com/auth/photoslibrary.sharing',
''
]
service = Create_Service(CLIENT_SECRET_FILE, API_NAME, API_VERSION, SCOPES)
#print(service.albums().list().execute())
upload_url = 'https://photoslibrary.googleapis.com/v1/albums/AIJeZ-HdakZiXwq2i2jVhw8LR4nOwHXBgPsBqYXZBt6qE61ELSGUprUkO1BVg4RJdMnzuxMotFJT:batchRemoveMediaItems'
token = pickle.load(open('token_photoslibrary_v1.pickle', 'rb'))
headers = {
'Authorization': 'Bearer ' + token.token,
'Content-type': 'application/json',
}
request_body = {
"mediaItemIds": [
SeattleupdatemediaID,
TACupdatemediaID,
NorthupdatemediaID,
]
}
r = requests.post(upload_url, json=request_body)
print(r.json)
谷歌脚本:
import pickle
import os
import datetime
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import Flow, InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
def Create_Service(client_secret_file, api_name, api_version, *scopes):
print(client_secret_file, api_name, api_version, scopes, sep='-')
CLIENT_SECRET_FILE = client_secret_file
API_SERVICE_NAME = api_name
API_VERSION = api_version
SCOPES = [scope for scope in scopes[0]]
cred = None
pickle_file = f'token_{API_SERVICE_NAME}_{API_VERSION}.pickle'
if os.path.exists(pickle_file):
with open(pickle_file, 'rb') as token:
cred = pickle.load(token)
if not cred or not cred.valid:
if cred and cred.expired and cred.refresh_token:
cred.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
cred = flow.run_local_server()
with open(pickle_file, 'wb') as token:
pickle.dump(cred, token)
try:
service = build(API_SERVICE_NAME, API_VERSION, credentials=cred)
print(API_SERVICE_NAME, 'service created successfully')
return service
except Exception as e:
print(e)
return None
def convert_to_RFC_datetime(year=1900, month=1, day=1, hour=0, minute=0):
dt = datetime.datetime(year, month, day, hour, minute, 0).isoformat() + 'Z'
return dt
解决方案
看起来好像您只包含在您的范围中
['https://www.googleapis.com/auth/photoslibrary.edit.appcreateddata',
'https://www.googleapis.com/auth/photoslibrary.sharing',
''
]
我想你得到的 401 (未经授权的 http 代码)是因为你没有删除的范围,只有appcreateddata
也许尝试添加https://www.googleapis.com/auth/photoslibrary
范围
来源:https ://developers.google.com/identity/protocols/oauth2/scopes#photoslibrary
编辑:
根据文档,您可能会遇到以下有关无效媒体项目的问题,或者有关媒体如何将其放入相册的案例(通过应用程序或作为上传的一部分 - 您是否手动推送这些媒体项目之一在你开发的时候?)。也许尝试删除媒体项目,直到你得到一个有效的。
您可以通过调用 albums.batchRemoveMediaItems 从相册中删除已添加的媒体项目。
如果指定了无效的媒体项目,整个请求将失败。不支持部分成功。
请注意,您只能删除您的应用程序已添加到相册或作为上传的一部分在相册中创建的媒体项目。对于共享的相册,如果您代表相册的所有者,则只能删除其他协作者添加的项目。
要从相册中删除媒体项目,请使用媒体项目和相册的标识符调用 albums.batchRemoveMediaItems。
我冒昧地自己尝试了这个,我能够让它发挥作用。也许以下步骤将帮助您解决删除问题,您可以从那里开始。
我首先使用Try This API来获取一些可以使用的媒体项目。我抓住了第一个以确保我 100% 拥有一个有效的 mediaId。
这是我的身份验证方法:
def get_authorized_session():
scopes = ['https://www.googleapis.com/auth/photoslibrary',
'https://www.googleapis.com/auth/photoslibrary.sharing']
cred = None
if os.path.exists('config/token.pickle'):
with open('config/token.pickle', 'rb') as token:
cred = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not cred or not cred.valid:
if cred and cred.expired and cred.refresh_token:
cred.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'config/client_id.json', scopes)
cred = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('config/token.pickle', 'wb') as token:
pickle.dump(cred, token)
session = AuthorizedSession(cred)
return session
我通过(注意 appcreatedOnly 的参数)获得了专辑 ID
def get_albums(session, appCreatedOnly=False):
params = {
'excludeNonAppCreatedData': appCreatedOnly
}
while True:
albums = session.get('https://photoslibrary.googleapis.com/v1/albums', params=params).json()
# print(f"Server response: {albums}")
if 'albums' in albums:
for a in albums["albums"]:
yield a
if 'nextPageToken' in albums:
params["pageToken"] = albums["nextPageToken"]
else:
return
else:
return
并提出以下要求:
session = get_authorized_session()
album_ids = get_albums()
album_title = 'albumtitlename'
album_id = album_ids[album_title]
request_body = {
"mediaItemIds": [
"ABg_5juBs_P76D6xYEgl3H0hZJB5n3qq1wFbGmRsl16B5dTvbNAa7G8-kxRrQZjBzGIf4SGMtpfdMRBSxEDhoy"
]
}
response = session.post(f'https://photoslibrary.googleapis.com/v1/albums/{album_id}:batchRemoveMediaItems', request_body)
print(response)
回复:
<Response [200]>
结束的想法:在我得到正确的专辑和媒体 ID 之前,我收到了 400 个错误。这使我相信您的 401 源于我链接的文档中关于如何上传您尝试删除的媒体以及根据 API 拥有该媒体的人的那些规则。
推荐阅读
- sql - 受外部查询条件约束的对象数
- amazon-web-services - 如何自动启用 Cloudformation 中指定的 ELB Cipher 策略
- reactjs - TypeError:无法读取未定义的属性(读取“原型”)
- php - 使用 Wordpress REST API 更新 JSON 文件
- r - 分离行并获得完整的数据集
- python - 无法访问 netCDF4 文件,不确定原因
- excel - 如何将列中的所有引用从绝对 excel 更改为相对 excel?
- javascript - 将加载状态应用于数组中单击的项目 - React
- python - 诗歌安装pandas mac os失败
- amazon-web-services - Sagemaker 笔记本与 Sagemaker 容器