2014-07-08 75 views
4

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

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) 

奇怪的是我能够创造新的资源,并使用Python 请求库上传文件。该代码是基于this documentation.代码:

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) 

我也能创建使用CKAN文档中的方法的数据集使用内置的Python库。文档: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的所有交易。有没有人能够成功地创建一个包含请求库的数据集?

任何帮助,非常感谢。

回答

4

我终于回来了,并找出它。爱丽丝建议检查编码非常接近。虽然请求确实为您编码,但它也根据输入自行决定哪种类型的编码是适当的。如果一个文件与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) 

然后该请求是成功的。

+1

感谢您发布此。我永远不会知道。耶稣 – Jesus

3

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

从文件(网页链接到您):

要调用API CKAN,张贴JSON字典中的HTTP POST请求 到CKAN的API网址之一。

在urllib的例子,这是由下面这行代码执行:

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

我认为(虽然你应该检查),该requests库会做报价为你 - 所以你只需要将您的字典转换为JSON。像这样的东西应该工作:

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

感谢您的回复。根据请求文档中的示例,它确实为您引用了引用。然而,将字典转换为json然后传递它也不起作用。同样的问题。我并不感到惊讶,因为如果这是这种情况,我希望在创建资源时得到相同的错误,但资源创建按照我的第二个示例工作。感谢您的尝试! :) – NenadK