microsoftgraph / microsoftgraph/msgraph-sdk-python-core

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

未关闭
#718 0 条评论 2 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

area:uploads P1 priority:p1 type:bug
主要语言
Python
星标
288
派生
52
平均合并
8 小时 10 分钟
30 天内合并 PR
1

描述

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_

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 LargeFileUploadTask.upload() 开始,使用小于 max_chunk_size 的文件重现报告的情况,例如使用 10 MB 的块大小上传一个 5 KB 的文件。跟踪上传结果和随后出现的 400 响应;当小文件上传完成且没有意外错误,或报告有意义的错误时,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
api
Issue 类型
缺陷
难度
3/5
预计耗时
1-2 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
48/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。