使用CKAN API和Python Requests库创建CKAN数据集



我正在使用CKAN 2.2版本,我试图自动创建数据集和资源上传。我似乎无法使用python 请求库创建数据集。我收到400错误代码。代码:

import requests, json
dataset_dict = {
    'name': 'testdataset',
    'notes': 'A long description of my dataset',
}
d_url = 'https://mywebsite.ca/api/action/package_create'
auth = {'Authorization': 'myKeyHere'}
f = [('upload', file('PathToMyFile'))]
r = requests.post(d_url, data=dataset_dict, headers=auth)

奇怪的是,我am能够使用python requests库创建一个新的资源并上传一个文件。代码基于此文档。代码:

import requests, json
res_dict = {
    'package_id':'testpackage',
    'name': 'testresource',
    'description': 'A long description of my resource!',
    'format':'CSV'
}
res_url = 'https://mywebsite.ca/api/action/resource_create'
auth = {'Authorization': 'myKey'}
f = [('upload', file('pathToMyFile'))]
r = requests.post(res_url, data=res_dict, headers=auth, files=f)

我还能够使用内置python库的CKAN文档中的方法创建一个数据集。文档:CKAN 2.2

代码:

#!/usr/bin/env python
import urllib2
import urllib
import json
import pprint
# Put the details of the dataset we're going to create into a dict.
dataset_dict = {
    'name': 'test1',
    'notes': 'A long description of my dataset',
}
# Use the json module to dump the dictionary to a string for posting.
data_string = urllib.quote(json.dumps(dataset_dict))
# We'll use the package_create function to create a new dataset.
request = urllib2.Request('https://myserver.ca/api/action/package_create')
# Creating a dataset requires an authorization header.
request.add_header('Authorization', 'myKey')
# Make the HTTP request.
response = urllib2.urlopen(request, data_string)
assert response.code == 200
# Use the json module to load CKAN's response into a dictionary.
response_dict = json.loads(response.read())
assert response_dict['success'] is True
# package_create returns the created package as its result.
created_package = response_dict['result']
pprint.pprint(created_package)

我真的不知道为什么我创建数据集的方法不工作。package_create和resource_create函数的文档非常相似,我希望能够使用相同的技术。我更愿意使用请求包来处理我与CKAN的所有交易。是否有人能够成功地使用请求库创建数据集?

我终于回过头来想明白了。爱丽丝检查编码的建议非常接近。虽然requests为您进行编码,但它还根据输入自行决定哪种类型的编码是合适的。如果文件与JSON字典一起传入,则请求自动执行多部分/表单数据编码,该编码被CKAN接受,因此请求成功。

然而,如果我们只传递一个JSON字典,默认编码是形式的编码。CKAN需要对没有文件的请求进行URL编码(application/x-www-form-urlencoded)。为了防止请求进行任何编码,我们可以将参数作为字符串传入,然后请求将只执行POST。这意味着我们必须自己对它进行URL编码。

因此,如果我指定内容类型,将参数转换为字符串并使用urllib编码,然后将参数传递给请求:

head['Content-Type'] = 'application/x-www-form-urlencoded'
in_dict = urllib.quote(json.dumps(in_dict))
r = requests.post(url, data=in_dict, headers=head)

您发送的数据必须是JSON编码。

从文档(您链接到的页面):

调用CKAN API,在HTTP post请求中发布一个JSON字典到CKAN的一个API url

在urllib示例中,这是通过以下代码行执行的:

data_string = urllib.quote(json.dumps(dataset_dict))

我认为(尽管你应该检查)requests库将为你做引用-所以你只需要将你的字典转换为JSON。像这样的代码应该可以工作:

r = requests.post(d_url, data=json.dumps(dataset_dict), headers=auth)

最新更新