Cannot (always) fetch an attribute in an object even though it exists

Question:

I’m currently developing locally an Azure function that communicates with Microsoft Sentinel, in order to fetch the alert rules from it, and more specifically their respective querys :

credentials = AzureCliCredential()
alert_rules_operations = SecurityInsights(credentials, SUBSCRIPTION_ID).alert_rules
list_alert_rules = alert_rules_operations.list(resource_group_name=os.getenv('RESOURCE_GROUP_NAME'), workspace_name=os.getenv('WORKSPACE_NAME'))

The issue is that when I’m looping over list_alert_rules, and try to see each rule’s query, I get an error:

Exception: AttributeError: 'FusionAlertRule' object has no attribute 'query'.

Yet, when I check their type via the type() function:

list_alert_rules = alert_rules_operations.list(resource_group_name=os.getenv(
        'RESOURCE_GROUP_NAME'), workspace_name=os.getenv('WORKSPACE_NAME'))
for rule in list_alert_rules:
     print(type(rule))
##console: <class 'azure.mgmt.securityinsight.models._models_py3.ScheduledAlertRule'>

The weirder issue is that this error appears only when you don’t print the attribute. Let me show you:

  • Print:
for rule in list_alert_rules:
     query = rule.query
     print('query', query)
##console: query YAY I GET WHAT I WANT
  • No print:
for rule in list_alert_rules:
     query = rule.query
        ...
##console: Exception: AttributeError: 'FusionAlertRule' object has no attribute 'query'.

I posted the issue on the GitHub repo, but I’m not sure whether it’s a package bug or a runtime issue. Has anyone ran into this kind of problems?

BTW I’m running Python 3.10.8

TIA!

EDIT:
I’ve tried using a map function, same issue:

def format_list(rule):
    query = rule.query
    # print('query', query)
    # query = query.split('n')
    # query = list(filter(lambda line: "//" not in line, query))
    # query = 'n'.join(query)
    return rule

def main(mytimer: func.TimerRequest) -> None:
    # results = fetch_missing_data()
    credentials = AzureCliCredential()
    alert_rules_operations = SecurityInsights(
        credentials, SUBSCRIPTION_ID).alert_rules
    list_alert_rules = alert_rules_operations.list(resource_group_name=os.getenv(
        'RESOURCE_GROUP_NAME'), workspace_name=os.getenv('WORKSPACE_NAME'))
    list_alert_rules = list(map(format_list, list_alert_rules))
Asked By: Fares

||

Answers:

I have tried with same as you used After I changed like below; I get the valid response.

# Management Plane - Alert Rules

alertRules = mgmt_client.alert_rules.list_by_resource_group('<ResourceGroup>')
for  rule  in  alertRules:
    # Try this
    test.query = rule.query //Get the result
    #print(rule)

if  mytimer.past_due:
    logging.info('The timer is past due!')

Instead of this

for rule in list_alert_rules:
     query = rule.query

Try below

for rule in list_alert_rules:
    # Try this
    test.query = rule.query

Sorry for the late answer as I’ve been under tons of work these last few days.

Python has an excellent method called hasattr that checks if the object contains a specific key.
I’ve used it in the following way:

for rule in rules:
    if hasattr(rule, 'query'):
       ...

The reason behind using this is because the method returns object of different classes, however inherited from the one same mother class.

Hope this helps.

Answered By: Fares