python - 在 python 中使用请求模块连接到 Azure-Datalakes-gen2 时遇到问题
问题描述
我目前正在尝试使用 python 连接到 azure datalakes-gen2,以从存储在其中的 json 文件中获取信息。听说 python 的 azure-datalakes 模块不适用于第 2 代(我自己也遇到了麻烦),我继续通过 rest-api 和 python 中的 requests 包进行连接。但是,阅读 Microsoft 留下的参考资料以及所需的身份验证标头让我更加困惑该怎么做。
虽然我对 python 有一个大致的了解,但对于更高级的项目,我仍然是一个业余爱好者,并且总是需要查找内容,但是这是我第一次寻求帮助而不是搜索直到找到答案(所以请忍受我)。
我找到了 Michal Pawlikowski 的有用链接,解释了如何通过 powershell 进行连接,这有助于解释很多松散的结局,但仍然存在两个问题,首先是我不确定是否正确编码身份验证标头。特别是“通过在 UTF-8 编码的签名字符串上使用 HMAC-SHA256 算法对该字符串进行编码”,其次,这只会列出在目录中找到的文件,而不是文件中包含的信息。
这是我尝试过的
date = "Wed, 15 May 2019 14:28:01 GMT"
string_to_sign = 'GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:'+date+'\nx-ms-version:2018-11-09\n/'+STORAGE_ACCOUNT_NAME+'/'+FILE_SYSTEM_NAME+'\nrecursive:true\nresource:fileststem'
signature = #Encoded string_to_sign + key, am unsure how to approach
auth_header = "SharedKey "+STORAGE_ACCOUNT_NAME+":"+signature
headers = {"Authorization" : auth_header, "x-ms-version" : "2018-11-09", "x-ms-date" : date}
req = requests.get("https://"+STORAGE_ACCOUNT_NAME+".dfs.core.windows.net/" + FILE_SYSTEM_NAME + "?recursive=true&resource=filesystem", headers=headers)
我希望 req.text 包含在 json 文件中找到的信息,但是我总是会收到 403 错误,以确保我的标题格式正确。
解决方案
如果你想读取文件内容,你应该使用Read api。
下面的代码在我身边有效:
import requests
import datetime
import hmac
import hashlib
import base64
storage_account_name = 'storage_account_name'
storage_account_key = 'storage_account_key'
api_version = '2018-11-09'
request_time = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
#the file path on adls gen2
FILE_SYSTEM_NAME='dd1/11.txt'
string_params = {
'verb': 'GET',
'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,
'CanonicalizedResource': '/' + storage_account_name+'/'+FILE_SYSTEM_NAME
}
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']+'\n'
+ 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 + '.dfs.core.windows.net/'+FILE_SYSTEM_NAME)
r = requests.get(url, headers = headers)
#print out the file content
print(r.text)
测试结果:
推荐阅读
- android - Why is the rendering object moving in the ARCore Location example?
- mongodb - How to define - environment specifc mongo db configuration in play framework with JpaApi?
- c++ - Why does object layout depend on initializer (clang)
- php - Display only the childrens from a specific category ID or slug
- java - Java Hibernate 二级缓存是否默认启用?
- html - How toggle menu
- jquery - jQuery 仅当至少一个输入字段的值大于 0 时才提交表单
- swift - Remove Animation When Selecting A Cell In A Tableview
- c# - EF Core HasQueryFilter on Include()
- ruby-on-rails - How to pass data from view that came from an external API to a controller?