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?
>Solution :
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 (here after the third iteration), and TS_IDs.items() is used to access and iterate over the key-value pairs of your dictionary.