one microsoft python sharepoint onedrive

python - microsoft - onedrive web service



Cargar archivo en MS SharePoint usando Python OneDrive SDK (1)

Finalmente encontré una solución, con la ayuda de sytech ( usuario de SO ).

La respuesta a mi pregunta original es que al usar el SDK original de Python OneDrive , no es posible cargar un archivo en la carpeta Shared Documents de un sitio de SharePoint Online (al momento de escribir esto): cuando el SDK consulta el servicio de descubrimiento de recursos , descarta todos los servicios cuyo service_api_version no es v2.0 . Sin embargo, obtengo el servicio de SharePoint con v1.0 , por lo que se descarta, aunque también se puede acceder usando API v2.0.

Sin embargo , al extender la clase ResourceDiscoveryRequest (en OneDrive SDK), podemos crear una solución para esto. Logré subir un archivo de esta manera:

import json import re import onedrivesdk import requests from onedrivesdk.helpers.resource_discovery import ResourceDiscoveryRequest, / ServiceInfo # 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'' # our sharepoint URL (not the original) sharepoint_base_url = ''https://{tenant}.sharepoint.com/'' # our site URL (not the original) sharepoint_site_url = sharepoint_base_url + ''sites/{site}'' file_to_upload = ''C:/test.xlsx'' target_filename = ''test.xlsx'' class AnyVersionResourceDiscoveryRequest(ResourceDiscoveryRequest): def get_all_service_info(self, access_token, sharepoint_base_url): headers = {''Authorization'': ''Bearer '' + access_token} response = json.loads(requests.get(self._discovery_service_url, headers=headers).text) service_info_list = [ServiceInfo(x) for x in response[''value'']] # Get all services, not just the ones with service_api_version ''v2.0'' # Filter only on service_resource_id sharepoint_services = / [si for si in service_info_list if si.service_resource_id == sharepoint_base_url] return sharepoint_services 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) service_info = AnyVersionResourceDiscoveryRequest()./ get_all_service_info(auth.access_token, sharepoint_base_url)[0] auth.redeem_refresh_token(service_info.service_resource_id) auth.save_session() client = onedrivesdk.OneDriveClient(sharepoint_site_url + ''/_api/v2.0/'', auth, http) # Get the drive ID of the Documents folder. documents_drive_id = [x[''id''] for x in client.drives.get()._prop_list if x[''name''] == ''Documents''][0] items = client.item(drive=documents_drive_id, id=''root'') # Upload file uploaded_file_info = items.children[target_filename].upload(file_to_upload)

La autenticación de un servicio diferente le proporciona un token diferente.

¿Es posible cargar un archivo en la biblioteca de documentos compartidos de un sitio de Microsoft SharePoint con Python OneDrive SDK ?

Esta documentación dice que debería ser (en la primera oración), pero no puedo hacer que funcione.

Puedo autenticarme (con Azure AD) y subirlo a una carpeta de OneDrive , pero cuando intento cargarlo a una carpeta de SharePoint , sigo recibiendo este error:

Se produjo una "excepción de tipo ''Microsoft.IdentityModel.Tokens. AudienceUriValidationFailedException ''".

El código que estoy usando devuelve un objeto con el error:

(...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'')

Puedo cargar con éxito a https://{tenant}-my.sharepoint.com/_api/v2.0/ (observe el " -my " después del {tenant} ) con el siguiente código:

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'')

¿Cómo podría subir el mismo archivo a un sitio de SharePoint ?

(Las respuestas a preguntas similares ( 1 , 2 , 3 , 4 ) sobre Stack Overflow son demasiado vagas o sugieren usar una API diferente. Mi pregunta es si es posible usar OneDrive Python SDK, y si es así, cómo hacerlo).

Actualización : aquí está mi código completo y salida. ( Datos originales sensibles reemplazados por galimatías formateados de forma similar. )

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)

Salida:

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