使用Python OneDrive SDK将文件上载到MS SharePoint

时间:2016-10-11 15:39:01

标签: python sharepoint onedrive

是否可以使用 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')

where I'd like to upload on the web

我可以使用以下代码成功上传到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上类似问题(1234)的答案要么太模糊,要么建议使用不同的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

1 个答案:

答案 0 :(得分:3)

我终于在( SO用户)sytech的帮助下找到了解决方案。

我原来的问题的答案是,使用原来的 Python OneDrive SDK 不可能将文件上传到{{1 } Shared Documents网站的文件夹(在撰写本文时):当SDK查询resource discovery service时,它会删除SharePoint Online不是service_api_version的所有服务。但是,我使用v2.0获取SharePoint服务,因此它已被删除,尽管也可以使用API​​ v2.0访问它。

但是,通过扩展v1.0类(在OneDrive SDK中),我们可以为此创建一个解决方法。我设法以这种方式上传文件

ResourceDiscoveryRequest

对其他服务进行身份验证可为您提供不同的令牌。