파이썬을 사용하여 RESTful API에 요청하기


221

EC2 인스턴스에서 Elasticsearch 구현을 사용하여 노출 된 RESTful API를 사용하여 콘텐츠 모음을 인덱싱합니다. 터미널 (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": {}
}'

어떻게 사용하여 API 요청으로 위의 설정 않습니다 python/requests또는 python/urllib2(- ... 더 나은 것을 요청한다 urllib2를 사용하고있다지만, 듣고 확인하는 하나 가지 않는)? 헤더 또는 다른 방식으로 전달합니까?

답변:


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)

종류 당신의 API 반환 응답, 당신은 다음 아마보고 싶지 무슨에 따라 response.text또는 response.json()(또는 아마도 검사 response.status_code첫번째). 빠른 시작 문서를 참조하십시오 여기에 , 특히 이 섹션을 .


3
나는 생각해야한다 : response = requests.post (url, data = data)
CK.Nguyen

8
"requests.get"은 "data"매개 변수를 사용하지 않습니다. 일반적으로 쿼리 문자열을 전달하는 dict 인 선택적 "params"매개 변수를 사용할 수 있습니다. 데이터를 가져 오기 위해 페이로드가 필요한 경우 (예 : 게시 된 예) "requests.post"를 사용해야합니다. 또한 "json"라이브러리를 사용하면 json 응답을보다 쉽게 ​​구문 분석 할 수 있습니다.
HVS 2016 년

4
@ParveenShukhala "요청은 공식적으로 Python 2.6–2.7 & 3.3–3.5를 지원하며 PyPy에서 훌륭하게 실행됩니다." - pypi.python.org/pypi/requests
다니오

2
보내는 JSON이므로 다음과 같은 데이터 대신 json 매개 변수를 사용할 수 있습니다. response = requests.post (url, json = data)
Mark Chorley

101

사용 요청JSON은 간단합니다.

  1. API 호출
  2. API가 JSON을 반환한다고 가정하면 json.loads함수를 사용하여 JSON 객체를 Python dict로 구문 분석하십시오.
  3. dict을 반복하여 정보를 추출하십시오.

요청 모듈은 성공과 실패를 반복하는 유용한 기능을 제공합니다.

if(Response.ok): API 호출의 성공 여부를 판단하는 데 도움이됩니다 (응답 코드-200).

Response.raise_for_status() API에서 반환 된 http 코드를 가져 오는 데 도움이됩니다.

다음은 이러한 API 호출을위한 샘플 코드입니다. 또한 github 에서 찾을 수 있습니다 . 이 코드는 API가 다이제스트 인증을 사용한다고 가정합니다. 이를 건너 뛰거나 다른 적절한 인증 모듈을 사용하여 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()

2
JSON 문서에 최상위 요소로 배열이있을 수 있으므로 키를 반복하는 마지막 부분이 항상 작동하지는 않습니다. 그래서, 그것을 얻는 것은 오류가 될 것입니다jData[key]
Denis The Menace

그것이 배열이라면 @DenisTheMenace, 어떻게 그것을 감쌀까요?
qasimalbaqali

@qasimalbaqali 사전을 반복하는 것과 같은 방법입니다. 그러나 배열 요소는 간단 jData하지 않습니다.jData[key]
Denis The Menace

참고 : API가 큰 JSON 응답을 반환하면 다음과 같이 인쇄 할 수 있습니다. print(json.dumps(jData, indent=4, sort_keys=True))
Marco

2
python3에서 다음은 'JSON은 바이트가 아니어야합니다.' 이것은 출력, 즉 json.loads (myResponse.content.decode ( 'utf-8'))를 디코딩하여 수정됩니다. 또한 RESTful API가 정수를 반환 할 때 키와 jData 키를 str ()로 감싸서 불평하지 않아야합니다.
Mirkules

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()

연결이
끊어졌습니다

4
headers 변수를 사용해야합니다 : requests.get (... headers = headers, ....)
Markus Meyer

9

아래는 파이썬에서 나머지 API를 실행하는 프로그램입니다.

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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.