Path: csiph.com!usenet.pasdenom.info!goblin2!goblin.stu.neva.ru!newsfeed.xs4all.nl!newsfeed1a.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'python,': 0.02; 'tutorial': 0.03; 'output': 0.05; 'true,': 0.05; 'interpreter.': 0.07; 'layers': 0.07; 'nested': 0.07; 'none,': 0.07; 'puts': 0.07; 'referring': 0.07; 'variables': 0.07; "'name':": 0.09; 'executes': 0.09; 'false,': 0.09; 'structure,': 0.09; 'subject:parsing': 0.09; 'teh': 0.09; 'tutorials,': 0.09; 'api': 0.11; 'cc:addr:python- list': 0.11; 'subject:Help': 0.11; 'python': 0.11; '(palo': 0.16; ':-d': 0.16; 'dict': 0.16; 'dump': 0.16; 'hobbyist': 0.16; 'hostname': 0.16; 'list"': 0.16; 'nick': 0.16; 'palo': 0.16; 'sense,': 0.16; 'stepping': 0.16; 'subject:API': 0.16; 'to:addr:web.de': 0.16; 'index': 0.16; ':-)': 0.16; 'wrote:': 0.18; 'looked': 0.18; "skip:' 30": 0.19; 'slightly': 0.19; 'seems': 0.21; 'command': 0.22; 'example': 0.22; 'cc:addr:python.org': 0.22; 'print': 0.22; 'days,': 0.24; 'entries': 0.24; 'parse': 0.24; 'simpler': 0.24; 'question': 0.24; 'cc:2**0': 0.24; 'script': 0.25; '15,': 0.26; 'task': 0.26; 'header:In-Reply-To:1': 0.27; 'tried': 0.27; 'host': 0.29; 'correct': 0.29; 'rest': 0.29; '(this': 0.29; 'am,': 0.29; 'xml': 0.29; 'related': 0.29; 'change,': 0.30; 'list:': 0.30; 'reaches': 0.30; 'url:mailman': 0.30; 'code': 0.31; 'easier': 0.31; 'received:10.0.0': 0.31; "skip:' 10": 0.31; '>>>>': 0.31; 'aligned': 0.31; 'firewall': 0.31; 'invoke': 0.31; 'layer': 0.31; "skip:' 40": 0.31; 'probably': 0.32; 'another': 0.32; 'url:python': 0.33; 'running': 0.33; 'device': 0.34; 'maybe': 0.34; 'skip:d 20': 0.34; 'subject:from': 0.34; 'could': 0.34; 'subject:with': 0.35; 'display': 0.35; 'tool': 0.35; 'something': 0.35; 'test': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'url:listinfo': 0.36; 'doing': 0.36; 'next': 0.36; 'entry': 0.36; 'useful': 0.36; 'charset:us-ascii': 0.36; "i'll": 0.36; 'subject:?': 0.36; 'received:10.0': 0.36; 'url:org': 0.36; 'should': 0.36; 'list': 0.37; 'received:10': 0.37; 'easily': 0.37; 'message-id:@gmail.com': 0.38; 'thank': 0.38; 'manager': 0.38; 'displays': 0.38; 'skip:[ 10': 0.38; 'ability': 0.39; 'does': 0.39; 'structure': 0.39; 'use.': 0.39; 'skip:p 20': 0.39; 'skip:x 10': 0.40; 'url:mail': 0.40; 'how': 0.40; 'even': 0.60; 'read': 0.60; 'devices': 0.61; 'field.': 0.61; 'new': 0.61; 'simple': 0.61; 'header:Message-Id:1': 0.63; 'information': 0.63; 'name': 0.63; 'central': 0.64; 'management': 0.65; 'iphone': 0.65; 'world': 0.66; 'here': 0.66; 'serial': 0.72; "'foo'": 0.84; '2014,': 0.84; 'a/v': 0.84; 'alto': 0.84; 'appreciative': 0.84; 'believe,': 0.84; 'dict.': 0.84; 'firewalls': 0.84; 'grabbing': 0.84; 'otten': 0.84; 'outsourced': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=content-type:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=cwqizHkTTyvtaUBXxO+yj8/bjhXxboFh4vQNzeFhRMA=; b=CP6J+MFlu7vtRdHhy0snwanMqBypA6uZTgXNKSu4S+3U5s8RUQaaykUiPj1qpPO/aK jOQn3p/P5BML1JGpTrBNAfTpM4WBnmjo9c4o5xh/Cz19LztnZzSPtRlSrrXrnY4aGu4C +0pmZ6WiO5y4h33gyCMbkIcOWVSH3M5dXEuyU1dZAzdaXG8lrGrmefAQ5FQGR39Wj1tc lGTpVzm1hyAcvzjlHFB9AWYz/JXq9HmzxOUWEPRkiJvkF/O4XVP8e5/sEZhMom+xRusm gH8B0BRasIq1VUYGuZRND+BBMz7IE5fDblEDT0jY6qhS1R/SbIwcaZiSrTNwZxGokKto dd9Q== X-Received: by 10.70.125.225 with SMTP id mt1mr12807938pdb.49.1413380159346; Wed, 15 Oct 2014 06:35:59 -0700 (PDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (1.0) Subject: Re: Help with parsing a dict from Vendor's API? From: Nick Ellson X-Mailer: iPhone Mail (12A405) In-Reply-To: Date: Wed, 15 Oct 2014 06:35:57 -0700 Content-Transfer-Encoding: quoted-printable References: To: Peter Otten <__peter__@web.de> X-Mailman-Approved-At: Wed, 15 Oct 2014 15:43:35 +0200 Cc: "python-list@python.org" X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 154 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1413380617 news.xs4all.nl 2913 [2001:888:2000:d::a6]:48649 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:79147 Thank you Peter!=20 That makes sense, and I did find "pprint" that dumped it out aligned so I co= uld actually see the nested layers you are referring to.=20 That got me my IP's. :-) I'll play with this now and see if I can harvest so= mething targeted.. Like list all device host names running code 4.1.9, or di= splay the serial number of the device with hostname 'foo' That should get me on my way to productive fun :-) Nick Nick Ellson - from iPhone (forgive typos) CCIE #20018 Network Hobbyist "Educating Layer 8, one user at a time." > On Oct 15, 2014, at 2:22 AM, Peter Otten <__peter__@web.de> wrote: >=20 > Nick Ellson wrote: >=20 >> Hello! >>=20 >> I have a very specific question related to the output of a Vendors API >> (Palo Alto Networks "pan.xapi" and how I might farm data from this output= . >> I am new to python, doing well in the tutorials, but this is an automatio= n >> task at work and I know the rest will be much easier once i get past the >> ability to read this dict. >>=20 >> The code reaches in to the central Palo Alto firewall manager (Panorama) >> and executes a simple command to return all of the information for each o= f >> the managed firewalls in the field. It captured this output in XML I >> believe, but has the ability to return it in python dict format too, whic= h >> looked like probably the best format to use. Here is the test I tried >>=20 >> >> xapi.op(cmd=3D'show devices connected', cmd_xml=3DTrue ) >> MyDict=3Dxapi.xml_python() >> print (type(MyDict)) >> print (MyDict) >> >>=20 >> and I get: (This displays only 2 firewalls of the 180, so you can see the= >> structure, and that python does say it is a "dict") >>=20 >> bertha bin # ./test.py >> >> {'response': {'result': {'devices': {'entry': [{'av-version': '1391-1863'= , >> 'unsupported-version': False, 'ip-address': '1.8.2.8', 'sw-version': >> '4.1.9', 'vsys': {'entry': [{'name': 'vsys1', 'shared-policy-md5sum': >> '8a8dcd146e24bd750ae571059bc09210', 'shared-policy-status': None, >> 'display-name': 'vsys1'}]}, 'uptime': '350 days, 14:29:49', >> 'threat-version': '460-2394', 'operational-mode': 'normal', 'multi-vsys':= >> False, 'global-protect-client-package-version': '0.0.0', 'app-version': >> '460-2394', 'model': 'PA-200', 'connected': True, 'name': '001606000002',= >> 'family': '200', 'url-filtering-version': '4390', 'vpn-disable-mode': >> False, 'logdb-version': '4.1.2', 'serial': '001606000002', 'hostname': >> 'bob-int-fw'}, {'av-version': '1391-1863', 'unsupported-version': False, >> 'ip-address': '1.9.8.8', 'sw-version': '4.1.9', 'vsys': {'entry': >> [{'name': 'vsys1', 'shared-policy-md5sum': >> '8a8dcd146e24bd750ae571059bc09210', 'shared-policy-status': None, >> 'display-name': 'vsys1'}]}, 'uptime': '358 days, 0:03:20', >> 'threat-version': '460-2394', 'operational-mode': 'normal', 'multi-vsys':= >> False, 'global-protect-client-package-version': '0.0.0', 'app-version': >> '460-2394', 'model': 'PA-200', 'connected': True, 'name': '001606000009',= >> 'family': '200', 'url-filtering-version': '4390', 'vpn-disable-mode': >> False, 'logdb-version': '4.1.2', 'serial': '001606008639', 'hostname': >> 'bib-int-fw'}, <****repeats for 180 firewalls****> ]}}, 'status': >> 'success'}} >>=20 >>=20 >> What I want is to parse through each firewall grabbing the "ip-address" >> value so that I can dump it to a list: >>=20 >> >> >> >>=20 >> For use in another network management tool so I don't rely on outsourced >> help to remember to place teh firewalls into the correct tools. >>=20 >> But dang if every dict tutorial seems to deal with slightly simpler >> looking structures than what this puts out. I would be very appreciative >> with help stepping out of the 6 line "address book/grocery list" example >> world for a taste of something useful :-) >>=20 >> Maybe to a Python coder, it maybe a simple even be able to randomly >> reference a firewall index number and teh value in this structure so one >> can easily just pluck any A/V pair at will.. just not for me yet :-D >=20 > Look at your dict (I use the name 'd' instead of 'MyDict'): >=20 > d =3D {"response": {"result": ...} >=20 > So >=20 > d["response"] >=20 > will give you=20 >=20 > {"result": {"devices": ...} >=20 > A good tool to explore a data structure like this is the interactive=20 > interpreter. If you invoke the script with >=20 > python -i test.py >=20 > you have all its global variables available, i. e. >=20 >>>> MyDict > { ... } # you should see the dictionary contents >=20 >=20 > On we go: >=20 > d["response"]["result"] >=20 > will give >=20 > {"devices": {"entry": ...} >=20 > Next step: >=20 > d["response"]["result"]["devices"] >=20 > --> >=20 > {"entry": [...] >=20 > That's a list for change, so you loop over it: >=20 > entries =3D d["response"]["result"]["devices"]["entry"] > for entry in entries: > print(entry) # --> {..., 'ip-address': '1.8.2.8', ... } >=20 > So the final code is: >=20 > for entry in d["response"]["result"]["devices"]["entry"]: > print(entry["ip-address"]) >=20 >=20 > --=20 > https://mail.python.org/mailman/listinfo/python-list