I have a working script in (Locust/Python) shown below:
import json
# import requests
import base64
from locust import HttpUser, between, task
server_name = "https://xxx"
from_date = "2023-07-04T08:00:00.000Z"
to_date = "2023-07-04T09:00:00.000Z"
# url = f"https://{server_name}/api/SaveValues"
# Basic authentication:
username = "xxx"
password = "xxx"
auth_token = f"{username}:{password}"
# Encode the authentication token in base64:
auth_token_bytes = auth_token.encode("ascii")
auth_header = "Basic " + base64.b64encode(auth_token_bytes).decode("ascii")
headers={'X-API-KEY': 'xxx', 'Content-Type': 'application/json'}
# headers = {
# "Content-Type": "application/json",
# "Authorization": auth_header
# }
TS_IDs = {
'10158': 10,
'10159': 20,
'10174': 30,
'10182': 40,
'10185': 50,
'11016': 60,
'10479': 70,
'10482': 80
}
def get_data(ts_id, from_date, to_date, ts_value):
myjson = {
"id": int(ts_id),
"values": [
{
"from": from_date,
"to": to_date,
"value": ts_value
}
]
}
return myjson
class SaveValuesUser(HttpUser):
host = server_name
# wait_time = between(10, 15)
@task
def save_list_values(self):
data_list = []
for ts_id, ts_value in TS_IDs.items():
data = get_data(ts_id, from_date, to_date, ts_value)
data_list.append(data)
json_data = json.dumps(data_list, indent=2)
self.save_values(json_data)
def save_values(self, json_data):
print(type(json_data))
print(json_data)
# Make the PUT request with authentication:
response = self.client.put("/api/SaveValues", data=json_data, headers=headers)
# Check the response:
if response.status_code == 200:
print("SaveValues successful!")
print("Response:", response.json())
else:
print("SaveValues failed.")
print("Response:", response.text)
The script will do the for-loop (and construct the payload) for as many iterations as it is elements in the structure "TS_IDs".
However I want to make the number of times the for-loop runs "configurable" and hence the size of the payload configurable.
Looking at the "range" function in Python I would assume I could do this:
for ts_id, ts_value in range(3):
data = get_data(ts_id, from_date, to_date, ts_value)
data_list.append(data)
This results in this error:
[2023-08-18 09:00:21,361] N52820/ERROR/locust.user.task: cannot unpack non-iterable int object Traceback (most recent call last): File "C:\PythonScripting\Applications\Mambaforge\envs\_scripting310w\lib\site-packages\locust\user\task.py", line 347, in run self.execute_next_task() File "C:\PythonScripting\Applications\Mambaforge\envs\_scripting310w\lib\site-packages\locust\user\task.py", line 372, in execute_next_task self.execute_task(self._task_queue.pop(0)) File "C:\PythonScripting\Applications\Mambaforge\envs\_scripting310w\lib\site-packages\locust\user\task.py", line 493, in execute_task task(self.user) File "C:\PythonScripting\MyCode\pythonProject\SaveValues_FIXED.py", line 60, in save_list_values for ts_id, ts_value in range(3): TypeError: cannot unpack non-iterable int object
Any tips on how to make the script configurable with the number of times the for-loop should run and hence how "big" the payload would be?
You need to adjust your for loop, to actually iterate over your dictionary. To make the "payload" adjustable, you can count the number of iterations via enumerate
like this:
for i, (ts_id, ts_value) in enumerate(TS_IDs.items()):
if i > 3:
break
data = get_data(ts_id, from_date, to_date, ts_value)
data_list.append(data)
To add some more explanation: enumerate
will count the number of iterations in your for loop (represented by i
), break
will stop the for loop, and TS_IDs.items()
is used to access and iterate over the key-value pairs of your dictionary.