Ich habe eine API-Prozedur geschrieben, um das Senden an eine HTTP-RestAPI mit JwToken-Authentifizierung zu testen. In diesem Szenario ist es für das Patientenmanagementsystem und ich erstelle einen Termin. Die API-Geschäftsregel lässt keine doppelten Buchungen für die gleiche Zeit zu.Python-Postanforderungen an HTTP-RestAPI mit JwToken-Authentifizierung generiert doppelte Posts
Ich benutze eine Python 3.5.3 Virtual Environment (schreiben in pycharm IDE) und führen meine Tests mit dem Pytest Rahmen arbeiten. Auch mit PyJWT 1.5.2. , Anfragen 2.18.3, simplejson 3.11.1 und urllib3 1.22 ist installiert (ich nehme an, Anfragen verwendet urllib3). Ich benutze simplejson.dumps anstelle der normalen json.dumps, weil die virtuelle Umgebung diese Bibliothek nicht hatte und ich Schwierigkeiten hatte, sie hinzuzufügen. Soweit ich sagen kann, hat simplejson die gleiche Funktionalität für die Dump-Prozedur.
Mit dem unten stehenden Code kann ich Requests.post Aufruf ausführen, um eine Json-Datennutzdaten erfolgreich zu liefern und einen Post zu generieren, aber dann scheint es anschließend einen zweiten Post durchzuführen, der einen 409 Konfliktfehler generiert. Ich habe Zugang zu einer Protokolldatenbank auf dem entsprechenden API-Server und kann sehen, dass es tatsächlich versucht hat, zweimal zu posten, aber ich kann nicht herausfinden, warum dies geschieht, und ich denke, dass etwas in der Anforderungsbibliothek zweimal aufgerufen wird . Möglicherweise wegen der Json, die ich poste.
Die Ausgabe sieht wie folgt aus:
https://targerserver.url.com.au/API/Core/v2.1/appointment/
200
{'statusMessages': [], 'appointment': {'startDateTime': '2017-08-15T11:00:00 +10:00', 'appointmentReferenceNumber': '39960337', 'notes': '', 'clients': [{'clientId': 'abeff2be-ce6e-4324-9b57-e28ab7967b6c'}], 'status': 'Booked', 'locationId': 'd8d4fe7c-765a-46a3-a389-54ce298a27e9', 'notifyPractitioner': False, 'endDateTime': '2017-08-15T11:30:00 +10:00', 'subject': 'Jim Beam ', 'appointmentId': '08b37ce3-25e1-4e2a-9bb7-9ec2d716f83b', 'practitioner': {'practitionerId': 'a630f4ad-8b4b-4e06-8cee-7db56ba8b9bf'}}}
collected 1 item
test_PMSAPI_availability.py https://targerserver.url.com.au/API/Core/v2.1/appointment/
409
Mein Json erfordert ein Objekt (das ein Wörterbuch ist) und auch eine Liste der Schlüssel für ein anderes Feld (das hat einen Eintrag in es) und ich frage mich, wenn die Anforderungsbibliothek dies nicht verarbeitet. Dies ist ein Beispiel, was die json sieht aus wie
payload_str = {"startDateTime":"2017-08-15T11:00+10:00","endDateTime":"2017-08-15T11:30+10:00","practitioner": {"practitionerId":"a630f4ad-8b4b-4e06-8cee-7db56ba8b9bf"}, "locationId":"d8d4fe7c-765a-46a3-a389-54ce298a27e9","clients":[{"clientId":"abeff2be-ce6e-4324-9b57-e28ab7967b6c"}]}
ich ähnlichen Code haben, der für Get Anrufe auf dem gleichen System gearbeitet hat, aber Entsendung der Json wirklich problematisch zu sein scheint. Wir haben andere Tools, um Aufrufe an die gleichen API-Endpunkte zu senden, die diese Probleme nicht zu haben scheinen. Die Protokolle würden vorschlagen, dass die JSON-Daten, die ich liefere, mit denen eines anderen Tools mit denselben Daten identisch sind.
Was ich von der Ausgabe sehen kann, ist, dass ein erfolgreicher 200-Code auf die erste Antwort erhalten wird, aber wenn Abfrage response.status_code es 409 Antwort geworden ist. Ich habe auch versucht, nichts mit der Antwort zu tun, falls dies dazu führte, dass die Anfrage erneut angefordert und der Konflikt erzeugt wurde.
Mein Code sieht wie folgt aus:
import jwt
import _datetime
import requests
import simplejson
from requests.packages.urllib3.exceptions import InsecureRequestWarning
from string import Template
def app_undertest_credentials(keyname):
app_credentials = {'app_consumer_id': 'MyTestApp',
'app_consumer_secret': 'where my secret goes',
'app_access_token': 'where my access token goes',
'base_url': 'https://targerserver.url.com.au'
}
return app_credentials.get(keyname)
def end_points_dict(keynameStr, versionStr):
end_points = {'location': '/API/Core/$version/location/',
'practitioner': '/API/Core/$version/practitioner/',
'availabilityslot': '/API/Core/$version/AvailabilitySlot/',
'client': '/API/Core/$version/client/',
'healthfundproviderlist': '/API/Core/$version/healthfundproviderlist/',
'timezone': '/API/Core/$version/timezone/',
'clientgroup': '/API/Core/$version/clientgroup/',
'appointment': '/API/Core/$version/appointment/'
}
lower_keynameStr = keynameStr.lower()
url_extension_no_version = Template(end_points.get(lower_keynameStr))
url_extension_with_version = url_extension_no_version.safe_substitute(version=versionStr)
return url_extension_with_version
def test_api_appointment_post():
# Set Client app credentials
app_consumer_id = app_undertest_credentials('app_consumer_id')
app_consumer_secret = app_undertest_credentials('app_consumer_secret')
app_access_token = app_undertest_credentials('app_access_token')
base_url = app_undertest_credentials('base_url')
end_point_url_sfx_str = end_points_dict('Appointment', 'v2.1')
httpmethod = 'POST'
# Create dictionary for json post payload
data_payload = {'startDateTime':'2017-08-15T11:00+10:00',
'endDateTime':'2017-08-15T11:30+10:00',
'practitioner': {'practitionerId':'a630f4ad-8b4b-4e06-8cee-7db56ba8b9bf'},
'locationId': 'd8d4fe7c-765a-46a3-a389-54ce298a27e9',
'clients': [{'clientId':'abeff2be-ce6e-4324-9b57-e28ab7967b6c'}]
# Create claims dictionary payload for generation of JwToken
claims = {
'iss': 'http://myappsdomain.com.au',
'aud': 'https://targetservers.domain.com.au',
'nbf': _datetime.datetime.utcnow(),
'exp': _datetime.datetime.utcnow() + _datetime.timedelta(seconds=60),
'consumerId': app_consumer_id,
'accessToken': app_access_token,
'url': base_url + end_point_url_sfx_str,
'httpMethod': http_method
}
#create jwtoken and then convert to string
encoded_jwt_byte = jwt.encode(claim_payload, app_consumer_secret, algorithm='HS256')
jwt_str = encoded_jwt_byte.decode()
#Create authentication header
headers = {'Authorization': 'JwToken' + ' ' + jwt_str, 'content-type': 'application/json'}
uri = base_url + end_point_url_sfx_str
response = requests.post(uri, headers=headers, json=datapayload)
print(response.status)
print(response.json())
response.close()
Ich bin angesichts wireshark mit meinem Anruf, um herauszufinden, was tatsächlich zu senden, aber ich vermute, dass mir nur sagen, dass die Anrufe zweimal gesendet werden
[Bearbeiten] Ihre Frage, mit welchem Python-Modul und Version Sie verwenden, entweder 'python_jwt' oder 'pyjwt'? – stovfl
Ich habe in dem anderen Modul hinzugefügt Versionen in Verwendung PyJWT 1.5.2., Anfragen 2.18.3, simplejson 3.11.1 und urllib3 1.22 – Roochiedoor