如何使用Python为Azure文件存储使用getfileproperties restapi

2024-06-25 23:18:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个Python脚本,它将同时使用pythonsdkforazure和restapi,以便为我的Azure文件存储帐户中的文件提取信息。在

我使用SDK访问存储中的文件并获取这些文件名。然后使用这个名称,我希望能够调用restapi来获取文件属性,特别是最后修改的属性。我尝试使用SDK访问最后修改的属性,但由于某种原因它总是不返回任何属性。在

我想用上次修改的日期来确定它是否已经超过24小时,如果已经超过了,我想删除文件。当我第一次创建并上传到azure时,我不确定是否可以在文件上设置某种类型的“在某个时间段后自动删除”属性。如果有,这无论如何都能解决我的问题。在

我已经在下面发布了我正在使用的代码。当我尝试发出HTTP请求时,我得到错误消息“服务器未能验证请求。请确保Authorization标头的值格式正确,包括签名。“

    import datetime
    import requests
    import json
    import base64
    import hmac
    import hashlib
    import urllib
    from azure.storage.file import *

StorageAccountConnectionString = ""
fileshareName = "testFileShare"
storage_account_name = "testStorage"
storage_account_key = ""
api_version = "2018-03-28"

        file_service = FileService(connection_string=StorageAccountConnectionString)
    listOfStateDirectories = file_service.list_directories_and_files(fileshareName)

    for state_directory in listOfStateDirectories:
        print("Cleaning up State Directory: " + state_directory.name)
        if(isinstance(state_directory, Directory)):
            listOfBridgeDirectories = file_service.list_directories_and_files(fileshareName, state_directory.name)
            for bridge_directory in listOfBridgeDirectories:
                if(isinstance(bridge_directory, Directory)):
                    print("Cleaning up Bridge Directory: " + bridge_directory.name)
                    path_to_bridge_directory = state_directory.name + "/" + bridge_directory.name
                    listOfFilesAndFolders = file_service.list_directories_and_files(fileshareName, path_to_bridge_directory)

                for file_or_folder in listOfFilesAndFolders:
                    if isinstance(file_or_folder, File):
                        name_of_file = file_or_folder.name

                        # Get the time of the current request
                        request_time = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')

                        string_to_append_to_url = fileshareName + '/' + path_to_bridge_directory + '/' + name_of_file
                        # Parse the url to make sure everything is good
                        # string_to_append_to_url = urllib.parse.quote(string_to_append_to_url)

                        string_params = {
                            'verb': 'HEAD',
                            'Content-Encoding': '',
                            'Content-Language': '',
                            'Content-Length': '',
                            'Content-MD5': '',
                            'Content-Type': '',
                            'Date': '',
                            'If-Modified-Since': '',
                            'If-Match': '',
                            'If-None-Match': '',
                            'If-Unmodified-Since': '',
                            'Range': '',
                            'CanonicalizedHeaders': 'x-ms-date:' + request_time + '\nx-ms-version:' + api_version + '\n',
                            'CanonicalizedResource': '/' + storage_account_name + '/' + string_to_append_to_url
                        }

                        string_to_sign = (string_params['verb'] + '\n'
                                          + string_params['Content-Encoding'] + '\n'
                                          + string_params['Content-Language'] + '\n'
                                          + string_params['Content-Length'] + '\n'
                                          + string_params['Content-MD5'] + '\n'
                                          + string_params['Content-Type'] + '\n'
                                          + string_params['Date'] + '\n'
                                          + string_params['If-Modified-Since'] + '\n'
                                          + string_params['If-Match'] + '\n'
                                          + string_params['If-None-Match'] + '\n'
                                          + string_params['If-Unmodified-Since'] + '\n'
                                          + string_params['Range'] + '\n'
                                          + string_params['CanonicalizedHeaders']
                                          + string_params['CanonicalizedResource'])

                        signed_string = base64.b64encode(hmac.new(base64.b64decode(storage_account_key), msg=string_to_sign.encode('utf-8'), digestmod=hashlib.sha256).digest()).decode()

                        headers = {
                            'x-ms-date': request_time,
                            'x-ms-version': api_version,
                            'Authorization': ('SharedKey ' + storage_account_name + ':' + signed_string)
                        }

                        url = ('https://' + storage_account_name + '.file.core.windows.net/' + string_to_append_to_url)
                        print(url)


                        r = requests.get(url, headers=headers)
                        print(r.content)

注意:有些目录会有空格,所以我不确定这是否会影响restapi调用,因为URL也会有空格。如果它真的影响了它,那么我该如何访问那些URL中包含空格的文件呢


Tags: 文件tonameimporturlstringifstorage
1条回答
网友
1楼 · 发布于 2024-06-25 23:18:05

I try to access the last modified property using the SDK but it always returns None for some reason.

并不是所有的sdkapi和restapi都会在响应的头中返回Last-Modified属性,其中包括restapi^{}和pythonsdkapi^{}。在

我尝试使用SDK重现您的问题,如下所示。在

generator = file_service.list_directories_and_files(share_name, directory_name)
for file_or_dir in generator:
    if isinstance(file_or_dir, File):
        print(file_or_dir.name, file_or_dir.properties.last_modified)

由于list_directories_and_files方法不会返回File对象中的任何属性,因此上面代码的file_or_dir.properties.last_modified值是None。在

restapi ^{}^{}^{}和pythonSDKAPI ^{}^{}将在响应的头中返回{}属性,以便按如下所示更改代码,以获得last_modified属性使其正常工作。在

^{pr2}$

调用restapi和使用sdkapi是一样的。然而,构建SAS签名字符串很容易出错,不利于代码的读取。在

相关问题 更多 >