Modify flag status if a condition is met

Question:

Below is a JSON output from an API microservice.

{
       "case": "2nmi",
       "id": "6.00c",
       "key": "subN",
       "Brand":[
         {
             "state": "Active",
             "name": "Apple",
             "date": "2021-01-20T08:35:33.382532",
             "Loc": "GA",
          },
          {
             "state": "Disabled",
             "name": "HP",
             "date": "2018-01-09T08:25:90.382",
             "Loc": "TX",
          },
          
          {
             "state": "Active",
             "name": "Acer",
             "date": "2022-01-2T8:35:03.5432",
             "Loc": "IO"
          },
          {
             "state": "Booted",
             "name": "Toshiba",
             "date": "2023-09-29T9:5:03.3298",
             "Loc": "TX"
          }
       ],
       "DHL_ID":"a3288ec45c82"
    }

#List holding the Laptop Brands

my_list = ["apple", "hp"]

I’m trying to come up with a script, to check, if items in the my_list list, is/are available as part of an API microservice’s streaming output(JSON), if so, validate whether, those item(apple/hp) is/are in Active state within a timeout of 10 minutes.
If a single item (either apple or hp) is not of Active state within 10 minutes, fail the script.

The state (Sales['state']) can vary like Active, Booted, Disabled and Purged and also, my_list can have any number of entries.

Unsure of logic, whether I should use multiple flags to check status of individual item in the list or manipulate the single flag accordingly.

def validate_status():
    all_brand_status = False # flag to check if all the Brand's state are Active.
    Sales = func_streaming_logs_json(args) # JSON output is captured from the microservice using this function.
    for sale in Sales['Brand']:
        if sale['name'].lower() in my_list and sale['state'] == "Active":
                all_brand_status = True
            else:
                print(f"{sale['name']} status: {sale['state']}") 
    return all_brand_status

# Timeout Function
def timeOut(T): 
    start_time = datetime.now()
    stop_time = start_time + timedelta(minutes=T)
    while True:
        success = validate_status()
        if success:
            print("say script is successful blah blah") 
            break
        start_time = datetime.now()
        if start_time > stop_time:
            print("Timeout")
            sys.exit(1)


if __name__ == '__main__':
    timeOut(10)
Asked By: voltas

||

Answers:

If you count the number of brands (that are in your list) that are Active then your condition is met if the count is equal to the length of my_list

from datetime import datetime, timedelta

SAMPLE = {
       "case": "2nmi",
       "id": "6.00c",
       "key": "subN",
       "Brand":[
         {
             "state": "Active",
             "name": "Apple",
             "date": "2021-01-20T08:35:33.382532",
             "Loc": "GA",
          },
          {
             "state": "Disabled",
             "name": "HP",
             "date": "2018-01-09T08:25:90.382",
             "Loc": "TX",
          },
          
          {
             "state": "Active",
             "name": "Acer",
             "date": "2022-01-2T8:35:03.5432",
             "Loc": "IO"
          },
          {
             "state": "Booted",
             "name": "Toshiba",
             "date": "2023-09-29T9:5:03.3298",
             "Loc": "TX"
          }
       ],
       "DHL_ID":"a3288ec45c82"
    }

ARGS = None
BRANDS = {'apple', 'hp'}

def func_streaming_logs_json(args=None):
    return SAMPLE

def validate_status():
    sales = func_streaming_logs_json(ARGS)
    assert isinstance(sales, dict)
    check = len(BRANDS)
    assert check > 0
    for item in sales.get('Brand', []):
        name = item.get('name', '')
        state = item.get('state', '')
        if name.lower() in BRANDS and state == 'Active':
            check -= 1
            if check == 0:
                return True
        else:
            print(f'{name} status: {state}')
    return False

def process(minutes):
    stop = datetime.now() + timedelta(minutes=minutes)
    while datetime.now() < stop:
        if validate_status():
            print('Success')
            break

if __name__ == '__main__':
    process(10)

Note:

The code shown here will "thrash" your CPU and never end. You need to adapt it by replacing the real implementation of func_streaming_logs_json()

Answered By: DarkKnight

Your code will return True as long as the last brand in Sales that is in my_list is Active. You should set all_brand_status = True initially and then set it to False if any brand in my_list is not Active.

def validate_status():
    all_brand_status = True # flag to check if all the Brand's state are Active.
    Sales = func_streaming_logs_json(args) # JSON output is captured from the microservice using this function.
    for sale in Sales['Brand']:
        if sale['name'].lower() in my_list and sale['state'] != "Active":
            all_brand_status = False
            print(f"{sale['name']} status: {sale['state']}") 
    return all_brand_status

Note you could also use all by manipulating the logic:

def validate_status():
    Sales = func_streaming_logs_json(args) # JSON output is captured from the microservice using this function.
    all_brand_status = all(sale['state'] == 'Active' for sale in Sales if sale['name'].lower() in my_list)
    return all_brand_status
Answered By: Nick
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.