Skip to main content

Hi,



What is the use of using the SDK when we already have API. We can directly use those API.



I am trying to do chunk file upload. For that it initially creates a session and then uploads parts of a file (https://upload.box.com/api/2.0/files/upload_sessions/:upload_session_id) this the API to upload parts of a file. I checked in SDK how they uploading the parts of a file, in that they have handled all the file splitting and every required. But when I tried the https://upload.box.com/api/2.0/files/upload_sessions/:upload_session_id API in postman, I am not able to upload file.



My question if SDK are handling these splitting functionalities, Does API also handle all the scenarios?



What is the benefit of using SDK if we already have API?

Hi @Sakthi11 , welcome to the forum!



Typically the SDKs include some helper methods and data structures, to make life easier for developers.



We are however creating new SDKs, we call the Next Gen SDKs where there is a closer mapping between the API end points and the SDK methods.



The example you mention is a perfect example. The chunked upload end point will respond to Postman, but it will be very hard to complete a chunked upload using Postman, since Postman is missing the file handling pieces.



This is where the SDKs shine, making your life as a developer simpler. In my personal opinion, and although I work mainly with Python, I do like type hints and a some formality in my data structures, and the SDK implements the formal dictionaries for the response objects.



Here is an article discussing different ways of uploading files to Box, that might interest you:




I am trying to upload the 37mb file using chunk upload.





  1. I created the upload session.




Body:



{

"folder_id": "0",

"file_size": 38273024,

"file_name": "37mb"

}



Response:



{

"total_parts": 5,

"part_size": 8388608,

"session_endpoints": {

"list_parts":

"commit":

"log_event":

"upload_part":

"status":

"abort": "

},

"session_expires_at": "2024-06-03T12:00:00Z",

"id": "FB2E73F5F631797D3E2F127170D327D8",

"type": "upload_session",

"num_parts_processed": 0

}



2)Upload part of file.



curl -X PUT  https://{{upload box}}/api/2.0/files/upload_sessions/:upload_session_id\

-H "Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXX" \

-H "Digest: sha=sha=fpRyg5eVQletdZqEKaFlqwBXJzM=" \

-H "Content-Range: bytes 8388608-16777215/38273024" \

-H "Content-Type: application/octet-stream" \

--data-binary @37mb.zip



Response:



{

"code": "request_size_too_long",

"message": "Request body larger than expected number of bytes: 8388608",

"request_id": "693372e8536c3338b3c36275b3037e00"

}



Can any one say what range of bytes i should give in content Range. And also say how to extract the digest. To rectify this error.


Hi @Sakthi11 ,



I removed a duplicate post on this thread and edit your post for format.





I’m not sure if the content range header is enough for this cUrl command. I think you need to actually split the file by the number of bytes length.



On macOS/Linux you can try the split command.



You would also need to calculate the SHA for each piece.



Anyway the SDKs would really help here.


I’ve just tried this by hand, and we have some detailed step by step guide:







In summary:



I have a 25 mbyte file



Create the upload session:



curl --location 'https://upload.box.com/api/2.0/files/upload_sessions' \

--header 'Content-Type: application/json' \

--header 'Authorization: Bearer B0...Pl'

--data '{

"folder_id": "0",

"file_size": 26214400,

"file_name": "25m_file.bin"

}'



Response:



{

"total_parts": 2,

"part_size": 16777216,

"session_endpoints": {

"list_parts": "https://upload.box.com/api/2.0/files/upload_sessions/5D...F5/parts",

"commit": "https://upload.box.com/api/2.0/files/upload_sessions/5D...F5/commit",

"log_event": "https://upload.box.com/api/2.0/files/upload_sessions/5D...F5/log",

"upload_part": "https://upload.box.com/api/2.0/files/upload_sessions/5D..F5",

"status": "https://upload.box.com/api/2.0/files/upload_sessions/5D.F5",

"abort": "https://upload.box.com/api/2.0/files/upload_sessions/5D..F5"

},

"session_expires_at": "2024-06-05T18:11:54Z",

"id": "5D...F5",

"type": "upload_session",

"num_parts_processed": 0

}



