使用Python从个人OneDrive下载文件 [英] Download files from personal OneDrive using Python

查看:1073
本文介绍了使用Python从个人OneDrive下载文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Python脚本,该脚本在AWS EC2 Ubuntu计算机上定期运行.

此脚本从某些文件读取数据,有时会更改其中的数据.

我想从OneDrive下载这些文件,对它们进行处理,然后将它们上传回OneDrive.

我希望此操作可以自动完成,而无需用户批准任何登录名或凭据.我可以这样做一次(即在第一次运行时批准登录),但是其余的必须自动运行,而无需再次请求批准(当然,除非更改权限).

做到这一点的最佳方法是什么?

我一直在阅读Microsoft Graph API上的文档,但是我在身份验证部分苦苦挣扎.我已经在Azure AAD中创建了一个应用程序,授予了示例权限(以进行测试)并创建了一个秘密凭据.

解决方案

我设法做到了.我不确定这是否是最好的方法,但是现在可以正常工作了.它每小时自动运行一次,我不需要触摸它.

我遵循了 https://login.microsoftonline.com /common/oauth2/nativeclient

  • API权限部分中,您必须添加您的应用将使用的所有权限.我添加了 User.Read Files.ReadWrite offline_access . offline_access 是为了能够获取刷新令牌,这对于保持应用程序运行而不要求用户登录至关重要.
  • 我没有创建任何证书秘密.
  • 网络

    看起来像是第一次需要获得令牌,我们必须使用浏览器或模拟类似的东西.

    必须有一种编程的方式来执行此操作,但是我不知道如何执行此操作.我也考虑过为此使用Selenium,但是由于只有一次,而且我的应用程序每小时都会请求令牌(保持令牌新鲜),所以我放弃了这个想法.

    如果我们添加新的权限,那么我们拥有的令牌将变得无效,我们必须再次执行本手册.

    • 打开浏览器,然后转到下面的URL.使用您在Azure门户中设置的范围重定向URI .

    https://reqbin.com/.

    端点: https://登录. microsoftonline.com/common/oauth2/v2.0/token

    表单URL :grant_type = authorization_code& client_id =您的app_client_id& code = use_the_code_returned_on_previous_step

    这将返回访问令牌和刷新令牌.将刷新令牌存储在某处.我正在将其保存在文件中.

    Python

    # Build the POST parameters
    params = {
              'grant_type': 'refresh_token', 
              'client_id': your_app_client_id,
              'refresh_token': refresh_token_that_you_got_in_the_previous_step
             }
    
    response = requests.post('https://login.microsoftonline.com/common/oauth2/v2.0/token', data=params)
    
    access_token = response.json()['access_token']
    new_refresh_token = response.json()['refresh_token']
    
    # ^ Save somewhere the new refresh token. 
    # I just overwrite the file with the new one. 
    # This new one will be used next time.
    
    header = {'Authorization': 'Bearer ' + access_token}
    
    # Download the file
    response = requests.get('https://graph.microsoft.com/v1.0/me/drive/root:' +
                             PATH_TO_FILE + '/' + FILE_NAME + ':/content', headers=header)
    
    # Save the file in the disk 
    with open(file_name, 'wb') as file:
        file.write(response.content)
    

    因此,基本上,我的刷新令牌始终处于更新状态.

    我使用该刷新令牌来调用令牌端点,并且API为我提供了在当前会话期间要使用的访问令牌和新的刷新令牌.

    下次运行程序时,我将使用此新的刷新令牌,依此类推.

    I have a Python script that is running periodically on an AWS EC2 Ubuntu machine.

    This script reads data from some files and sometimes changes data in them.

    I want to download these files from OneDrive, do my own thing with them, and upload them back to OneDrive.

    I want this to be done automatically, without the need for a user to approve any login or credentials. I'm ok with doing it once (i.e. approving the login on the first run) but the rest has to run automatically, without asking ever again for approvals (unless the permissions change, of course).

    What is the best way to do this?

    I've been reading the documentation on Microsoft Graph API but I'm struggling with the authentication part. I've created an application in Azure AAD, gave the sample permissions (to test) and created a secret credential.

    解决方案

    I managed to do it. I'm not sure if it's the best way but it is working now. It's running automatically every hour and I don't need to touch it.

    I followed the information on https://docs.microsoft.com/en-gb/azure/active-directory/develop/v2-oauth2-auth-code-flow

    This is what I did.

    Azure Portal

    • Create an application. Azure Active Directory -> App Registrations -> Applications from personal account
    • In Supported account types, choose the one that has personal Microsoft accounts.
    • In Redirect URI, choose Public client/native. We'll add the specific URI later.
    • In the application details, in the section Overview, take note of the Application (client) ID. We'll need this later.
    • In the section Authentication, click Add a Platform and choose Desktop + devices. You can use your own, I chose one of the suggested: https://login.microsoftonline.com/common/oauth2/nativeclient
    • In the section API permissions, you have to add all the permissions that your app will use. I added User.Read, Files.ReadWrite and offline_access. The offline_access is to be able to get the refresh token, which will be crucial to keep the app running without asking the user to login.
    • I did not create any Certificate or Secret.

    Web

    Looks like to get a token for the first time we have to use a browser or emulate something like that.

    There must be a programmatic way to do this, but I had no idea how to do it. I also thought about using Selenium for this, but since it's only one time and my app will request tokens every hour (keeping the tokens fresh), I dropped that idea.

    If we add new permissions, the tokens that we have will become invalid and we have to do this manual part again.

    • Open a browser and go to the URL below. Use the Scopes and the Redirect URI that you set up in Azure Portal.

    https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=your_app_client_id&response_type=code&redirect_uri=https%3A%2F%2Flogin.microsoftonline.com%2Fcommon%2Foauth2%2Fnativeclient&response_mode=query&scope=User.Read%20offline_access%20Files.ReadWrite

    That URL will redirect you to the Redirect URI that you set up and with a code=something in the URL. Copy that something.

    Endpoint: https://login.microsoftonline.com/common/oauth2/v2.0/token

    Form URL: grant_type=authorization_code&client_id=your_app_client_id&code=use_the_code_returned_on_previous_step

    This will return an Access Token and a Refresh Token. Store the Refresh Token somewhere. I'm saving it in a file.

    Python

    # Build the POST parameters
    params = {
              'grant_type': 'refresh_token', 
              'client_id': your_app_client_id,
              'refresh_token': refresh_token_that_you_got_in_the_previous_step
             }
    
    response = requests.post('https://login.microsoftonline.com/common/oauth2/v2.0/token', data=params)
    
    access_token = response.json()['access_token']
    new_refresh_token = response.json()['refresh_token']
    
    # ^ Save somewhere the new refresh token. 
    # I just overwrite the file with the new one. 
    # This new one will be used next time.
    
    header = {'Authorization': 'Bearer ' + access_token}
    
    # Download the file
    response = requests.get('https://graph.microsoft.com/v1.0/me/drive/root:' +
                             PATH_TO_FILE + '/' + FILE_NAME + ':/content', headers=header)
    
    # Save the file in the disk 
    with open(file_name, 'wb') as file:
        file.write(response.content)
    

    So basically, I have the Refresh Token always updated.

    I call the Token endpoint using that Refresh Token, and the API gives me an Access Token to use during the current session and a new Refresh Token.

    I use this new Refresh Token the next time I run the program, and so on.

    这篇关于使用Python从个人OneDrive下载文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