Fazer um pedido para uma API repousante usando python

tenho uma API repousante que expus usando uma implementação de pesquisa elastica numa instância EC2 para indexar um corpus de conteúdo. Posso consultar a pesquisa, executando o seguinte a partir do meu terminal (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": {}
}'

Como é que eu me transformo acima num pedido de API usando python/requests ou python/urllib2 (Não tenho a certeza de qual a pessoa a procurar - tem usado o urllib2, mas ouvir que os pedidos são melhores...)? Passo de cabeça ou não?

Author: katericata, 2013-06-25

4 answers

Usando pedidos:

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)

Dependendo do tipo de resposta que a sua API devolve, provavelmente irá querer olhar para response.text ou response.json() (ou, possivelmente, inspeccionar response.status_code primeiro). Veja os documentos de arranque rápido aqui , especialmente Esta secção.

 216
Author: andersschuller, 2017-05-28 03:33:39

Usandopedidos eJSON torna as coisas simples.

  1. chama a API
  2. assumindo que a API devolve um JSON, divide o objecto JSON num Dict em Python usando a função json.loads
  3. Passar pelo dict para extrair informações.

O módulo Requests oferece-lhe uma função útil para o sucesso e a falha.

if(Response.ok): irá ajudá - lo a determinar se a sua chamada da API foi bem sucedida (código de resposta-200)

Response.raise_for_status() irá ajudá-lo a obter o código http que é devolvido da API.

Abaixo está um código de exemplo para fazer tais chamadas de API. Também pode ser encontrado em github . O código assume que a API faz uso da autenticação digest. Você pode ignorar isso ou usar outros módulos de autenticação apropriados para autenticar o cliente invocando a 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()
 73
Author: HVS, 2015-09-22 16:23:57
Então, se quiser passar dados no corpo de um pedido de obtenção, melhor seria fazê-lo no post call. Você pode conseguir isso usando ambos os Pedidos.

Pedido Em Bruto

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

Recolha de amostras com pedidos

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()
 9
Author: gvir, 2018-05-27 18:43:07

Abaixo está o programa para executar o resto da api em 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)
 6
Author: Shashank G, 2017-05-18 10:12:47