【问题标题】:Making a request to a RESTful API using python使用 python 向 RESTful API 发出请求
【发布时间】:2013-06-22 12:31:32
【问题描述】:

我有一个 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/requestspython/urllib2 将上述请求转换为API 请求(不确定该选择哪一个- 一直在使用urllib2,但听说请求更好......)?我是作为标题传递还是以其他方式传递?

【问题讨论】:

    标签: python elasticsearch rest


    【解决方案1】:

    使用requests

    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.textresponse.json()(或者可能首先检查response.status_code)。请参阅快速入门文档here,尤其是this section

    【讨论】:

    • @ParveenShukhala “Requests 正式支持 Python 2.6–2.7 和 3.3–3.5,并且在 PyPy 上运行良好。” -- pypi.python.org/pypi/requests
    • 由于您发送的是 JSON,因此您可以使用 json 参数而不是像这样的数据:response = requests.post(url, json=data)
    【解决方案2】:

    使用requestsjson 让事情变得简单。

    1. 调用 API
    2. 假设 API 返回一个 JSON,将 JSON 对象解析为 Python dict 使用json.loads 函数
    3. 遍历字典以提取信息。

    Requests 模块为您提供有用的函数来循环成功和失败。

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

    【讨论】:

    • 对键进行迭代的最后部分并不总是有效,因为 JSON 文档可能将数组作为顶级元素。因此,尝试获取jData[key] 将是错误的
    • @DenisTheMenace 如果它是一个数组,我将如何循环它?
    • @qasimalbaqali 与遍历字典的方式相同。但是数组元素只是jData,而不是jData[key]
    • 旁注:如果您的 API 返回较大的 JSON 响应,您可以像这样打印它:print(json.dumps(jData, indent=4, sort_keys=True))
    • 在python3下,吐出'JSON must be str not bytes'。这可以通过解码输出来解决,即 json.loads(myResponse.content.decode('utf-8'))。你也应该用 str() 包装 key 和 jData 键,所以当 RESTful API 返回整数时,它不会抱怨。
    【解决方案3】:

    因此,您想在 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()
    

    【讨论】:

    • 那里有一个死链接
    • headers 变量应该被使用:requests.get(...headers = headers, ....)
    【解决方案4】:

    下面是python中执行rest 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)
    

    【讨论】:

      猜你喜欢
      • 2014-02-23
      • 2022-01-12
      • 1970-01-01
      • 2015-01-26
      • 1970-01-01
      • 2018-07-05
      • 2014-04-16
      • 1970-01-01
      • 2013-10-15
      相关资源
      最近更新 更多