pythonlocust

For loop configuration in Locust/Python


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