अजगर का उपयोग करके एक RESTful API के लिए अनुरोध करना


221

मेरे पास एक RESTful API है जिसे मैंने सामग्री के एक कोष को अनुक्रमित करने के लिए EC2 उदाहरण पर Elasticsearch के कार्यान्वयन का उपयोग करके उजागर किया है। मैं अपने टर्मिनल (MacOSX) से निम्नलिखित को खोज कर क्वेरी कर सकता हूं:

curl -XGET 'http://ES_search_demo.com/document/record/_search?pretty=true' -d '{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}'

मैं एक एपीआई अनुरोध का उपयोग करके ऊपर कैसे बदल सकता हूं ( python/requestsया python/urllib2यह सुनिश्चित करने के लिए कि कौन से व्यक्ति के लिए urlib2 का उपयोग किया गया है, लेकिन सुनें कि अनुरोध बेहतर है ...)? क्या मैं हेडर के रूप में पास करूं या अन्यथा?

जवाबों:


340

अनुरोधों का उपयोग करना :

import requests
url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
data = '''{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}'''
response = requests.post(url, data=data)

क्या प्रतिक्रिया की तरह अपने एपीआई रिटर्न, आप तो शायद को देखने के लिए चाहते हैं पर निर्भर करता है response.textया response.json()(या संभवतः निरीक्षण response.status_codeपहले)। क्विकार्ट डॉक्स यहां देखें , विशेष रूप से यह खंड


3
मुझे लगता है, यह होना चाहिए: प्रतिक्रिया =
request.post

8
"request.get" "डेटा" पैरामीटर नहीं लेता है। यह वैकल्पिक "पैराम्स" पैरामीटर ले सकता है जो आमतौर पर एक ले जाने वाला क्वेरी स्ट्रिंग होता है। यदि एक पेलोड डेटा लाने के लिए आवश्यक है (जैसे कि प्रश्न में पोस्ट किया गया उदाहरण), तो "रिक्वेस्ट.पोस्ट" का उपयोग करने की आवश्यकता है। इसके अतिरिक्त "json" लाइब्रेरी का उपयोग करने से json प्रतिक्रिया को पार्स करना आसान हो जाता है।
एचवीएस

4
@ParveenShukhala "अनुरोध आधिकारिक तौर पर अजगर 2.6-2.7 और 3.33.5 का समर्थन करता है, और PyPy पर बहुत अच्छा चलता है।" - pypi.python.org/pypi/requests
danio

2
जैसा कि आप इसे JSON भेज रहे हैं, आप डेटा के बजाय json पैरामीटर का उपयोग कर सकते हैं जैसे: response = request.post (url, json = data)
मार्क Chorley

101

अनुरोधों और json का उपयोग करना सरल बनाता है।

  1. एपीआई को बुलाओ
  2. मान लें कि एपीआई एक JSON देता है, json.loadsफ़ंक्शन का उपयोग करके एक पायथन तानाशाही में JSON ऑब्जेक्ट को पार्स करता है
  3. जानकारी निकालने के लिए तानाशाही के माध्यम से लूप।

अनुरोध मॉड्यूल आपको सफलता और विफलता के लिए लूप के लिए उपयोगी फ़ंक्शन प्रदान करता है।

if(Response.ok): यदि आपका एपीआई कॉल सफल है तो आपको यह निर्धारित करने में मदद करेगा कि (रिस्पांस कोड - 200)

Response.raise_for_status() एपीआई से लौटाए गए http कोड को लाने में आपकी मदद करेगा।

नीचे ऐसे एपीआई कॉल करने के लिए एक नमूना कोड है। जीथुब में भी पाया जा सकता है । कोड मानता है कि एपीआई पाचन प्रमाणीकरण का उपयोग करता है। आप या तो इसे छोड़ सकते हैं या एपीआई को लागू करने वाले क्लाइंट को प्रमाणित करने के लिए अन्य उपयुक्त प्रमाणीकरण मॉड्यूल का उपयोग कर सकते हैं।

