pythondbusnetworkmanager

Reading full NetworkManager connection information using python-dbus


I am trying to interrogate dbus in python to get NetworkManager to tell me whether or not a connection is configured to attempt to connect automatically to a network.

When I use nmcli to inspect a NetworkManager connection, I get output like this

connection.id:                          my_wifi
connection.uuid:                        f36e1220-cf36-4254-b790-6d21b70ff76a
connection.stable-id:                   --
connection.type:                        802-11-wireless
connection.interface-name:              wlan0
connection.autoconnect:                 yes
connection.autoconnect-priority:        1
connection.autoconnect-retries:         -1 (default)
connection.multi-connect:               0 (default)
connection.auth-retries:                -1
connection.timestamp:                   1690711294
connection.read-only:                   no
connection.permissions:                 --
connection.zone:                        --
connection.master:                      --
connection.slave-type:                  --
connection.autoconnect-slaves:          -1 (default)
connection.secondaries:                 --
connection.gateway-ping-timeout:        0
connection.metered:                     unknown
connection.lldp:                        default
connection.mdns:                        -1 (default)
connection.llmnr:                       -1 (default)
connection.wait-device-timeout:         -1
...

We can see the connection.autoconnect parameter displayed there.

However, if I try to get the same info from a PyQt program using the GetSettings method on a connection object I get:

connection:
   id:
      my_wifi
   interface-name:
      wlan0
   permissions:
      <Empty Array>
   timestamp:
      1689966080
   type:
      802-11-wireless
   uuid:
      f36e1220-cf36-4254-b790-6d21b70ff76a
802-11-wireless:
....

Here is the source of the code used to query the dbus. (Please note that I get the same result presented less readably without the formatting code, so this is not an artefact of that.)

#!/usr/bin/env python3
# The code below is released under a public domain licence

from dbus import SystemBus, Interface
from dbus.types import Dictionary, String, Array, ByteArray, Byte

# Output formatting code
def display_data(structure, indent: int = 0):

   prefix = ""
   for i in range (indent):
      prefix +=  "   "

   if type(structure) == Dictionary:
      if len(structure) == 0:
         print(f"{prefix}<Empty Dict>")
      else:
         for element in structure:
            if type(structure[element] == Dictionary):
               print(f"{prefix}{element}:")
               display_data(structure[element], indent + 1)
            else:
               display_data("structure[element]")
   elif type(structure) == Array:
      if len(structure) == 0:
         print(f"{prefix}<Empty Array>")
      elif type(structure[0]) == Byte:
         print(f"{prefix}{''.join([str(c) for c in structure])}")

      else:
         for array_element in structure:
            print(f"{prefix}{array_element}")

   else: 
      if type(structure) == String and len(structure) == 0:
         print(f"{prefix}<Empty Value>")
      print(f"{prefix}{structure}")

# Dbus probe code
interface_netman = "org.freedesktop.NetworkManager"
path_netman_settings = "/org/freedesktop/NetworkManager/Settings"

interface_settings = "org.freedesktop.NetworkManager.Settings"
interface_connection = "org.freedesktop.NetworkManager.Settings.Connection"

bus = SystemBus()

settings_proxy = bus.get_object(interface_netman, path_netman_settings) 
settings = Interface(settings_proxy, interface_settings)

connection_list = settings.ListConnections()

out = {}

for connection in connection_list:
   this_connection = bus.get_object(interface_netman, connection)
   this_connection_interface = Interface(this_connection, interface_connection)        
   this_connection_settings = this_connection_interface.GetSettings()

   display_data(this_connection_settings)

I expected that when I ran the code above, I would get the same info as nmcli outputs including whether the connection has autoconnect enabled, but the information provided was much more limited.

So my question is where is nmcli getting the extra connection info from, and how do I access it?


Solution

  • It turns out that GetSettings() will not return a value for connection.autoconnect unless it is set to a non-default value (i.e. "no").