@16_Bit: Auf Modulebene sollte wie schon erwähnt wurde keine Variablen stehen. Deshalb gehört auch der Code im ``if __name__ …``-Zweig in eine Funktion.
`headers` und das `json`-Modul brauchst Du nicht, denn `requests.post()` hat auch ein `json`-Argument welches das für Dich erledigt.
`set_params()` macht relativ wenig und ist Teil von etwas das bei den drei anderen Funktionen am Ende steht und überall eigentlich bis auf den Methodennamen in den Daten und die Parameter gleich ist.
Das was Du da immer `request` nennst ist genau das Gegenteil: `response`.
Man sollte die `response` auf Fehler testen.
`add_participants()` ist als Name falsch weil damit nur *ein* Teilnehmer hinzufügt werden kann.
Mal ein kleiner Ausschnitt aus dem Zwischenstand um zu sehen was aus `set_params()` geworden ist (`call()`) und wie kurz die anderen Funktionen dadurch werden:
Code: Alles auswählen
def call(method, params):
response = requests.post(
URL, json={"method": method, "params": params, "id": str(uuid4())}
)
response.raise_for_status()
return response.json()
def get_session_key():
return call(
"get_session_key", {"username": API_USER, "password": API_PASSWORD}
)["result"]
def release_session_key(session_key):
return call("release_session_key", {"sSessionKey": session_key})
...
Packen wir das in eine Klasse die eine Session repräsentiert und benennenen `release_session_key()` in ein traditionelleres `close()` um:
Code: Alles auswählen
class Session:
def __init__(self):
self.session_key = None
self.session_key = self.call(
"get_session_key", {"username": API_USER, "password": API_PASSWORD}
)["result"]
def call(self, method, params=None):
if self.session_key:
params["sSessionKey"] = self.session_key
response = requests.post(
URL,
json={
"method": method,
"params": params if params else {},
"id": str(uuid4()),
},
)
response.raise_for_status()
return response.json()
def close(self):
return self.call("release_session_key")
...
Bietet sich jetzt einfach an einen Kontextmanager aus dem Datentyp zu machen, damit man das Hauptprogramm so schreiben kann:
Code: Alles auswählen
def main():
with Session() as session:
session.add_participant(
SURVEY_ID,
CREATE_TOKEN,
TOKEN,
VALID_FROM,
VALID_UNTIL,
EMAIL,
LASTNAME,
FIRSTNAME,
)
Und jetzt mal alles, mit einem Teilnehmer beispielhaft zusammengefasst mit einer Klasse + `attr`-Modul (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
from uuid import uuid4
import requests
from attr import asdict, attrib, attrs
URL = "https://umfrage.de/index.php/admin/remotecontrol"
API_USER = "lsrc"
API_PASSWORD = "V&v3DNU#AwV4GJ"
SURVEY_ID = 928126
CREATE_TOKEN = False
VALID_FROM = ""
VALID_UNTIL = ""
EMAIL = "dieter.hallervorden@fun.de"
LASTNAME = "Hallervorden"
FIRSTNAME = "Dieter"
TOKEN = 1234567890
@attrs(frozen=True)
class Participant:
email = attrib()
lastname = attrib()
firstname = attrib()
token = attrib()
as_dict = asdict
@attrs
class Session:
session_key = attrib(default=None)
def __attrs_post_init__(self):
self.session_key = self.call(
"get_session_key", {"username": API_USER, "password": API_PASSWORD}
)["result"]
def __enter__(self):
return self
def __exit__(self, _exception_type, _value, _traceback):
self.close()
def call(self, method, params=None):
if self.session_key:
params["sSessionKey"] = self.session_key
response = requests.post(
URL,
json={
"method": method,
"params": params if params else {},
"id": str(uuid4()),
},
)
response.raise_for_status()
return response.json()
def add_participant(
self, survey_id, create_token, valid_from, valid_until, participant
):
return self.call(
"add_participants",
{
"iSurveyID": survey_id,
"aParticipantData": [participant.as_dict()],
"bCreateToken": create_token,
},
)
def close(self):
return self.call("release_session_key")
def main():
with Session() as session:
session.add_participant(
SURVEY_ID,
CREATE_TOKEN,
VALID_FROM,
VALID_UNTIL,
Participant(EMAIL, LASTNAME, FIRSTNAME, TOKEN),
)
if __name__ == "__main__":
main()