Python: Code Snippets - System Information

Friday 21st July 2017 3:16am

This is script displays system information including:

  • Software
  • CPU
  • Memory
  • Storage
  • Network
  • Previous Networks
  • Network Devices

To run this script copy the code below and save to a file called system_info.py

system_info.py:

#!/usr/bin/env python

from urllib2 import urlopen
from collections import namedtuple
from subprocess import Popen, PIPE
import socket
import fcntl
import struct
import platform
import getpass
import os
import sys
import subprocess

class SystemInfo():

    # ## Software Information ## #

    # Get hostname
    def get_hostname(self):
        return socket.gethostname()

    def get_platform_info(self):
        os_platform = platform.platform()
        distname, dist_version, id = platform.linux_distribution()
        system, node, release, version, machine, processor = platform.uname()
        return (os_platform,
                distname,
                dist_version,
                id,
                system,
                node,
                release,
                version,
                machine,
                processor)

    # Get username
    def get_username(self):
        return getpass.getuser()

    # Is current user root
    def _is_user_root(self):
        if os.geteuid() == 0:
            return True
        else:
            return False

    # ## CPU Information ## #

    # Get CPU info
    def get_cpu_info(self):
        _ntuple_CPUinfo = namedtuple('CPU', 'model hardware revision \
                                     serial cores temp')
        try:
            return _ntuple_CPUinfo(self.get_cpu_model(),
                                   self.get_cpu_hardware(),
                                   self.get_cpu_revision(),
                                   self.get_cpu_serial(),
                                   self.get_cpu_cores(),
                                   self.get_cpu_temp())
        except:
            return 'Error: Unable to get cpu information :('

    # Get CPU items
    def _get_cpu_item(self, item, ini_value):
        temp = ini_value
        try:
            f = open('/proc/cpuinfo', 'r')
            for line in f:
                if line[0:len(item)] == item:
                    item_value = line[len(item)+3:]
            f.close()
        except:
            item_value = 'Error: Unable to get %s :(' % item
        return item_value.strip()

    # Get CPU Serial Number
    def get_cpu_serial(self):
        return self._get_cpu_item('Serial', '0000000000000000')

    # Get Model Name
    def get_cpu_model(self):
        return self._get_cpu_item('model name', '')

    # Get Hardware
    def get_cpu_hardware(self):
        return self._get_cpu_item('Hardware', '')

    # Get Revision
    def get_cpu_revision(self):
        return self._get_cpu_item('Revision', '')

    # Return CPU temperature as a character string
    def get_cpu_temp(self):
        res = os.popen('vcgencmd measure_temp').readline()
        return(res.replace("temp=", "").replace("'C\n", ""))

    # Get number of cpu cores
    def get_cpu_cores(self):
        # Linux, Unix and MacOS:
        if hasattr(os, "sysconf"):
            if "SC_NPROCESSORS_ONLN" in os.sysconf_names:
                # Linux and Unix:
                ncpus = os.sysconf("SC_NPROCESSORS_ONLN")
                if isinstance(ncpus, int) and ncpus > 0:
                    return ncpus
            else: # OSX:
                return int(os.popen2("sysctl -n hw.ncpu")[1].read())

    # ## Hard Disk Informtion ## #

    # Get Hard Drive Devices
    def get_devices(self, path):
        return next(os.walk(path))[1]

    # Get hard drive usage
    def disk_usage(self, path):
        _ntuple_diskusage = namedtuple('usage', 'path total used free')
        st = os.statvfs(path)
        free = st.f_bavail * st.f_frsize
        total = st.f_blocks * st.f_frsize
        used = (st.f_blocks - st.f_bfree) * st.f_frsize
        return _ntuple_diskusage(path, total, used, free)

    # Get hard drive(s) info
    def get_disk_info(self):
        devices = []
        for device in self.get_devices("/media/"):
            devices.append(self.disk_usage("/media/" + device + "/"))
        devices.append(self.disk_usage("/root/"))
        return devices

    # ## Memory Informtion ## #

    # Get memory info
    def get_ram_info(self):
        _ntuple_RAMinfo = namedtuple('RAM', 'total used free')
        p = os.popen('free')
        i = 0
        while i < 3:
            i += 1
            line = p.readline()
            if i == 2:
                total = line.split()[1]
                used = line.split()[2]
                free = int(total) - int(used)
        return _ntuple_RAMinfo(total, used, free)

    # ## Network Informtion ## #

    # Get list of network settings
    def get_network_settings(self):
        _ntuple_LANinfo = namedtuple('LAN', 'ssid psk proto')
        ssid = ''
        psk = ''
        proto = ''
        settings = []
        if os.path.exists('/var/lib/connman'):
            for network in next(os.walk('/var/lib/connman'))[1]:
                settings.append((network, ''))
                file = open('/var/lib/connman/%s/settings' % network, 'r')
                for line in file:
                    settings.append((line[:line.find('=')],
                                     line[line.find('=')+1:].replace('\n',
                                     '')))
                file.close()
                settings.append(('', ''))
        elif os.path.exists('/etc/wpa_supplicant/wpa_supplicant.conf'):
            file = open('/etc/wpa_supplicant/wpa_supplicant.conf', 'r')
            for line in file:
                settings.append((line[:line.find('=')].strip(),
                                 line[line.find('=')+1:].replace('\n',
                                 '')))
            file.close()
        else:
            return 'Error getting Network Settings!'
        return settings

    # Get list of networks
    def get_networks_info(self):
        try:
            lst = []
            tabs = ''
            for name, value in self.get_network_settings():
                if name != value:
                    if value != '':
                        if len(name) < 8:
                            tabs = "\t\t\t"
                        elif len(name) > 13:
                            tabs = "\t"
                        else:
                            tabs = "\t\t"
                        lst.append('\t\t %s:%s%s\n' % (name, tabs, value))
                else:
                    lst.append('\t\t%s\n\n' % name)
            return lst
        except:
            return 'Error getting Networks!'

    # Get the WAN IP address
    def get_wan_ip_addr(self):
        try:
            return urlopen('http://ip.42.pl/raw').read()
        except:
            return 'Error getting WAN IP Address!'

    # Get LAN IP address for either etho or wlan
    def get_lan_ip_addr(self, ifname):
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            return socket.inet_ntoa(fcntl.ioctl(
                                    s.fileno(),
                                    0x8915, # SIOCGIFADDR
                                    struct.pack('256s', ifname[:15])
                                    )[20:24])
        except:
            return 'Error! Unable to get LAN IP address :('

    # Get default gateway
    def get_default_gateway(self):
        with open("/proc/net/route") as fh:
            for line in fh:
                fields = line.strip().split()
                if fields[1] != '00000000' or not int(fields[3], 16) and 2:
                    continue
                return socket.inet_ntoa(struct.pack("<L", int(fields[2], 16)))

    # Get whois response
    def get_whois(self, ip):
        results = []
        if self.is_tool_installed('whois') is False:
            if self._is_user_root():
                self.install_tool('whois')
            else:
                return results
        desc = ['netname:', 'descr:', 'country:', 'role:']
        p = os.popen('whois ' + ip)
        for line in p:
            for item in desc:
                if line[0:len(item)] == item:
                    results.append(line[len(item):].strip())
        return results

    # Check tool is installed
    def is_tool_installed(self, name):
        try:
            devnull = open(os.devnull)
            subprocess.Popen([name],
                             stdout=devnull,
                             stderr=devnull).communicate()
        except OSError as e:
            if e.errno == os.errno.ENOENT:
                return False
        return True

    # Install Whois
    def install_tool(self, name):
        os.popen('sudo apt-get install -y -qq %s' % name, 'w', 1)

    # Discover other devices on the network
    def get_arp_info(self):
        import re
        devices = []
        pid = Popen(["arp"], stdout=PIPE)
        s = pid.communicate()[0]
        for item in s.split('\n'):
            devices.append("%s" % item.strip())
        return devices

    # Get complete system information
    def get_system_info(self):
        try:
            root_user = self._is_user_root()
            arp_info = self.get_arp_info()
            cpu_info = self.get_cpu_info()
            disk_info = self.get_disk_info()
            ram_info = self.get_ram_info()
            networks_info = self.get_networks_info()
            whois_info = self.get_whois(self.get_wan_ip_addr())
            disk_info_txt = '\nStorage:'
            networks_info_txt = ''
            arp_info_txt = '\nNetwork Devices:\n'
            if root_user:
                networks_info_txt = '\nPrevious Networks:\n'
            hostname = self.get_hostname()
            username = self.get_username()
            (os_platform,
             distname,
             dist_version,
             id,
             system,
             node,
             release,
             version,
             machine,
             processor) = self.get_platform_info()
            for item in disk_info:
                disk_info_txt = disk_info_txt + '\
                \n\t\t Path:                  %s\n \
                Total:                 %sGB\n \
                Used:                  %sGB\n \
                Free:                  %sGB\n' % (
                item.path,
                item.total / (1024**3),
                item.used / (1024**3),
                item.free / (1024**3))

            if root_user:
                for network in networks_info:
                    networks_info_txt = networks_info_txt + network

            for device in arp_info:
                arp_info_txt = arp_info_txt + '\t\t%s\n' % device

            return '\nSoftware:\n \
                Username:              %s\n \
                Hostname:              %s\n \
                Platform:              %s\n \
                Distribution:          %s\n \
                Dist. Version:         %s\n \
                System:                %s\n \
                Node:                  %s\n \
                Release:               %s\n \
                Version:               %s\n \
                Machine:               %s\n \
                Processor:             %s\n \
                \nCPU:\n \
                Model:                 %s\n \
                Cores:                 %s\n \
                Temp:                  %s\n \
                Hardware:              %s\n \
                Revision:              %s\n \
                Serial number:         %s\n \
                \nMemory:\n \
                Total:                 %sMB\n \
                Used:                  %sMB\n \
                Free:                  %sMB\n \
                %s \
                \nNetwork:\n \
                LAN IP Address:\n \
                \teth0:           %s\n \
                \twlan0:          %s\n \
                Gateway IP Address:    %s\n \
                WAN IP Address:        %s\n \
                Whois:\n \
                \tnetname:        %s\n \
                \trole:           %s\n \
                \tdescr:          %s\n \
                \tcountry:        %s\n \
                %s \
                %s' % (
                username,
                hostname,
                os_platform,
                distname,
                dist_version,
                system,
                node,
                release,
                version,
                machine,
                processor,
                cpu_info.model,
                cpu_info.cores,
                cpu_info.temp,
                cpu_info.hardware,
                cpu_info.revision,
                cpu_info.serial,
                int(ram_info.total) / 1024,
                int(ram_info.used) / 1024,
                int(ram_info.free) / 1024,
                disk_info_txt,
                self.get_lan_ip_addr('eth0'),
                self.get_lan_ip_addr('wlan0'),
                self.get_default_gateway(),
                self.get_wan_ip_addr(),
                whois_info[0],
                whois_info[3],
                whois_info[1],
                whois_info[2],
                networks_info_txt,
                arp_info_txt)
        except:
            return 'Error! Unable to get system informtaion :('


