2014-07-08 112 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