2016-08-16 18 views
0

我正在Python中使用Flask實現REST API。 我必須獲取參數來執行查詢並返回資源。爲了與REST原則保持一致,我將使用GET請求進行此操作。如何在Flask中獲取GETs json數據

既然可以有很多的參數,我想通過一個conf.json文件給他們,例如:

{"parameter": "xxx"} 

我通過curl執行請求:

$捲曲 - H「Content-Type:application/json」--data @ conf.json -G http://localhost:8080/resources/

該請求是redire反恐執行局的路線與這些操作:

@resources.route('/resources/', methods=['GET']) 
def discover(): 
if request.get_json(): 
    json_data=request.get_json() 
    return jsonify(json_data) 

我得到的回覆是:

<head> 
<title>Error response</title> 
</head> 
<body> 
<h1>Error response</h1> 
<p>Error code 400. 
<p>Message: Bad request syntax ('GET /resources/?{"parameter": "xxx"} HTTP/1.1'). 
<p>Error code explanation: 400 = Bad request syntax or unsupported method. </body> 

有人知道如何獲得JSON數據並妥善請求處理呢?

+0

@加載文件的URL參數,因爲該請求是GET類型。這看起來不太好,可能會導致字符編碼的許多問題。你確定這是你想要的嗎? – Fma

回答

4

request.get_json()尋找請求中的JSON數據主體(例如POST請求將包括什麼)。相反,您將JSON數據放入GET請求的URL查詢字符串

curl命令發送您的JSON未逃脫,併產生一個無效的URL,所以服務器正確會拒絕:

http://localhost:8080/resources/?{"parameter": "xxx"} 

你不能在URL中的空間,例如。你不得不使用--data-urlencode而不是爲這是正確轉義:

$ curl --data-urlencode @conf.json -G http://localhost:8080/resources/ 

請注意,在這裏不需要的Content-Type頭;您沒有任何請求機構來記錄的內容

調整後的curl命令現在發送一個正確編碼的URL:

http://localhost:8080/resources/?%7B%22parameter%22%3A%20%22xxx%22%7D%0A%0A 

訪問與request.query_string數據。您也將有解碼 URL編碼再次路過這json.loads()前:

from urllib import unquote 

json_raw_data = unquote(request.query_string) 
json_data = json.loads(json_raw_data) 

要考慮到許多Web服務器放在他們將一個URL多久接受限度。如果您打算以這種方式在URL中發送超過4k個字符,則您確實需要重新考慮並使用POST請求。這是4k與JSON數據URL編碼,這增加了相當大的開銷。

0

的Martijn答案是正確的這一

$ curl --data-urlencode @conf.json -G http://localhost:8080/resources/ 

但你並不需要使用urllib與瓶拿到ARGS。我會在我的端點上使用以下內容。

@resources.route('/resources') 
def test(): 
    args = request.args 
    return args.get('parameter') 

而且我想看看使用flask_testing擴展,這樣你可以存在正在運行的應用程序的上下文內建立可重複的測試案例。

from flask_testing import TestCase 
from app import app 

class TestQueryString(TestCase): 

    def create_app(self): # Must be implemented 
     return app 

    def test_json_parse_args(self): 
     data = { 
      'parameter': 'value' 
     } 

     r = self.client.get('/resources', query_string=data) 
     self.assert200(r) 
     self.assertEqual(r.data, 'value') 

https://pythonhosted.org/Flask-Testing/

+0

感謝Adam。我試過,但沒有使用'urllib'我無法得到參數。燒瓶過程'ImmutableMultiDict'在這樣的ARGS: 'ImmutableMultiDict([( '{ 「參數」: 「XXX」}',U '')])' 代替比: 'ImmutableMultiDict([( 'parameter':u'xxx')])' 因此,他不解析{}中的參數我猜 – adefabritiis

+0

是的,但事實是,您不會通過'curl'與API進行交互在生產中。您將使用編程語言發送請求,無論它是JS還是Python。另外,如果你使用'-d parameter = value',它會給你正確的查詢字符串並且可以工作。 – Adam