# Check if running stand-alone or imported
if __name__ == '__main__':
   import system_info
   si = SystemInfo()
   info = si.get_system_info()
   print info

Output:

sudo python system_info.py
Software:
             Username:              root
             Hostname:              prb-glow
             Plantform:             Linux-4.9.35+-armv6l-with-debian-8.0
             Distribution:          debian
             Dist. Version:         8.0
             System:                Linux
             Node:                  prb-glow
             Release:               4.9.35+
             Version:               #1014 Fri Jun 30 14:34:49 BST 2017
             Machine:               armv61
             Processor:

CPU:
             Model:                 ARMv6-compatible processor rev 7 (v61)
             Cores:                 1
             Temp:                  41.2
             Hardware:              BCM2835
             Revision:              9000c1
             Serial Number:         0000000009f23301

Memory:
             Total:                 370MB
             Used:                  46MB
             Free:                  324MB

Storage:
             Path:                  /root/
             Total:                 7GB
             Used:                  1GB
             Free:                  5GB

Network:
             LAN IP Address:
                    eth0:           Error! Unable to get LAN IP Address : (
                    wlan0:          192.168.1.29
             Gateway IP Address:    192.168.1.1
             WAN IP Address:        82.27.170.62
             Whois:
                    netname:        VMCBBUK
                    role:           Virgin Media Network Management Centre
                    descr:          NORTHFIELDS
                    country:        GB

Previous Networks:
             ctrl_interface:        DIR=/var/run/wpa_supplicant GROUP=netdev
             update_config:         1


             network                        {
             ssid:                  "PRB WLAN"
             psk:                   "PASSWORD HERE"
             proto:                 WPA2
             key_mgmt:              WPA-PSK
            }

Network Devices:
             Address            HWtype   HWAddress            Flags Mask      Iface
             192.168.1.10       ether    b8:27:eb:5c:57:ff    C               wlan0
             192.168.1.17       ether    00:16:ea:5c:c6:10    C               wlan0
             192.168.1.1        ether    a0:21:b7:23:46:b3    C               wlan0
             192.168.1.11       ether    b8:27:eb:ad:c0:01    C               wlan0
FB Like & Share