Then split the file in 16,777,216 chunks



split -b 16777216 25m_file.bin file-part-



Result:



-rw-r--r--@  1 rbarbosa  staff  16777216 May 29 14:14 file-part-aa

-rw------- 1 rbarbosa staff 26214400 May 29 14:11 25m_file.bin

-rw-r--r--@ 1 rbarbosa staff 9437184 May 29 14:14 file-part-ab



Calculate the SHA1 for each file:



openssl sha1 -binary file-part-aa | base64 ->> O0QX/EIc7jCprQ/ZMZIgqNrjLaI=

openssl sha1 -binary file-part-ab | base64 ->> j3ZZsPo5lPzOK+Biu+oNGD6bxE4=

openssl sha1 -binary 25m_file.bin | base64 ->> qxG6ik5VlRg8Eq2mhpcT/4JtINc=



Upload first part:



curl --location --request PUT 'https://upload.box.com/api/2.0/files/upload_sessions/5D...F5' \

--header 'digest: sha=O0QX/EIc7jCprQ/ZMZIgqNrjLaI=' \

--header 'content-range: bytes 0-16777215/26214400' \

--header 'Content-Type: application/octet-stream' \

--header 'Authorization: Bearer B0...Pl' \

--data '@/Users/rbarbosa/Library/CloudStorage/Box-Box/A-RB-Stuff/LapTop/Documents/code/forum-demos/manual_chunked_uploads/file-part-aa'



Result:



{

"part": {

"part_id": "891EECF0",

"offset": 0,

"size": 16777216,

"sha1": "3b4417fc421cee30a9ad0fd9319220a8dae32da2"

}

}



Upload 2nd part:



curl --location --request PUT 'https://upload.box.com/api/2.0/files/upload_sessions/5D...F5' \

--header 'digest: sha=j3ZZsPo5lPzOK+Biu+oNGD6bxE4=' \

--header 'content-range: bytes 16777216-26214399/26214400' \

--header 'Content-Type: application/octet-stream' \

--header 'Authorization: Bearer B0...Pl' \

--data '@/Users/rbarbosa/Library/CloudStorage/Box-Box/A-RB-Stuff/LapTop/Documents/code/forum-demos/manual_chunked_uploads/file-part-ab'



Result:



{

"part": {

"part_id": "FA52FAAF",

"offset": 16777216,

"size": 9437184,

"sha1": "8f7659b0fa3994fcce2be062bbea0d183e9bc44e"

}

}



Commit the upload:



curl --location 'https://upload.box.com/api/2.0/files/upload_sessions/5D...F5/commit' \

--header 'digest: sha=qxG6ik5VlRg8Eq2mhpcT/4JtINc=' \

--header 'Content-Type: application/json' \

--header 'Authorization: Bearer B0...Pl' \

--data '{

"parts": :

{

"part_id": "891EECF0",

"offset": 0,

"size": 16777216,

"sha1": "3b4417fc421cee30a9ad0fd9319220a8dae32da2"

},

{

"part_id": "FA52FAAF",

"offset": 16777216,

"size": 9437184,

"sha1": "8f7659b0fa3994fcce2be062bbea0d183e9bc44e"

}

]

}'



Result (simplified):



{

"total_count": 1,

"entries": :

{

"type": "file",

"id": "1545165688368",

"sha1": "ab11ba8a4e5595183c12ada6869713ff826d20d7",

"name": "25m_file.bin",

"size": 26214400,

"created_at": "2024-05-29T11:32:48-07:00",

"item_status": "active"

}

]

}



Let us knows if this helps



Cheers


Can you please explain this process from start end in detail, and may i know where you run the command (split command and openssl command).


Hi @Sakthi11 ,



Just follow the guide I’ve linked in the previous message, or the step by step example of my response.



The split and openssl commands are operating system commands executed on a terminal, in my case for macOS, and they should work for linux also.



If you’re using windows you may need to install some utilities.



Best regards


Reply