More than one way to skin a cat
What is the best way to do something? When dealing with technical people this can sometimes be an easy question. They’re opininated, fickle, and judgemental. They’ve tried things and have arrived at the best solution. Is it the best solution for them? For everyone?
Objectively how do we decide? Documenting the decision-making process is always a good start. Expose yourself to critique, assuming the critics don’t put you off it entirely, you may end up more assured in your assumptions.
Considerations: 1. Do I want the user to download extra libraries? - How difficult is this? - How savy are my users? 2. What is the delivery method? - Does the packaging/readme/manual alleviate the installation over-head? - Is this delivered in a container or pre-built VM? 3. What is the system over-head between two different methods? - Big O notation anyone? 4. Implementation complexity.
I want to understand the total amount of memory available and the current amount of memory used. What I have found is two methods for getting what I want. One is a taco bell programmer method. The second is through some text manipulation and understanding of linux system architecture.
- Using the subprocess module. “`python import subprocess
command = “free -h” p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) print(“Running “, command) for line in p.stdout.readlines(): print(line.decode(), end=”) retval = p.wait()
2. Opening the file /proc/meminfo and parsing it. ```python import os input = open("/proc/meminfo", "r") meminfo = input.read() input.close() meminfo_list = meminfo.split('\n') for i in range(len(meminfo_list)): if( "MemTotal" in meminfo_list[i] ): print(meminfo_list[i].split())
My goal is to just print information about the system to the terminal, not evaluate it. I’m doing this for users who are not that linux savvy. Therefore I’m going with the 2nd method here because: a) By adding a print statement with the command run, I can teach users how to inspect their own system. b) The command already summarizes all the information I want nicely. c) The os module is part of the standard library, so my users don’t have to do extra work during installation.
Here’s a few other methods I’m comparing.
Requests vs. urllib:
Standard Library (urllib):
import urllib.request url = 'http://odl1:8181/restconf/operational/network-topology:network-topology/' passman = urllib.request.HTTPPasswordMgrWithDefaultRealm() passman.add_password(None, url, 'admin', 'admin') authhandler = urllib.request.HTTPBasicAuthHandler(passman) opener = urllib.request.build_opener(authhandler) urllib.request.install_opener(opener) u = urllib.request.urlopen(url) topology = json.loads(u.read().decode())
import requests operational_db = 'http://localhost:8181/restconf/operational/opendaylight-inventory:nodes/' operational_request = requests.get(operational_db, auth=('admin','admin')) operational_json = json.loads(operational_request.text)
JMESPath vs Normal Dictionary and Lists
Standard Library (loops,conditionals)
topology_list = topology["network-topology"]["topology"] for i in range(len(topology_list)): if topology_list[i]["topology-id"] == "topology-netconf": for j in range(len(topology_list[i]["node"])): print(topology_list[i]["node"][j]["netconf-node-topology:host"])
import jmespath operational_list = ((jmespath.search('"network-topology".topology[?"topology-id" == `topology-netconf`]', operational_json))).get('node') for i in range(len(operational_list)): print(operational_netconf[i].get('node-id'))
On a side-note, really liking jq:
$ http -a admin:admin http://odl1:8181/restconf/operational/network-topology:network-topology | jq '."network-topology"."topology" | keys' [ "node", "topology-id" ] $ http -a admin:admin http://odl1:8181/restconf/operational/network-topology:network-topology | jq '."network-topology"."topology"."topology-id"' "topology-netconf"