ā04-13-2020 11:34 AM - edited ā04-13-2020 11:36 AM
Hi there,
I'm digging my way through the queries with Cobra SDK and I'm getting stuck on how to extract a Json formatted output from a query. This is easily done when you push a new config using toJSONStr from jsoncodec in both cobra and ACI-toolkit but I'm not sure on how this can be done when you query the actual config on a fabric. My purpose is to be able to automate Json formatted config download from a certain number of elements/tenants without using the usual GUI right click "save as". This is my query sample with Cobra (ACI-toolkit produces similar situation):
import cobra.mit.access import cobra.mit.request import cobra.mit.session import cobra.model.fv import cobra.model.pol #from cobra.internal.codec.xmlcodec import toXMLStr from cobra.internal.codec.jsoncodec import toJSONStr from credentials import * # set login session session = cobra.mit.session.LoginSession(URL, LOGIN, PASSWORD) # set object directory moDir = cobra.mit.access.MoDirectory(session) # submit login moDir.login() # filter class cq = cobra.mit.request.ClassQuery('fvTenant') # set subtree to full cq.subtree = 'full' # set property filter to tenant name cq.propFilter = 'eq(fvTenant.name, "My_Tenant")' # submit query tnt = moDir.query(cq) #print print(toJSONStr(tnt))
Which gives the following output:
AttributeError: 'listWithTotalCount' object has no attribute 'meta'
I take it the code is obviously wrong. I've been trying with json.dumps as well for the sake of it but the outcome it is simply an empty []
Any hint would be greatly appreciated.
Thanks!
Solved! Go to Solution.
ā04-13-2020 11:39 PM
#print print(toJSONStr(tnt))
---------------
Checking the objects around, it seems this is a generator of the MO objects, that we could use the iteration to list MO object.
I tried the following and it seems to work.
print([json.loads(toJSONStr(mo)) for mo in tnt])
or
for mo in tnt:
print(json.loads(toJSONStr(mo))
ā04-14-2020 07:21 AM
Hi @m.papini
Typically, the query will return an object.
For example, with the ACI-Toolkit a tenant query like this
# Download all of the tenants tenants = ACI.Tenant.get(session)
gets you a list of Tenant objects like <acitoolkit.acitoolkit.Tenant object at 0x10bae8c18>,
print the tenant variable which is of type <class 'list'> [<acitoolkit.acitoolkit.Tenant object at 0x10bae8c18>, <acitoolkit.acitoolkit.Tenant object at 0x10c0ef128>, <acitoolkit.acitoolkit.Tenant object at 0x10c0ef160>, <acitoolkit.acitoolkit.Tenant object at 0x10c0d3828>, <acitoolkit.acitoolkit.Tenant object at 0x10c0d37f0>, <acitoolkit.acitoolkit.Tenant object at 0x10c0d37b8>, <acitoolkit.acitoolkit.Tenant object at 0x10c0d3780>, <acitoolkit.acitoolkit.Tenant object at 0x10c0d3748>, <acitoolkit.acitoolkit.Tenant object at 0x10c0a9320>, <acitoolkit.acitoolkit.Tenant object at 0x10c0a9390>, <acitoolkit.acitoolkit.Tenant object at 0x10c0ef198>, <acitoolkit.acitoolkit.Tenant object at 0x10c0ef1d0>]
Each of those Tenant objects has the methods below (one of which is .name). To do this you can just use the dir method on the object. Because you get back a list used the first element in the list (the first tenant object) and ran it through dir.
print(dir(response_list[0]))
lets see methods with dir: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_add_relation', '_attachments', '_check_attachment', '_check_relation', '_children', '_dedup_searchables', '_define_searchables', '_deleted', '_extract_relationships', '_generate_attributes', '_get_all_detached_relation', '_get_all_relation', '_get_all_relations_by_class', '_get_any_relation', '_get_apic_classes', '_get_children_classes', '_get_children_concrete_classes', '_get_instance_subscription_urls', '_get_name_dn_delimiters', '_get_name_from_dn', '_get_parent_class', '_get_parent_dn', '_get_parent_from_dn', '_get_starting_name_delimiter', '_get_subscription_urls', '_get_toolkit_to_apic_classmap', '_get_url_extension', '_has_any_relation', '_has_relation', '_instance_get_event', '_instance_get_subtree_faults', '_instance_has_events', '_instance_has_subtree_faults', '_instance_subscribe', '_instance_unsubscribe', '_parent', '_populate_from_attributes', '_relations', '_remove_all_relation', '_remove_attachment', '_remove_relation', '_session', '_tags', 'add_child', 'add_tag', 'attach', 'check_session', 'delete_tag', 'descr', 'detach', 'dn', 'exists', 'find', 'get', 'get_all_attached', 'get_all_attachments', 'get_attributes', 'get_child', 'get_children', 'get_deep', 'get_deep_apic_classes', 'get_dn_from_attributes', 'get_event', 'get_fault', 'get_from_json', 'get_interfaces', 'get_json', 'get_parent', 'get_searchable', 'get_table', 'get_tags', 'get_url', 'has_attachment', 'has_child', 'has_detachment', 'has_events', 'has_parent', 'has_tag', 'has_tags', 'info', 'infoList', 'is_attached', 'is_deleted', 'is_detached', 'is_interface', 'mark_as_deleted', 'mask_class_from_graphs', 'name', 'populate_children', 'push_to_apic', 'remove_child', 'remove_tag', 'set_parent', 'subscribe', 'subscribe_to_fault_instances_subtree', 'unsubscribe', 'update_db']
Note that one of the methods is āget_jsonā
print(f"\nlets use the get_json method on one of the objects") print(tenants[0].get_json())
This gives us the JSON payload you would want to use to push updates.
lets use the get_json method on one of the objects:
{'fvTenant': {'attributes': {'name': 'infra'}, 'children': []}}
To iterate over the tenants in the list and print their name you can use the .name method:
for tenant in tenants: print(tenant.name)
My suggestion is to use the API Inspector to develop your payload templates.
ā04-13-2020 11:39 PM
#print print(toJSONStr(tnt))
---------------
Checking the objects around, it seems this is a generator of the MO objects, that we could use the iteration to list MO object.
I tried the following and it seems to work.
print([json.loads(toJSONStr(mo)) for mo in tnt])
or
for mo in tnt:
print(json.loads(toJSONStr(mo))
ā04-16-2020 02:57 PM
ā04-14-2020 07:21 AM
Hi @m.papini
Typically, the query will return an object.
For example, with the ACI-Toolkit a tenant query like this
# Download all of the tenants tenants = ACI.Tenant.get(session)
gets you a list of Tenant objects like <acitoolkit.acitoolkit.Tenant object at 0x10bae8c18>,
print the tenant variable which is of type <class 'list'> [<acitoolkit.acitoolkit.Tenant object at 0x10bae8c18>, <acitoolkit.acitoolkit.Tenant object at 0x10c0ef128>, <acitoolkit.acitoolkit.Tenant object at 0x10c0ef160>, <acitoolkit.acitoolkit.Tenant object at 0x10c0d3828>, <acitoolkit.acitoolkit.Tenant object at 0x10c0d37f0>, <acitoolkit.acitoolkit.Tenant object at 0x10c0d37b8>, <acitoolkit.acitoolkit.Tenant object at 0x10c0d3780>, <acitoolkit.acitoolkit.Tenant object at 0x10c0d3748>, <acitoolkit.acitoolkit.Tenant object at 0x10c0a9320>, <acitoolkit.acitoolkit.Tenant object at 0x10c0a9390>, <acitoolkit.acitoolkit.Tenant object at 0x10c0ef198>, <acitoolkit.acitoolkit.Tenant object at 0x10c0ef1d0>]
Each of those Tenant objects has the methods below (one of which is .name). To do this you can just use the dir method on the object. Because you get back a list used the first element in the list (the first tenant object) and ran it through dir.
print(dir(response_list[0]))
lets see methods with dir: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_add_relation', '_attachments', '_check_attachment', '_check_relation', '_children', '_dedup_searchables', '_define_searchables', '_deleted', '_extract_relationships', '_generate_attributes', '_get_all_detached_relation', '_get_all_relation', '_get_all_relations_by_class', '_get_any_relation', '_get_apic_classes', '_get_children_classes', '_get_children_concrete_classes', '_get_instance_subscription_urls', '_get_name_dn_delimiters', '_get_name_from_dn', '_get_parent_class', '_get_parent_dn', '_get_parent_from_dn', '_get_starting_name_delimiter', '_get_subscription_urls', '_get_toolkit_to_apic_classmap', '_get_url_extension', '_has_any_relation', '_has_relation', '_instance_get_event', '_instance_get_subtree_faults', '_instance_has_events', '_instance_has_subtree_faults', '_instance_subscribe', '_instance_unsubscribe', '_parent', '_populate_from_attributes', '_relations', '_remove_all_relation', '_remove_attachment', '_remove_relation', '_session', '_tags', 'add_child', 'add_tag', 'attach', 'check_session', 'delete_tag', 'descr', 'detach', 'dn', 'exists', 'find', 'get', 'get_all_attached', 'get_all_attachments', 'get_attributes', 'get_child', 'get_children', 'get_deep', 'get_deep_apic_classes', 'get_dn_from_attributes', 'get_event', 'get_fault', 'get_from_json', 'get_interfaces', 'get_json', 'get_parent', 'get_searchable', 'get_table', 'get_tags', 'get_url', 'has_attachment', 'has_child', 'has_detachment', 'has_events', 'has_parent', 'has_tag', 'has_tags', 'info', 'infoList', 'is_attached', 'is_deleted', 'is_detached', 'is_interface', 'mark_as_deleted', 'mask_class_from_graphs', 'name', 'populate_children', 'push_to_apic', 'remove_child', 'remove_tag', 'set_parent', 'subscribe', 'subscribe_to_fault_instances_subtree', 'unsubscribe', 'update_db']
Note that one of the methods is āget_jsonā
print(f"\nlets use the get_json method on one of the objects") print(tenants[0].get_json())
This gives us the JSON payload you would want to use to push updates.
lets use the get_json method on one of the objects:
{'fvTenant': {'attributes': {'name': 'infra'}, 'children': []}}
To iterate over the tenants in the list and print their name you can use the .name method:
for tenant in tenants: print(tenant.name)
My suggestion is to use the API Inspector to develop your payload templates.
ā04-16-2020 03:02 PM
Thanks Claudia, I did run into that output using the Toolkit and with your input now I'm able to dissect that entirely, very helpful.
Thanks a million.
Regards,
Massimo
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide