Upload session for uploading large attachments, no response

Amr Elagaty 21 Reputation points
2022-04-14T16:30:21.38+00:00

I am trying to upload a large attachment file to send via mail.
As this link outlook-large-attachments suggests, I created a draft message with all the necessary parameters and started the upload session which gave me as a response the opaque url, expiration time and so on (til here, everything works fine). The next step where I have to use PUT iteratively to upload parts of the mail, gives me no response and the code keeps running. I tried using POST or GET instead of PUT to see if anything changes & changing the opaque url, but the same behavior continues.

I searched the internet endlessly but could not find someone with a similar problem. Can anyone help me?

#create draft  
                payload=json.dumps({  

                    "subject":subject,  
                    "importance":"Low",  
                    "body":{                 
                        "contentType":"Text",  
                        "content":content  
                    },  
                    "toRecipients":setup_recipients(recipients)    
                    })  
                mail_data_draft = requests.post(url=ms_graph_endpoint_draft, data=payload, headers={'Authorization': 'Bearer ' + result['access_token'], 'Content-Type': 'application/json'})  
                message_id=json.loads(mail_data_draft.text)["id"]  

                #creating upload session with message id  
                upload_session_endpoint="https://graph.microsoft.com/v1.0/users/" + email_account +"/messages/"+message_id+"/attachments/createUploadSession"  
                up_session_payload= json.dumps({  
                    "AttachmentItem":{  
                        "attachmentType":"file",  
                        "name":"fileName",  
                        "size": contentSize,  

                    }  
                })  
                upload_session_info= requests.post(url=upload_session_endpoint, data=up_session_payload, headers={'Authorization': 'Bearer ' + result['access_token'], 'Content-Type': 'application/json'})  
                opaque_url =json.loads(upload_session_info.text)["uploadUrl"]  
                next_expected_range=json.loads(upload_session_info.text)["nextExpectedRanges"][0]  


                #####################################################################Tested till here   
                #uploading attachment  

                #problem  
                print("start")  

                upload_things = requests.put(url=json.loads(upload_session_info.text)["uploadUrl"],headers={'Content-Type':'application/octet-stream','Content-Length':'327680','Content-Range': 'bytes 0-327679/'+str(contentSize)})  
                #keeps running  
                #iteration  
                print(upload_things.text)  
                print("done")  
##The last two lines are not processed as code gets stuck in requests.put() -> terminal prints : start only  
Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
10,735 questions
{count} votes

Accepted answer
  1. ShivaniRai-MSFT 2,726 Reputation points
    2022-05-04T11:12:22.507+00:00

    Hi @Amr Elagaty ,

    As per this Documentation, I can successfully upload a file of size more than 3MB using upload session. If the file size is less than 3MB do a single POST on the attachments navigation property of the Outlook item instead of creating an upload session.
    If you are creating an upload session for file size more than 3MB then make sure that you don't use graph bearer token as it will have its own authorization token while making PUT request as per the below screenshot from documentation:
    198739-image.png

    Also, please share screenshot if you are getting any error message.

    Hope this helps.

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

    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Ilyes Zemalache 1 Reputation point
    2022-06-09T12:33:48.403+00:00

    Hello @Amr Elagaty ,

    I think I know why it doesn't work for you, you have to send the data in your put request

    headers2 = {  
                        'Content-Type': content_type,  
                        'Content-Length': content_length,  
                        'Content-Range': content_range  
                    }  
    response = requests.put(upload_url, headers=headers, **data=content_byte[0:size]**)  
    

    and to save you some time, you have to get the content_byte of your file with this format:

    "contentBytes": base64.b64encode(pdf).decode('ascii')  
    

    ref : https://learn.microsoft.com/en-us/graph/outlook-large-attachments?tabs=http

    209809-image.png

    For me, I managed to send the message, and the attachment which is a pdf, but I still have a problem with the file, which remains in plain text and not pdf I do not know the cause, if someone has the solution for that, I will be delighted.

    I hope I could bring some help


  2. Amr Elagaty 21 Reputation points
    2022-06-11T12:54:49.457+00:00
     `#1. create draft  
                    payload={  
                        "subject":subject,  
                       # "importance":"Low",  
                        "body":{                 
                            "contentType":"Text",  
                            "content":content  
                        },  
                        "toRecipients":setup_recipients(recipients)    
                        }  
                    if(ccrecipients):  
                        payload["ccRecipients"]=setup_recipients(ccrecipients)  
                    if (bccrecipients):  
                        payload["bccRecipients"]=setup_recipients(bccrecipients)  
                    print("there")  
                    payload = json.dumps(payload)  
                      
                    mail_data_draft = requests.post(url=ms_graph_endpoint_draft, data=payload, headers={'Authorization': 'Bearer ' + result['access_token'], 'Content-Type': 'application/json'})  
                    message_id=json.loads(mail_data_draft.text)["id"]  
                      
                    #2. creating upload session with message id  
                    upload_session_endpoint="https://graph.microsoft.com/v1.0/users/" + email_account +"/messages/"+message_id+"/attachments/createUploadSession"  
                    for attachmentName in attachments:  
                        contentSize=os.path.getsize(attachmentName)  
                        print()  
                        up_session_payload= json.dumps({  
                            "AttachmentItem":{  
                                "attachmentType":"file",  
                                "name":attachmentName,  
                                "size":  contentSize                     
                            }  
                        })  
                        upload_session_info= requests.post(url=upload_session_endpoint, data=up_session_payload, headers={'Authorization': 'Bearer ' + result['access_token'], 'Content-Type': 'application/json'})  
                        #print(upload_session_info.text)  
                        opaque_url =json.loads(upload_session_info.text)["uploadUrl"]                  
                        #3. uploading attachment  
                        with open(attachmentName, 'rb') as f:  
                            chunk_size = 327680  
                            chunk_number = contentSize//chunk_size  
                            chunk_leftover = contentSize - chunk_size * chunk_number  
                            i = 0  
                            while True:  
                                chunk_data = f.read(chunk_size)  
                                start_index = i*chunk_size  
                                end_index = start_index + chunk_size  
                                #If end of file, break  
                                if not chunk_data:  
                                   # print("BREAKING")  
                                    break  
                                if i == chunk_number:  
                                    end_index = start_index + chunk_leftover  
                                #Setting the header with the appropriate chunk data location in the file  
                                headers = {'Content-Length':'{}'.format(chunk_size),'Content-Range':'bytes {}-{}/{}'.format(start_index, end_index-1, contentSize)}  
                                #Upload one chunk at a time  
                                chunk_data_upload = requests.put(opaque_url, data=chunk_data, headers=headers)  
                                ##print(chunk_data_upload)  
                                i = i + 1            
                    # sending draft  
                    ms_graph_endpoint="https://graph.microsoft.com/v1.0/users/" + email_account +  "/messages/"+message_id+"/send"  
                    mail_data = requests.post(url=ms_graph_endpoint, data=payload, headers={'Authorization': 'Bearer ' + result['access_token'], 'Content-Type': 'application/json'})  
                    return`