Office365-REST-Python-Client icon indicating copy to clipboard operation
Office365-REST-Python-Client copied to clipboard

Add custom columns to SharePoint Site and assign specific values to the column when uploading files

Open LynLi-TA opened this issue 2 years ago • 1 comments

Hi,

Thanks for developing and maintaining the API.

Is there a way to add a column to SharePoint site and assign specific value of the column when uploading files?

For example, add "myTag" column to the Site, and assign myTag = "Data Science" to a pdf file when uploading it to the Site.

Thanks, Lyn

LynLi-TA avatar Jun 02 '23 06:06 LynLi-TA

Hi @LynLi-TA Have a look at code below. It creates a DateTime type column with custom name, which I use to mark files as "processed":

    def create_property(self, property_name):
        '''Create SharePoint property (column name) to mark if '''
        field_info = FieldCreationInformation(property_name, FieldType.DateTime)
        self.ctx.web.lists.get_by_title(self.sharepoint_lib).fields.add(field_info).execute_query()
        logger.debug('Created property %s in SharePoint library %s', property_name, self.sharepoint_lib)

in list/library of files in SharePoint site which hosts "SP directory" I determine through:

    def set_sharepoint_lib(self):
        '''
        Utility function to dermine name of library (SharePoint list) containing folder
        and initiate it's instance variable
        '''
        try:
            folder = self.ctx.web.get_folder_by_server_relative_url(self.root_extraction_path)
            self.ctx.load(folder)
            parent_list = folder.list_item_all_fields.parent_list
            self.ctx.load(parent_list)
            self.ctx.execute_query()
            self.sharepoint_lib = parent_list.properties["Title"]
            logger.info('sharepoint_lib: %s', self.sharepoint_lib)
        except Exception:
            logger.error('Cannot access folder: "%s"', self.root_extraction_path)
            raise

after that, I can set its value:

    def mark_processed(self, file):
        '''Set property of SharePoint file indicating that it was processed'''
        file_id = file.listItemAllFields.get().execute_query().id
        file_item = self.ctx.web.lists.get_by_title(self.sharepoint_lib).get_item_by_id(file_id).get().execute_query()
        property_name = self.processed_poperty_name()
        if not property_name in file_item.properties.keys():
            self.create_property(property_name)
        now_str = datetime.today().strftime(SP_DATE_WRITE_FORMAT)
        mdate_utc = datetime.strptime(file_item.properties['Modified'], SP_DATE_READ_FORMAT)
        mdate_str = mdate_utc.replace(tzinfo=tz.utc).astimezone().strftime(SP_DATE_WRITE_FORMAT)
        client_result = file_item.validate_update_list_item(
            {
                property_name: now_str,
                'Modified': mdate_str # Does not work, despite o365 author's claim:
            }
        ).execute_query()
        self.raise_for_o365(client_result)
        logger.debug('Set property %s of %s as %s', property_name, file.serverRelativeUrl, now_str)

I wanted to preserve modification time, but it does not work for some reason (it reflects time, when property was set) despited example @vgrem has posted some time ago for calendar list items. @vgrem - any clues?

r2oro avatar Jul 31 '23 13:07 r2oro