【发布时间】:2016-10-20 19:59:01
【问题描述】:
是否可以使用 Python OneDrive SDK 将文件上传到 Microsoft SharePoint 网站的 共享文档 库?
This documentation 说应该是(在第一句话中),但我不能让它工作。
我能够进行身份验证(使用 Azure AD)并上传到 OneDrive 文件夹,但是在尝试上传到 SharePoint 文件夹时,我不断收到此错误:
“引发了 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' 类型的异常。”
我正在使用的代码返回带有错误的对象:
(...authentication...)
client = onedrivesdk.OneDriveClient('https://{tenant}.sharepoint.com/{site}/_api/v2.0/', auth, http)
client.item(path='/drive/special/documents').children['test.xlsx'].upload('test.xlsx')
我可以使用以下代码成功上传到https://{tenant}-my.sharepoint.com/_api/v2.0/(注意{tenant}后面的“-my”):
client = onedrivesdk.OneDriveClient('https://{tenant}-my.sharepoint.com/_api/v2.0/', auth, http)
returned_item = client.item(drive='me', id='root').children['test.xlsx'].upload('test.xlsx')
如何将相同的文件上传到 SharePoint 网站?
(Stack Overflow 上类似问题的答案 (1,2,3,4) 要么过于模糊,要么建议使用不同的 API。我的问题是是否可以使用OneDrive Python SDK,如果是的话,怎么做。)
更新:这是我的完整代码和输出。 (敏感的原始数据替换为类似格式的乱码。)
import re
import onedrivesdk
from onedrivesdk.helpers.resource_discovery import ResourceDiscoveryRequest
# our domain (not the original)
redirect_uri = 'https://example.ourdomain.net/'
# our client id (not the original)
client_id = "a1234567-1ab2-1234-a123-ab1234abc123"
# our client secret (not the original)
client_secret = 'ABCaDEFGbHcd0e1I2fghJijkL3mn4M5NO67P8Qopq+r='
resource = 'https://api.office.com/discovery/'
auth_server_url = 'https://login.microsoftonline.com/common/oauth2/authorize'
auth_token_url = 'https://login.microsoftonline.com/common/oauth2/token'
http = onedrivesdk.HttpProvider()
auth = onedrivesdk.AuthProvider(http_provider=http, client_id=client_id,
auth_server_url=auth_server_url,
auth_token_url=auth_token_url)
should_authenticate_via_browser = False
try:
# Look for a saved session. If not found, we'll have to
# authenticate by opening the browser.
auth.load_session()
auth.refresh_token()
except FileNotFoundError as e:
should_authenticate_via_browser = True
pass
if should_authenticate_via_browser:
auth_url = auth.get_auth_url(redirect_uri)
code = ''
while not re.match(r'[a-zA-Z0-9_-]+', code):
# Ask for the code
print('Paste this URL into your browser, approve the app\'s access.')
print('Copy the resulting URL and paste it below.')
print(auth_url)
code = input('Paste code here: ')
# Parse code from URL if necessary
if re.match(r'.*?code=([a-zA-Z0-9_-]+).*', code):
code = re.sub(r'.*?code=([a-zA-Z0-9_-]*).*', r'\1', code)
auth.authenticate(code, redirect_uri, client_secret, resource=resource)
# If you have access to more than one service, you'll need to decide
# which ServiceInfo to use instead of just using the first one, as below.
service_info = ResourceDiscoveryRequest().get_service_info(auth.access_token)[0]
auth.redeem_refresh_token(service_info.service_resource_id)
auth.save_session() # Save session into a local file.
# Doesn't work
client = onedrivesdk.OneDriveClient(
'https://{tenant}.sharepoint.com/sites/{site}/_api/v2.0/', auth, http)
returned_item = client.item(path='/drive/special/documents')
.children['test.xlsx']
.upload('test.xlsx')
print(returned_item._prop_dict['error_description'])
# Works, uploads to OneDrive instead of SharePoint site
client2 = onedrivesdk.OneDriveClient(
'https://{tenant}-my.sharepoint.com/_api/v2.0/', auth, http)
returned_item2 = client2.item(drive='me', id='root')
.children['test.xlsx']
.upload('test.xlsx')
print(returned_item2.web_url)
输出:
Exception of type 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' was thrown.
https://{tenant}-my.sharepoint.com/personal/user_domain_net/_layouts/15/WopiFrame.aspx?sourcedoc=%1ABCDE2345-67F8-9012-3G45-6H78IJKL9M01%2N&file=test.xlsx&action=default
【问题讨论】:
-
你能提供完整的追溯吗?或者指定以
client或returned_item开头的行是错误的来源? -
另外,您有 set the appropriate AuthScope 的 SharePoint Online 吗?这与您的 OneDrive 权限是分开的。
-
@Gator_Python - 我添加了完整的代码。没有抛出错误,但是成功的情况下返回的对象包含上传文件的属性,不成功的情况下有这个错误信息。 AuthScope是这样设置的(其实所有权限都打勾了)。
-
我注意到,当您尝试为您的共享点库执行此操作时,您没有指定
drive。这似乎违反直觉,但共享点文档库被视为 驱动器,访问方式与访问其他 OneDrive 资源的方式相同。无论您是访问 OneDrive 还是 Sharepoint,API 操作都应该(几乎)始终处理驱动器资源。见drive resources 和list drives -
谢谢!我意识到我可以使用
onedrivesdk.OneDriveClient('https://{tenant}-my.sharepoint.com/_api/v2.0/', auth, http).drives.get()列出驱动器。它列出了一个驱动器,类型为“业务”。我假设这是 OneDrive 存储。对于没有-my的URL,我可以执行onedrivesdk.OneDriveClient('https://{tenant}.sharepoint.com/_api/v2.0/', auth, http).drive.get(),它返回一个与上面一样的错误信息(AudienceUri...)的对象。
标签: python sharepoint onedrive