microsoftgraph / microsoftgraph/msgraph-sdk-python-core

`LargeFileUploadTask.upload()` throws a 400 error when file size is smaller than max_chunk_size

Aperta
#718 0 commenti 2 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

area:uploads P1 priority:p1 type:bug
Lingua principale
Python
Stelle
288
Fork
52
Merge medio
8h 10m
PR unite (30g)
1

Descrizione

Describe the bug

While uploading a large file using LargeFileUploadTask to a SharePoint drive location, if the overall file size is less than the max_chunk_size defined (e.g uploading a 5 KB file but the chunk size is 10 MB), the async LargeFileUploadTask.upload() method uploads the file but throws below error:

APIError:
        APIError
        Code: 400
        message: The server returned an unexpected status code and no error class is registered for this code 400
Expected behavior

The upload task should complete without any errors OR the error message should be meaningful e.g. File is too small.

How to reproduce
destination_path = "path/to/your_file.txt" # path on SharePoint drive where I want to upload the file
file_path = "path/to/your_file.txt" # A small file like 10 KB in my local system

async def upload_large_file(graph_client, drive_id):
    try:
        file = open(file_path, 'rb')
        uploadable_properties = DriveItemUploadableProperties(
            additional_data={'@microsoft.graph.conflictBehavior': 'replace'}
        )
        upload_session_request_body = CreateUploadSessionPostRequestBody(item=uploadable_properties)
        print(f"Uploadable Properties: {uploadable_properties.additional_data}")
        # can be used for normal drive uploads
        try:
            upload_session = await graph_client.drives.by_drive_id(
                drive_id
            ).items.by_drive_item_id("root:/my_docs/test_upload.txt:"
                                     ).create_upload_session.post(upload_session_request_body)
            
        except APIError as ex:
            print(f"Error creating upload session: {ex}")

        # to be used for large file uploads
        large_file_upload_session = LargeFileUploadSession(
            upload_url=upload_session.upload_url,
            expiration_date_time=datetime.now() + timedelta(days=1),
            additional_data=upload_session.additional_data,
            is_cancelled=False,
            next_expected_ranges=upload_session.next_expected_ranges
        )

        max_chunk_size = 10 * 1024 * 1024
        task = LargeFileUploadTask(
            upload_session=large_file_upload_session, 
            request_adapter=graph_client.request_adapter, 
            stream=file, 
            parsable_factory=DriveItem, 
            max_chunk_size=max_chunk_size
        )
        total_length = os.path.getsize(file_path)
        
        # Upload the file
        # The callback
        def progress_callback(uploaded_byte_range: tuple[int, int]):
            print(f"Uploaded {uploaded_byte_range[0]} bytes of {total_length} bytes\n\n")

        try:
            upload_result = await task.upload(progress_callback)
            print(f"Upload complete {upload_result}")
        except APIError as ex:
            print(f"Error uploading: {ex.message} - {ex.response_status_code}")
            raise
    except APIError as e:
        print(f"Error: {e}")
        raise

asyncio.run(upload_large_file(graph_client, drive_id))
SDK Version

1.1.7

Latest version known to work for scenario above?

No response

Known Workarounds

Changing the max_chunk_size value to (file_size - 1) seems to prevent the error from occurring.

Debug output
Click to expand log ```
</details>


### Configuration

OS: Windows 10
Architecture: x64
Python version: 3.9.19

### Other information

_No response_

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia da LargeFileUploadTask.upload() e riproduci il caso segnalato usando un file più piccolo di max_chunk_size, ad esempio un file da 5 KB con una dimensione del chunk di 10 MB. Traccia il risultato dell'upload e la successiva risposta 400; il lavoro è completato quando l'upload del file piccolo termina senza un errore imprevisto oppure segnala un errore significativo.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
api
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
48/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.