Get hardware and system information in Python

As a Python developer, it's convenient to use a third-party library to do what you really want, rather than reinventing the wheel every time. In this tutorial, you will be familiar with psutil , which is a cross platform library for process and system monitoring in Python, and a built-in library for extracting system and hardware information in Python platform modular.

Finally, I'll show you how to print GPU information (if you have it, of course).

This is the directory of this tutorial:

  1. system information
  2. CPU Information
  3. Memory usage
  4. Disk usage
  5. network information
  6. Graphics processor information

Related: How to use the ipaddress module to manipulate IP addresses in Python.

 

 

Before we delve further, you need to install psutil:

pip3 install psutil
copy

Open a new python file. Let's start by importing the necessary modules:

import psutil
import platform
from datetime import datetime
copy

Let's create a function to convert a large number of bytes to a scaled format (for example, in thousands, megabytes, gigabytes, etc.):

def get_size(bytes, suffix="B"):
    """
    Scale bytes to its proper format
    e.g:
        1253656 => '1.20MB'
        1253656678 => '1.17GB'
    """
    factor = 1024
    for unit in ["", "K", "M", "G", "T", "P"]:
        if bytes < factor:
            return f"{bytes:.2f}{unit}{suffix}"
        bytes /= factor
copy

system information

We need it here platform modular:

 

 

print("="*40, "System Information", "="*40)
uname = platform.uname()
print(f"System: {uname.system}")
print(f"Node Name: {uname.node}")
print(f"Release: {uname.release}")
print(f"Version: {uname.version}")
print(f"Machine: {uname.machine}")
print(f"Processor: {uname.processor}")
copy

Get the date and time the computer started:

# Boot Time
print("="*40, "Boot Time", "="*40)
boot_time_timestamp = psutil.boot_time()
bt = datetime.fromtimestamp(boot_time_timestamp)
print(f"Boot Time: {bt.year}/{bt.month}/{bt.day} {bt.hour}:{bt.minute}:{bt.second}")
copy

CPU Information

Let's get some CPU information, such as total number of cores, usage, etc

# let's print CPU information
print("="*40, "CPU Info", "="*40)
# number of cores
print("Physical cores:", psutil.cpu_count(logical=False))
print("Total cores:", psutil.cpu_count(logical=True))
# CPU frequencies
cpufreq = psutil.cpu_freq()
print(f"Max Frequency: {cpufreq.max:.2f}Mhz")
print(f"Min Frequency: {cpufreq.min:.2f}Mhz")
print(f"Current Frequency: {cpufreq.current:.2f}Mhz")
# CPU usage
print("CPU Usage Per Core:")
for i, percentage in enumerate(psutil.cpu_percent(percpu=True, interval=1)):
    print(f"Core {i}: {percentage}%")
print(f"Total CPU Usage: {psutil.cpu_percent()}%")
copy

psutil CPU of_ The count() function returns the number of cores, while the CPU_ The freq() function returns the CPU frequency. namedtuple includes the current, minimum and maximum frequencies expressed in Mhz. You can set percpu=True to get the frequency of each CPU.

cpu_ The percent () method returns a floating-point number that represents the percentage of the current CPU utilization. Setting the interval to 1 (second) will compare the system CPU time after one second. We set percpu to True to obtain the CPU utilization of each kernel.

Memory usage

# Memory Information
print("="*40, "Memory Information", "="*40)
# get the memory details
svmem = psutil.virtual_memory()
print(f"Total: {get_size(svmem.total)}")
print(f"Available: {get_size(svmem.available)}")
print(f"Used: {get_size(svmem.used)}")
print(f"Percentage: {svmem.percent}%")
print("="*20, "SWAP", "="*20)
# get the swap memory details (if exists)
swap = psutil.swap_memory()
print(f"Total: {get_size(swap.total)}")
print(f"Free: {get_size(swap.free)}")
print(f"Used: {get_size(swap.used)}")
print(f"Percentage: {swap.percent}%")
copy