#Python 2.7.6
#RestfulClient.py

import requests
from requests.auth import HTTPDigestAuth
import json

# Replace with the correct URL
url = "http://api_url"

# It is a good practice not to hardcode the credentials. So ask the user to enter credentials at runtime
myResponse = requests.get(url,auth=HTTPDigestAuth(raw_input("username: "), raw_input("Password: ")), verify=True)
#print (myResponse.status_code)

# For successful API call, response code will be 200 (OK)
if(myResponse.ok):

    # Loading the response data into a dict variable
    # json.loads takes in only binary or string variables so using content to fetch binary content
    # Loads (Load String) takes a Json file and converts into python data structure (dict or list, depending on JSON)
    jData = json.loads(myResponse.content)

    print("The response contains {0} properties".format(len(jData)))
    print("\n")
    for key in jData:
        print key + " : " + jData[key]
else:
  # If response code is not ok (200), print the resulting http error code with description
    myResponse.raise_for_status()

2
कुंजियों पर चलना के साथ अंतिम भाग हमेशा काम नहीं करेगा क्योंकि JSON दस्तावेज़ में शीर्ष स्तर के तत्व के रूप में सरणी हो सकती है। तो, इसे पाने के लिए एक त्रुटि होगीjData[key]
डेनिस द मेनेस

@DenisTheMenace अगर यह एक सरणी है, तो मैं इसके चारों ओर कैसे लूप करूंगा?
1948 में क़ासिमालबाकली

@qasimalbaqali जिस तरह से आप शब्दकोश पर पाश। लेकिन सरणी तत्व बस होंगे jData, नहींjData[key]
डेनिस द मेनेस

सिडेनोट: यदि आपका एपीआई एक बड़ी JSON प्रतिक्रिया देता है, तो आप इसे इस तरह प्रिंट कर सकते हैं: print(json.dumps(jData, indent=4, sort_keys=True))
Marco

2
Python3 के तहत, निम्नलिखित थूक था 'JSON को बाइट्स नहीं होना चाहिए'। यह आउटपुट को डिकोड करके तय किया गया है, अर्थात json.loads (myResponse.content.decode ('utf-8'))। इसके अलावा, आपको स्ट्रेट () के साथ की और जडाटा की को लपेटना चाहिए, ताकि जब RESTful API पूर्णांक देता है, तो यह शिकायत नहीं करता है।
मिरकुल्स

11

तो आप एक GET अनुरोध के शरीर में डेटा पास करना चाहते हैं, बेहतर होगा कि इसे POST कॉल में किया जाए। आप दोनों अनुरोधों का उपयोग करके इसे प्राप्त कर सकते हैं।

कच्चा अनुरोध

GET http://ES_search_demo.com/document/record/_search?pretty=true HTTP/1.1
Host: ES_search_demo.com
Content-Length: 183
User-Agent: python-requests/2.9.0
Connection: keep-alive
Accept: */*
Accept-Encoding: gzip, deflate

{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}

अनुरोध के साथ नमूना कॉल

import requests

def consumeGETRequestSync():
data = '{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}'
url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
headers = {"Accept": "application/json"}
# call get service with headers and params
response = requests.get(url,data = data)
print "code:"+ str(response.status_code)
print "******************"
print "headers:"+ str(response.headers)
print "******************"
print "content:"+ str(response.text)

consumeGETRequestSync()

वहाँ एक मृत लिंक मिला
user3157940

4
हेडर वैरिएबल का उपयोग किया जाना चाहिए: request.get (... हेडर = हेडर, ....)
मार्कस मेयर

9

नीचे अजगर में बाकी एपी को निष्पादित करने का कार्यक्रम है-

import requests
url = 'https://url'
data = '{  "platform": {    "login": {      "userName": "name",      "password": "pwd"    }  } }'
response = requests.post(url, data=data,headers={"Content-Type": "application/json"})
print(response)
sid=response.json()['platform']['login']['sessionId']   //to extract the detail from response
print(response.text)
print(sid)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.