Python TextFSM template for parsing CLI output - python

I have CLI output from FortiGate looks like
edit "Company_1"
set member "Member_1"
next
edit "Company_2"
set member "Member_3" "Member_2" "Member_6" "Member_10"
next
edit "Company_3"
set member "Member_4" "Member_9" "Member_5" "Member_8" "Member_7" "Member_N"
next
I tried to write a template
Value Filldown company (\S*)
Value List member (\S*)
Start
^.\s+edit\s+"${company}" -> Continue.Record
^.\s+set\s+member\s+"${member}"\s+ -> Continue
but can get only the first element from each Company.
[
{
"company": "Company_1",
"group": [
"member_1"
]
},
{
"company": "Company_2",
"group": [
"member_3"
]
}
]
How I can do 'foreach' in string? I would like to get a result below
Company_1: [Member_1]
Company_2: [Member_3 Member_2 Member_6 Member_10]
Company_3: [Member_4 Member_9 Member_5 Member_8 Member_7 Member_N]
or better like this
Company_1: Member_1
Company_2: Member_3
Company_2: Member_2
Company_2: Member_6
Company_2: Member_10
....

Related

Parse the inside json data of all variables

Im working on big json data . In every data set ther will be Name,Type,Value. Im actually need to parse the all type which as equal to "Shirt". I don't know to parse the inside json data.
x={
"Data": "Ecommerce",
"Host":{
"Items": [
[
{
"Name": "cot",
"Value": 99,
"Type": "Shirt"
},
{
"Name": "ploy",
"Value": 90,
"Type": "Pant"
},
{
"Name": "lyc",
"Value": 22,
"Type":"Shirt"
}
]
],
}}
k=x.get("Host")
print(k)
The above code will Display all data inside the Host.
What I'm trying to get output as parse only the Type: Shirt and Value of the Shirt .
I tried with some Def ,loop concepts but i can't able to achieve my output.
Output I'm looking for :-
If Type = Shirt , need parse that json data
Cot:90
Lyc:22
In dict format
This shows how to access the data. I assume you can change this to create a dictionary.
for item in x['Host']['Items'][0]:
if item['Type'] == 'Shirt':
print(item['Name'],':',item['Value'])
This is an example to do it with short for
items = x["Host"]["Items"]
shirt_values = {item["Name"]: item["Value"] for sublist in items for item in sublist if item["Type"] == "Shirt"}

SQLAlchemyObjectType.Meta two models graphene

I am trying to combine two SQLAlchemyConnectionField. The current error i face is graphql.error.base.GraphQLError: Expected value of type "PostsObject" but got: Tag
My current connections are defined like so posts = SQLAlchemyConnectionField(PostsObject.connection, /* input arguments like posts(name: "") */) Is there a way to add another type or allow to return something like
"data": {
"posts": {
"edges": [
{
"node": "Different table"
},
{
"node": "Other table"
}]}},
I am using graphene_sqlalchemy well anyway thats all thanks !

Save reference to a python dictionary (from a json file) item in a variable

I'm trying to save the reference to a value in a json file where item orders could not be guaranteed. So far, what I have for a dataset like this one:
"Values": [
{
"Object": "DFC_Asset_05",
"Properties": [
{
"Property": "WeightKilograms",
"Value Offset": 5
},
{
"Property": "WeightPounds",
"Value Offset": 10
}
]
},
{
"Object": "DFC_Asset_05",
"Properties": [
{
"Property": "Name",
"Value Offset": 25
},
{
"Property": "ShortName",
"Value Offset": 119
}
]
}
]
and retrieving this object:
{
"Property": "ShortName",
"Value Offset": 119
}
Is a string like this:
reference = "[Object=DFC_Asset_06][Properties][Property=Name]"
Which looks nice and understandable in a string, but it's very unclean to find the referenced value as I must first parse the reference it with a regex then loop in the data to retrieve the matching item.
Am I doing this wrong? Is there a better way to do this? I looked at the reduce() function however it seems like it's made for dictionaries with static data. For example, I could not save the direct keys:
reference = "[1][Properties][1]"
reference_using_reduce = [1, "Properties", 1]
As they might not always be in that order
You can run "queries" on JSONs without referencing specific indexes using the pyjq module:
query = (
'.Values[]' # On all the items in "Values"
'|select(."Object" == "DFC_Asset_06")' # Find key "Object" which holds this value
'|."Properties"[]' # And get all the items of "Properties"
'|select(."Property" == "Name")' # Where the key "Property" holds the value "Name"
)
pyjq.first(query, d)
Result:
{'Property': 'Name', 'Value Offset': 25}
You can read more about jq in the documentations.