virtual_ The memory () method returns the statistical information about the system memory usage, namedtuple, including fields such as (total available physical memory), available (available memory, i.e. unused), used and percent (i.e. percentage). swap_memory() is the same, but is used to swap memory.

 

 

We use the previously defined get_ The size() function prints the value in a scaled manner because these statistics are expressed in bytes.

 

Disk usage

# Disk Information
print("="*40, "Disk Information", "="*40)
print("Partitions and Usage:")
# get all disk partitions
partitions = psutil.disk_partitions()
for partition in partitions:
    print(f"=== Device: {partition.device} ===")
    print(f"  Mountpoint: {partition.mountpoint}")
    print(f"  File system type: {partition.fstype}")
    try:
        partition_usage = psutil.disk_usage(partition.mountpoint)
    except PermissionError:
        # this can be catched due to the disk that
        # isn't ready
        continue
    print(f"  Total Size: {get_size(partition_usage.total)}")
    print(f"  Used: {get_size(partition_usage.used)}")
    print(f"  Free: {get_size(partition_usage.free)}")
    print(f"  Percentage: {partition_usage.percent}%")
# get IO statistics since boot
disk_io = psutil.disk_io_counters()
print(f"Total read: {get_size(disk_io.read_bytes)}")
print(f"Total write: {get_size(disk_io.write_bytes)}")
copy

As expected, disk_ The usage () function returns the disk usage statistics as namedtuple, including total, used and free space in bytes.

network information

# Network information
print("="*40, "Network Information", "="*40)
# get all network interfaces (virtual and physical)
if_addrs = psutil.net_if_addrs()
for interface_name, interface_addresses in if_addrs.items():
    for address in interface_addresses:
        print(f"=== Interface: {interface_name} ===")
        if str(address.family) == 'AddressFamily.AF_INET':
            print(f"  IP Address: {address.address}")
            print(f"  Netmask: {address.netmask}")
            print(f"  Broadcast IP: {address.broadcast}")
        elif str(address.family) == 'AddressFamily.AF_PACKET':
            print(f"  MAC Address: {address.address}")
            print(f"  Netmask: {address.netmask}")
            print(f"  Broadcast MAC: {address.broadcast}")
# get IO statistics since boot
net_io = psutil.net_io_counters()
print(f"Total Bytes Sent: {get_size(net_io.bytes_sent)}")
print(f"Total Bytes Received: {get_size(net_io.bytes_recv)}")
copy

net_ if_ The addrs() function returns the address associated with each network interface card installed on the system.

OK, this is the result output of my personal linux machine:

<span style="color:#212529"><span style="background-color:#ffffff"><span style="background-color:#f5f2f0"><span style="color:#000000"><code class="language-markup">======================================== System Information ========================================
System: Linux
Node Name: rockikz
Release: 4.17.0-kali1-amd64
Version: #1 SMP Debian 4.17.8-1kali1 (2018-07-24)
Machine: x86_64
Processor:
======================================== Boot Time ========================================
Boot Time: 2019/8/21 9:37:26
======================================== CPU Info ========================================
Physical cores: 4
Total cores: 4
Max Frequency: 3500.00Mhz
Min Frequency: 1600.00Mhz
Current Frequency: 1661.76Mhz
CPU Usage Per Core:
Core 0: 0.0%
Core 1: 0.0%
Core 2: 11.1%
Core 3: 0.0%
Total CPU Usage: 3.0%
======================================== Memory Information ========================================
Total: 3.82GB
Available: 2.98GB
Used: 564.29MB
Percentage: 21.9%
==================== SWAP ====================
Total: 0.00B
Free: 0.00B
Used: 0.00B
Percentage: 0%
======================================== Disk Information ========================================
Partitions and Usage:
=== Device: /dev/sda1 ===
  Mountpoint: /
  File system type: ext4
  Total Size: 451.57GB
  Used: 384.29GB
  Free: 44.28GB
  Percentage: 89.7%
