Membuat permintaan ke RESTful API menggunakan python

221

Saya memiliki API TENANG yang telah saya paparkan menggunakan implementasi Elasticsearch pada contoh EC2 untuk mengindeks kumpulan konten. Saya dapat meminta pencarian dengan menjalankan yang berikut dari terminal saya (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": {}
}'

Bagaimana cara mengubah di atas menjadi permintaan API menggunakan python/requestsatau python/urllib2(tidak yakin mana yang harus dituju - telah menggunakan urllib2, tetapi mendengar bahwa permintaan lebih baik ...)? Apakah saya lulus sebagai tajuk atau tidak?

pengguna7289
sumber

Jawaban:

340

Menggunakan permintaan :

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)

Bergantung pada respons apa yang dikembalikan API Anda, Anda mungkin ingin melihat response.textatau response.json()(atau mungkin memeriksanya response.status_codeterlebih dahulu). Lihat dokumen mulai cepat di sini , terutama bagian ini .

andersschuller
sumber
3
saya pikir, itu harus: response = requests.post (url, data = data)
CK.Nguyen
8
"requests.get" tidak mengambil parameter "data". Itu bisa mengambil parameter "params" opsional yang biasanya merupakan dict yang membawa string kueri. Jika payload diperlukan untuk mengambil data (seperti contoh yang diposting dalam pertanyaan), maka "requests.post" perlu digunakan. Selain itu menggunakan pustaka "json" membuatnya lebih mudah untuk mem-parsing respons json.
HVS
4
@ParveenShukhala "Permintaan secara resmi mendukung Python 2.6–2.7 & 3.3–3.5, dan berjalan dengan baik di PyPy." - pypi.python.org/pypi/requests
danio
2
Karena JSON yang Anda kirim, Anda dapat menggunakan parameter json daripada data seperti: response = requests.post (url, json = data)
Mark Chorley
101

Menggunakan permintaan dan json membuatnya mudah.

  1. Panggil API
  2. Dengan asumsi API mengembalikan JSON, parsing objek JSON menjadi json.loadsfungsi menggunakan Python
  3. Lingkari dict untuk mengekstrak informasi.

Modul Permintaan memberi Anda fungsi yang berguna untuk mengulang kesuksesan dan kegagalan.

if(Response.ok): akan membantu Anda menentukan apakah panggilan API Anda berhasil (Kode respons - 200)

Response.raise_for_status() akan membantu Anda mengambil kode http yang dikembalikan dari API.

Di bawah ini adalah contoh kode untuk melakukan panggilan API semacam itu. Juga dapat ditemukan di github . Kode mengasumsikan bahwa API menggunakan otentikasi intisari. Anda dapat melewati ini atau menggunakan modul otentikasi lain yang sesuai untuk mengotentikasi klien yang memohon API.

#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()
HVS
sumber
2
Bagian terakhir dengan iterasi atas kunci tidak selalu berfungsi karena dokumen JSON mungkin memiliki larik sebagai elemen tingkat atas. Jadi, itu akan menjadi kesalahan untuk mencobajData[key]
Denis The Menace
@DenisTheMenace jika array, bagaimana saya akan memutarnya?
qasimalbaqali
@qasimalbaqali dengan cara yang sama Anda menggunakan kamus. Tetapi elemen array akan sederhana jData, bukanjData[key]
Denis The Menace
Sidenote: Jika API Anda mengembalikan respons JSON yang besar, Anda dapat mencetaknya seperti ini: print(json.dumps(jData, indent=4, sort_keys=True))
Marco
2
Di bawah python3, berikut ini diludahkan 'JSON harus str bukan byte'. Ini diperbaiki dengan mendekodekan output, yaitu json.loads (myResponse.content.decode ('utf-8')). Anda juga harus membungkus kunci dan kunci jData dengan str () sehingga ketika RESTful API mengembalikan bilangan bulat, itu tidak mengeluh.
Mirkules
11

Jadi, Anda ingin meneruskan data di badan permintaan GET, lebih baik melakukannya di panggilan POST. Anda dapat mencapai ini dengan menggunakan kedua Permintaan.

Permintaan Mentah

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": {}
}

Contoh panggilan dengan Permintaan

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()
gvir
sumber
mendapat tautan mati di sana
user3157940
4
variabel header harus digunakan: requests.get (... header = header, ....)
Markus Meyer
9

Di bawah ini adalah program untuk menjalankan api sisanya di python-

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)
Shashank G
sumber