How to download a items from a shared folder using the onedrive api for python. Quite urgent.

Pavan Aakash Rangaraj 0 Reputation points
2024-05-28T21:52:23.55+00:00

I have a large shared file hosted on OneDrive that I want to download. The default download button is failing repeatedly to create a proper zip file so I turned to use the Python API but I am quite new to REST and Graph API.

Using the Graph Explorer with this query User's image

I found the details of the shared item. The returned field contains remoteItem, parentReference and SharePointIds fields. How can I use the info found here to get the content of the shared items and download the content to a local drive using the API's ?

Note: The hierarchy of the folder is as follows Shared_Folder -> Sub_Folders -> Items. Ideally would like to have control over which items I download, but can compromise.

I cannot use the Azure portal to register an APP to get client id's, so if this is required please also share how to register an app using powershell. Apparently my company account does not have an Azure subscription to register an app.

Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
11,253 questions
OneDrive
OneDrive
A Microsoft file hosting and synchronization service.
939 questions
SharePoint
SharePoint
A group of Microsoft Products and technologies used for sharing and managing content, knowledge, and applications.
10,151 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. RaytheonXie_MSFT 33,176 Reputation points Microsoft Vendor
    2024-05-30T02:28:44.54+00:00

    Hi @Pavan Aakash Rangaraj ,

    If you want to download large file from onedrive, I would recommend you to chunk the download with the Range header. Please refer to the following code

    const long DefaultChunkSize = 50 * 1024; // 50 KB, TODO: change chunk size to make it realistic for a large file.
    long ChunkSize = DefaultChunkSize;
    long offset = 0;         // cursor location for updating the Range header.
    byte[] bytesInStream;                    // bytes in range returned by chunk download.
    // Get the collection of drive items. We'll only use one.
    IDriveItemChildrenCollectionPage driveItems = await graphClient.Me.Drive.Root.Children.Request().GetAsync();
    foreach (var item in driveItems)
    {
        // Let's download the first file we get in the response.
        if (item.File != null)
        {
            int lastChunkSize = Convert.ToInt32(size % DefaultChunkSize) - numberOfChunks - 1; 
            if (lastChunkSize > 0) { numberOfChunks++; }
            // Create a file stream to contain the downloaded file.
            using (FileStream fileStream = System.IO.File.Create((@"C:\Temp\" + driveItemInfo.Name)))
            {
                for (int i = 0; i < numberOfChunks; i++)
                {
                    // Setup the last chunk to request. This will be called at the end of this loop.
                    if (i == numberOfChunks - 1)
                    {
                        ChunkSize = lastChunkSize;
                    }
                    // Create the request message with the download URL and Range header.
                    HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, (string)downloadUrl);
                    req.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(offset, ChunkSize + offset);
                    var client = new HttpClient();
                    HttpResponseMessage response = await client.SendAsync(req);
                    using (Stream responseStream = await response.Content.ReadAsStreamAsync())
                    {
                        bytesInStream = new byte[ChunkSize];
                        int read;
                        do
                        {
                            read = responseStream.Read(bytesInStream, 0, (int)bytesInStream.Length);
                            if (read > 0)
                                fileStream.Write(bytesInStream, 0, bytesInStream.Length);
                        }
                        while (read > 0);
                    }
                    offset += ChunkSize + 1; // Move the offset cursor to the next chunk.
                }
            }
            return;
        }
    }
    
    
    

    If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.