Total read: 2.38GB
Total write: 2.45GB
======================================== Network Information ========================================
=== Interface: lo ===
  IP Address: 127.0.0.1
  Netmask: 255.0.0.0
  Broadcast IP: None
=== Interface: lo ===
=== Interface: lo ===
  MAC Address: 00:00:00:00:00:00
  Netmask: None
  Broadcast MAC: None
=== Interface: wlan0 ===
  IP Address: 192.168.1.101
  Netmask: 255.255.255.0
  Broadcast IP: 192.168.1.255
=== Interface: wlan0 ===
=== Interface: wlan0 ===
  MAC Address: 64:70:02:07:40:50
  Netmask: None
  Broadcast MAC: ff:ff:ff:ff:ff:ff
=== Interface: eth0 ===
  MAC Address: d0:27:88:c6:06:47
  Netmask: None
  Broadcast MAC: ff:ff:ff:ff:ff:ff
Total Bytes Sent: 123.68MB
Total Bytes Received: 577.94MB</code></span></span></span></span>
copy

 

 

If you are using a laptop computer, you can use psutil sensors_ Battery() gets battery information.

 

In addition, if you are a Linux user, you can use psutil sensors_ Fan() to obtain the RPM of the fan, also known as psutil sensors_ Temperatures() to obtain the temperature of various devices.

Graphics processor information

psutil does not provide us with GPU information. Therefore, we need to install GPUtil:

pip3 install gputil
copy

GPUtil is a Python module, which is only used to obtain the GPU status of NVIDIA GPU. It locates all GPUs on the computer, determines their availability, and returns an ordered list of available GPUs. It needs to install the latest NVIDIA driver.

In addition, we need to install tabulate module , this will allow us to print GPU information in tabular form:

pip3 install tabulate
copy

 

 

The following code line prints all GPU s in your machine and their details:

 

# GPU information
import GPUtil
from tabulate import tabulate
print("="*40, "GPU Details", "="*40)
gpus = GPUtil.getGPUs()
list_gpus = []
for gpu in gpus:
    # get the GPU id
    gpu_id = gpu.id
    # name of GPU
    gpu_name = gpu.name
    # get % percentage of GPU usage of that GPU
    gpu_load = f"{gpu.load*100}%"
    # get free memory in MB format
    gpu_free_memory = f"{gpu.memoryFree}MB"
    # get used memory
    gpu_used_memory = f"{gpu.memoryUsed}MB"
    # get total memory
    gpu_total_memory = f"{gpu.memoryTotal}MB"
    # get GPU temperature in Celsius
    gpu_temperature = f"{gpu.temperature} °C"
    gpu_uuid = gpu.uuid
    list_gpus.append((
        gpu_id, gpu_name, gpu_load, gpu_free_memory, gpu_used_memory,
        gpu_total_memory, gpu_temperature, gpu_uuid
    ))

print(tabulate(list_gpus, headers=("id", "name", "load", "free memory", "used memory", "total memory",
                                   "temperature", "uuid")))
copy

This is the output from my machine:

======================================== GPU Details ========================================
  id  name              load    free memory    used memory    total memory    temperature    uuid
----  ----------------  ------  -------------  -------------  --------------  -------------  ----------------------------------------
   0  GeForce GTX 1050  2.0%    3976.0MB       120.0MB        4096.0MB        52.0 °C        GPU-c9b08d82-f1e2-40b6-fd20-543a4186d6ce
copy

Great, now you can integrate this information into your Python monitor applications and utilities!

Check the documentation for the library we used in this tutorial:

 

 

You can also use psutil to Monitor operating system processes For example, the CPU and memory usage of each process.

 

Added by dmcentire on Sun, 30 Jan 2022 03:09:40 +0200