Back to Blog
Python

Python psutil System Information and Battery Status

python psutil system information and battery status: Learn how to use Python psutil to retrieve CPU, memory, disk, network, and battery status across platforms, with p...

psutilsystem monitoringbattery statuspythoncross-platform
Diagram showing a Python script using psutil to collect system metrics and battery status from a laptop.

This article covers Python psutil system information and battery status, including CPU, memory, disk, network, and battery sensors. psutil provides a consistent cross-platform API for these metrics without shelling out to system-specific commands.

Installing psutil

psutil is available on PyPI and can be installed with pip:

pip install psutil

The library supports Linux, Windows, and macOS, and the same Python API works across these platforms. After installation, import the module as psutil.

Reading CPU and Memory Information

psutil.cpu_percent(interval=None) returns the CPU utilization as a percentage. When interval is omitted or None, it returns the utilization since the last call, which is useful for polling. To get an instantaneous reading, pass a small interval like 0.1.

import psutil cpu = psutil.cpu_percent(interval=0.1) print(f"CPU: {cpu}%")

Memory usage is available through psutil.virtual_memory(), which returns a named tuple with total, available, percent, used, and free values. The percent field is the most commonly used metric for monitoring.

mem = psutil.virtual_memory() print(f"Memory: {mem.percent}% used")

These functions are non-blocking when interval=None, but they do consume a small amount of CPU to read the system counters. For long-running monitors, call them at a fixed interval rather than in a tight loop.

Disk and Network Usage

psutil.disk_usage(path) returns a named tuple with total, used, free, and percent for the filesystem containing path. On Windows, you may need to pass a drive letter like C:\\.

disk = psutil.disk_usage('/') print(f"Disk: {disk.percent}% used")

Network I/O counters are available via psutil.net_io_counters(), which returns bytes sent and received since boot. To measure throughput, you need to sample the counters over a time interval and compute the difference.

import time before = psutil.net_io_counters() time.sleep(1) after = psutil.net_io_counters() rx_rate = (after.bytes_recv - before.bytes_recv) / 1 tx_rate = (after.bytes_sent - before.bytes_sent) / 1 print(f"RX: {rx_rate} B/s, TX: {tx_rate} B/s")

Reading Battery Status with psutil.sensors_battery()

psutil provides sensors_battery() to read battery information on laptops and other devices with batteries. The function returns a sensor_battery named tuple with percent, secsleft, and power_plugged. On systems without a battery, or when the sensor is not available, it returns None.

battery = psutil.sensors_battery() if battery is not None: print(f"Battery: {battery.percent}%") print(f"Plugged in: {battery.power_plugged}") if battery.secsleft != psutil.POWER_TIME_UNLIMITED: print(f"Time left: {battery.secsleft} seconds") else: print("No battery detected")

secsleft is an estimate. On some systems, it may be psutil.POWER_TIME_UNLIMITED when the OS cannot estimate remaining time, or psutil.POWER_TIME_UNKNOWN when the value is not available. The accuracy varies by platform and hardware.

Handling Missing Sensors and Cross-Platform Differences

sensors_battery() is not available on every platform. On Linux, it reads from /sys/class/power_supply; on Windows, it uses the Win32 API; on macOS, it uses IOKit. The function returns None if no battery is present or if the sensor cannot be read. Always check the return value before accessing attributes.

PlatformBattery supportNotes
LinuxYesReads from sysfs; secsleft may be POWER_TIME_UNKNOWN
WindowsYesUses Win32; secsleft often POWER_TIME_UNKNOWN
macOSYesUses IOKit; secsleft generally accurate

When writing cross-platform code, treat None as a valid outcome and handle it gracefully. For example, a monitoring script might log a warning instead of crashing.

Polling System Metrics Efficiently

For a monitoring script that samples metrics every few seconds, the simplest approach is a while loop with time.sleep(). However, psutil.cpu_percent(interval=None) returns the utilization since the previous call, so you must call it at a consistent interval to get meaningful data. If you need a one-shot reading, pass an explicit interval.

import time import psutil def sample(): cpu = psutil.cpu_percent(interval=None) mem = psutil.virtual_memory().percent battery = psutil.sensors_battery() return { 'cpu': cpu, 'mem': mem, 'battery': battery.percent if battery else None, 'plugged': battery.power_plugged if battery else None, } while True: print(sample()) time.sleep(5)

The interval=None call in the first iteration returns 0.0 because there is no previous sample. To avoid this, either call cpu_percent(interval=0.1) on the first iteration or discard the first reading.

Building a Lightweight System Monitor

Combining the metrics above, you can create a compact system monitor that prints CPU, memory, disk, and battery status. This example also handles the case where battery information is unavailable.

import psutil import time def monitor(): cpu = psutil.cpu_percent(interval=0.1) mem = psutil.virtual_memory().percent disk = psutil.disk_usage('/').percent battery = psutil.sensors_battery() line = f"CPU {cpu:5.1f}% | MEM {mem:5.1f}% | DISK {disk:5.1f}%" if battery: line += f" | BAT {battery.percent:3.0f}%" if battery.power_plugged: line += " (AC)" else: line += " (Battery)" print(line) if __name__ == "__main__": while True: monitor() time.sleep(5)

This script runs indefinitely and prints a single line every five seconds. In a production context, you would likely log to a file or send metrics to a monitoring service instead of printing to stdout. The key point is that psutil gives you all the data you need from a single, consistent API.

python psutil system information and battery status: Practic | RYUSLOG DEV