Comparing value in a JSON using Python

I receive a fairly uncomfortable JSON to work with, which looks as follows:
[
{
"attributes": [
{
"type": "COMMAND",
"name": "COMMAND",
"value": [
"buttonState"
]
},
{
"type": "std_msgs.msg.Bool",
"name": "buttonState",
"value": {
"data": false
}
}
],
"type": "sensor",
"id": "s_2"
}]
And I would like to compare a piece of data (more precisely - value of Button state) but I seem to fail. Tried following:
import requests
import json
yo = 1
switchPost = "http://192.168.0.104:7896/iot/d?k=123456789&i=san_1_switch&d=sw|{}"
robGet = "http://192.168.0.109:10100/robot/sen_2"
r = requests.get(robGet, headers={"content-type":"application/json"})
resp = json.loads(r.text)
for attrs in (resp['attributes']['value']):
if attrs['data'] == false:
yo = 100
break
g = requests.post(switchPost.format(yo), headers={"content-type":"text/plain"})
print(r.text)
Unfortunately, the error I receive is the following:
for attrs in (resp['attributes']['value']):
TypeError: list indices must be integers, not str
In your JSON, the fact that it is wrapped in [ then ] means it is a JSON array, but with just one element.
So, as your error message suggests, resp needs an integer as its index, for which element of the array you want. resp[0] then refers to
{
"attributes": [
{
"type": "COMMAND",
"name": "COMMAND",
"value": [
"buttonState"
]
},
{
"type": "std_msgs.msg.Bool",
"name": "buttonState",
"value": {
"data": false
}
}
],
"type": "sensor",
"id": "s_2"
}
(notice no [] now, so it's a JSON object)
Then you want resp[0]['attributes'] to refer to the single part of this object, 'attributes' which again refers to an array.
Therefore for attribute in resp[0]['attributes'] will allow you to loop through this array.
To get the boolean value you want, you'll then want to find which element of that array has 'name' of 'buttonState' and check the corresponding 'value'.
In all, you're probably looking for something like:
for attribute in resp[0]['attributes']:
if attribute['name'] == 'buttonState' and attribute['value']['data'] is False:
# Do your thing here
resp is a list so, to get first element, access it as resp[0]. Same with resp[0]['attributes']
So you can access it as follows
resp[0]['attributes'][0]['value']
You can restructure your for loop as follows
for d in resp[0]['attributes']:
if isinstance(d['value'], dict) and d['value'].get('data') == false:
yo = 100
break
The answer is in the error message I think:
TypeError: list indices must be integers, not str
The first entry in attributes has a value that is a list, so you can't get 'data' from that.
Since you have a mix of types, you might need to check if 'value' is a list or a dict.
Edit:
Jumped the gun here I think. #dennlinger gives an explanation to your error message. But you'll get it again once you're past that...

Parse Json data

a= [{
"data" : {
"check": true,
},
"AMI": {
"status": 1,
"firewall":{
"status": enable
},
"d_suffix": "x.y.com",
"id": 4
},
"tags": [ #Sometime tags could be like "tags": ["default","auto"]
"default"
],
"hostname": "abc.com",
}
]
How to get a hostname on the basis of tags?I am trying to implement it using
for i in a:
if i['tags'] == 'default':
output = i['hostname']
but it's failing because 'tags' is a list which is not mapping to hostname key.Is there any way i can get hostname on the basis of 'tags'?
Use in to test if something is in a list. You also need to put default in quotes to make it a string.
for i in a:
if 'default' in i['tags']:
output = i['hostname']
break
If you only need to find one match, you should break out of the loop once you find it.
If you need to find multiple matches, use #phihag's answer with the list comprehension.
To get all hostnames tagged as default, use a list comprehension:
def_hostnames = [i['hostname'] for i in a if 'default' in i['tags']]
print('Default hostnames: %s' % ','.join(def_hostnames))
If you only want the first hit, either use def_hostnames[0] or the equivalent generator expression:
print('first: %s' % next(i['hostname'] for i in a if 'default' in i['tags']))
Your current code fails because it uses default, which is a variable named default. You want to look for a string default.
Make sure that you have everything in Json format like
a= [{
"data" : {
"check": True,
},
"AMI": {
"status": 1,
"firewall":{
"status": "enable"
},
"d_suffix": "x.y.com",
"id": 4
},
"tags": [
"default"
],
"hostname": "abc.com",
}
]
and then you can easily get it by using in
for i in a:
if 'default' in i['tags']:
output = i['hostname']

Categories