Wie die Abfrage eines restful webservice auf Basis von Python
Schreiben Sie ein Python-Skript, dass verwendet Anfragen lib Feuer aus einer Anfrage zu einem entfernten webservice. Hier ist mein code (test.py):
import logging.config
from requests import Request, Session
logging.config.fileConfig('../../resources/logging.conf')
logr = logging.getLogger('pyLog')
url = 'https://158.74.36.11:7443/hqu/hqapi1/user/get.hqu'
token01 = 'hqstatus_python'
token02 = 'ytJFRyV7g'
response_length = 351
def main():
try:
logr.info('start SO example')
s = Session()
prepped = Request('GET', url, auth=(token01, token02), params={'name': token01}).prepare()
response = s.send(prepped, stream=True, verify=False)
logr.info('status: ' + str(response.status_code))
logr.info('elapsed: ' + str(response.elapsed))
logr.info('headers: ' + str(response.headers))
logr.info('content: ' + response.raw.read(response_length).decode())
except Exception:
logr.exception("Exception")
finally:
logr.info('stop')
if __name__ == '__main__':
main()
Bekomme ich die folgende erfolgreiche Leistung, wenn ich dies ausführen:
INFO test - start SO example
INFO test - status: 200
INFO test - elapsed: 0:00:00.532053
INFO test - headers: CaseInsensitiveDict({'server': 'Apache-Coyote/1.1', 'set-cookie': 'JSESSIONID=8F87A69FB2B92F3ADB7F8A73E587A10C; Path=/; Secure; HttpOnly', 'content-type': 'text/xml;charset=UTF-8', 'transfer-encoding': 'chunked', 'date': 'Wed, 18 Sep 2013 06:34:28 GMT'})
INFO test - content: <?xml version="1.0" encoding="utf-8"?>
<UserResponse><Status>Success</Status> .... </UserResponse>
INFO test - stop
Wie Sie sehen können, gibt es diese komische variable 'response_length", die ich übergeben zu müssen, an das response-Objekt (optionales argument), um in der Lage sein, um den Inhalt Lesen. Diese variable muss gesetzt werden, um einen numerischen Wert, der gleich der Länge des 'content'. Dies bedeutet natürlich, dass ich brauche, um zu wissen, die Antwort- " content-length, bevor die hand, die unzumutbar ist.
Wenn ich mich nicht übergeben Sie die variable oder auf einen Wert größer als die Länge des Inhalts, bekomme ich die folgende Fehlermeldung:
Traceback (most recent call last):
File "\Python33\lib\http\client.py", line 590, in _readall_chunked
chunk_left = self._read_next_chunk_size()
File "\Python33\lib\http\client.py", line 562, in _read_next_chunk_size
return int(line, 16)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb4 in position 0: invalid start byte
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "test.py", line 22, in main
logr.info('content: ' + response.raw.read().decode())
File "\Python33\lib\site-packages\requests\packages\urllib3\response.py", line 167, in read
data = self._fp.read()
File "\Python33\lib\http\client.py", line 509, in read
return self._readall_chunked()
File "\Python33\lib\http\client.py", line 594, in _readall_chunked
raise IncompleteRead(b''.join(value))
http.client.IncompleteRead: IncompleteRead(351 bytes read)
Wie mache ich diese Arbeit ohne diese "response_length' variable?
Auch, gibt es bessere Möglichkeiten als 'Anforderungen' lib?
PS: dieser code ist ein unabhängiges script, und nicht in das Django-framework.
- Warum nicht mit den öffentlichen API-Anfragen? Sie basteln mit Interna, warum?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Verwenden Sie die öffentliche API anstelle von Interna und verlassen sich Gedanken über die Länge des Inhalts und Lesen in der Bibliothek:
oder, da
stream=True
verwenden, können Sie dieresp.raw
file-Objekt:oder
Wenn Sie muss haben eine Datei-wie-Objekt, dann
resp.raw
verwendet werden können (vorausgesetztstream=True
festgelegt ist, auf die Anfrage, wie oben beschrieben), aber dann verwenden Sie einfach.read()
Anrufe ohne eine Länge zu Lesen auf EOF.Wenn Sie jedoch nicht Abfragen einer Ressource, die benötigt man zum streamen (aber alles andere als eine große Datei request, eine Anforderung zu test-headers die ersten, oder ein web-service ist explizit dokumentiert, wie ein streaming-Dienst), lassen Sie einfach aus der
stream=True
und verwendenresp.content
oderresp.text
für-byte oder unicode-response-Daten.In das Ende, es scheint jedoch, dein server sendet chunked Antworten, sind fehlerhafte oder auch unvollständige; ein chunked transfer encoding beinhaltet die Länge der Daten für jeden Block und der server scheint zu Lügen, etwa ein Block der Länge oder senden, zu wenig Daten für ein bestimmtes Stück. Die decode-Fehler ist bloß die Folge der unvollständigen Daten gesendet wird.
http.client
Bibliothek von code, der reagiert auf einen server senden chunked Antworten, basierend auf den Header der server sendet. Ja, Sie verlangt, dass 351 bytes gelesen werden, aber das ist nicht die Ursache der unvollständigen Antwort Ausnahme.Server, die Sie anfordern nutzen "chunked" übertragen Codierung so dass es nicht einen content-length-header. Eine raw-Reaktion im chunked transfer-encoding enthält nicht nur den eigentlichen Inhalt, sondern auch chunks, ein chunk ist eine Zahl in hex, gefolgt von einem "\r\n" und es immer zu einem xml-oder json-parser-Fehler.
versuchen Sie verwenden: