Error 400 during put on drive item
Describe the bug
I am trying to upload a .docx file into OneDrive using Graph API. Unfortunately, it returns an error 400.
msgraph.generated.models.o_data_errors.o_data_error.ODataError:
{
APIError
Code: 400
error: MainError(code='BadRequest', message='Entity only allows writes with JSON Content-Type header.')
}
Expected behavior
Based on the type from the code of the sdk passed type is correct, so I don't understand this behaviour and the bellow code should upload the file.
How to reproduce
file_path = "test.docx"
with open(file_path, "rb") as file_handle:
file_bytes = file_handle.read()
item_path = "/root:/Documents/test_on_one_drive.docx"
r = await client.drives.by_drive_id(drive_id).items.by_drive_item_id(item_path).content.put(body=file_bytes)
SDK Version
1.4.0
Latest version known to work for scenario above?
No response
Known Workarounds
No response
Debug output
Click to expand log
```</details>
### Configuration
_No response_
### Other information
_No response_
Hello @PrzemyslawSagalo thanks for using the SDK and for raising this.
What is the requestInformation, does it set the apprpriate content headers.
prior to sending the request, you might consider setting the request information object https://github.com/microsoft/kiota-abstractions-python/blob/main/kiota_abstractions/request_information.py
Then use that request information object for the request e.g to upload an item to drive?
Is the intention to upload an item to drive item https://learn.microsoft.com/en-us/graph/api/driveitem-put-content?view=graph-rest-1.0&tabs=http or to update the properties of a drive item https://learn.microsoft.com/en-us/graph/api/driveitem-update?view=graph-rest-1.0&tabs=http?
Hi @shemogumbe thank you for your quick response.
- Where exactly should I put/use this request information object? This is my client init stage.
proxies = {"http": "http://my-proxy.com:80", "https": "http://my-proxy.com:443"}
tenant_id = "tenant_id_value"
client_id = "client_id_value"
credentials = DeviceCodeCredential(client_id=client_id, tenant_id=tenant_id, proxies=proxies)
scopes = ["Files.ReadWrite.All"]
auth_provider = AzureIdentityAuthenticationProvider(credentials, scopes=scopes)
httpx_proxies = {
"http://": proxies["http"],
"https://": proxies["https"],
}
http_client = AsyncClient(proxies=httpx_proxies)
http_client = GraphClientFactory.create_with_default_middleware(client=http_client)
request_adapter = GraphRequestAdapter(auth_provider, http_client)
client = GraphServiceClient(request_adapter=request_adapter)
- My intention is to upload a new file to OneDrive as it is here: https://learn.microsoft.com/en-us/graph/api/driveitem-put-content?view=graph-rest-1.0&tabs=http#to-upload-a-new-file
@shemogumbe
The problem was in the wrong construction of the item_path.
It should be root:/Documents/test_on_one_drive.docx: instead of /root:/Documents/test_on_one_drive.docx.
The exception message could be more intuitive because it does not accurately convey the actual problem.
@PrzemyslawSagalo I had your same problem using almost the same code, and after fixing the item_path with the missing : char I get another error:
APIError Code: 400 message: None error: MainError(additional_data={}, code='invalidRequest', details=None, inner_error=InnerError(..., message='A valid name must be provided.', target=None)
Did you happen to solve this too?
My code is:
async with aiofiles.open(src_file_path, 'rb') as file:
file_content = await file.read()
dest_file_path = f"{dest_folder_name}/{src_file_name}"
drive_item_id = f"root:/{dest_file_path}/:"
uploaded_file = await self.client.drives.by_drive_id(drive_id).items.by_drive_item_id(drive_item_id).content.put(file_content)
What can I try to solve this? @shemogumbe
Thank you.
Solved, there was a missing /, i.e. drive_item_id = f"/root:/{dest_file_path}/:"