Richard Ellison
Richard Ellison

Reputation: 325

Office365-REST-Python-Client 401 on File Update

I finally got over the hurdle of uploading files into SharePoint which enabled me to answer my own question here: Office365-REST-Python-Client Access Token issue

However, the whole point of my project was to add metadata to the files being uploaded to make it possible to filter on them. For the avoidance of double, I am talking about column information in Sharepoints Document Libraries.

Ideally, I would like to do this when I upload the files in the first place but my understanding of the rest API is that you have to upload first and then use a PUT request to update its metadata.

The link to the Git Hub for Office365-REST-Python-Client: https://github.com/vgrem/Office365-REST-Python-Client

This Libary seems to be the answer but the closest I can find to documentation is under the examples folder. Sadly the example for update file metadata does not exist. I think part of the reason for this stems from the only option being to use a PUT request on a list item.

According to the REST API documentation, which this library is built on, an item's metadata must be operated on as part of a list.

REST API Documentation for file upload: https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/working-with-folders-and-files-with-rest#working-with-files-by-using-rest

REST API Documentation for updating list metadata: https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/working-with-lists-and-list-items-with-rest#update-list-item

There is an example for updating a list item: 'https://github.com/vgrem/Office365-REST-Python-Client/blob/master/examples/sharepoint/listitems_operations_alt.py' but it returns a 401. If you look at my answer to my own question in the link-up top you will see that I granted this App full control. So an unauthorized response and stopped has stopped me dead in my tracks wondering what to do next.

So after all that, my question is: How do I upload a file to a Sharepoint Document Libary and add Metadata to its column information using Office365-REST-Python-Client?

Kind Regards Rich

Upvotes: 2

Views: 6461

Answers (2)

nefdot
nefdot

Reputation: 3

I'm glad I stumbled upon this post and Office365-REST-Python-Client in general. However, I'm currently stuck trying to update a file's metadata, I keep receiving:

'File' object has no attribute 'listitem_allfields'

Any help is greatly appreciated. Note, I also updated this module to v 2.3.1

Here's my code:

list_title = "Documents"
target_folder = ctx.web.lists.get_by_title(list_title).root_folder
target_file = target_folder.upload_file(filename, filecontents)    
ctx.execute_query()
list_item = target_file.listitem_allfields

I've also tried:

library_root = ctx.web.get_folder_by_server_relative_url('Shared Documents')
file_info = FileCreationInformation()
file_info.overwrite = True
file_info.content = filecontent
file_info.url = filename
upload_file = library_root.files.add(file_info)
ctx.load(upload_file)
ctx.execute_query()
list_item = upload_file.listitem_allfields

I've also tried to get the uploaded file item directly with the same result:

target_folder = ctx.web.lists.get_by_title(list_title).root_folder
target_file = target_folder.upload_file(filename, filecontent)    
ctx.execute_query()

uploaded_file = ctx.web.get_file_by_server_relative_url(target_file.serverRelativeUrl)
print(uploaded_file.__dict__)
list_item = uploaded_file.listitem_allfields

All variations return:

'File' object has no attribute 'listitem_allfields'

What am I missing? How to add metadata to a new SPO file/list item uploaded via Python/Office365-REST-Python-Client

Update: The problem was I was looking for the wrong property of the uploaded file. The correct attribute is:

uploaded_file.listItemAllFields

Note the correct casing. Hopefully my question/answer may help someone else who's is as ignorant as me of attribute/object casing.

Upvotes: 0

Vadim Gremyachev
Vadim Gremyachev

Reputation: 59338

Upload endpoint request

url: http://site url/_api/web/GetFolderByServerRelativeUrl('/Shared Documents')/Files/Add(url='file name', overwrite=true)
method: POST
body: contents of binary file
headers:
    Authorization: "Bearer " + accessToken
    X-RequestDigest: form digest value
    content-type: "application/json;odata=verbose"
    content-length:length of post body

could be converted to the following Python example:

ctx = ClientContext(url, ctx_auth)

file_info = FileCreationInformation()
file_info.content = file_content
file_info.url = os.path.basename(path)
file_info.overwrite = True
target_file = ctx.web.get_folder_by_server_relative_url("Shared Documents").files.add(file_info)
ctx.execute_query()

Once file is uploaded, it's metadata could be set like this:

list_item = target_file.listitem_allfields # get associated list item 
list_item.set_property("Title", "New title")
list_item.update()
ctx.execute_query()

Upvotes: 1

Related Questions