Skip to content

Commit 196fa39

Browse files
author
Bernhard Kaindl
committed
Example to create a WiFi-PSK connection profile
Also fix mypy and sourcery warnings in examples/async/device-state-async.py
1 parent b077a60 commit 196fa39

File tree

3 files changed

+232
-7
lines changed

3 files changed

+232
-7
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/usr/bin/env python
2+
# SPDX-License-Identifier: LGPL-2.1-or-later
3+
#
4+
# Example to create a new WiFi-PSK network connection profile:
5+
#
6+
# $ add-wifi-psk-connection.py --help
7+
# usage: add-wifi-psk-connection.py [-h] [-c CONN_ID] [-s SSID] [-p PSK]
8+
# [-i INTERFACE_NAME] [-a] [--save]
9+
#
10+
# Optional arguments have example values:
11+
#
12+
# optional arguments:
13+
# -h, --help show this help message and exit
14+
# -c CONN_ID Connection Id
15+
# -s SSID WiFi SSID
16+
# -p PSK WiFi PSK
17+
# -i INTERFACE_NAME WiFi device
18+
# -a autoconnect
19+
# --save Save
20+
#
21+
# $ add-wifi-psk-connection.py
22+
# New unsaved connection profile created, show it with:
23+
# nmcli connection show "MyConnectionExample"|grep -v -e -- -e default
24+
# Settings used:
25+
# {'connection': {'id': ('s', 'MyConnectionExample'),
26+
# 'uuid': ('s', '90e3bcc8-d3a5-4725-a363-abb788fd47bf'),
27+
# 'type': ('s', '802-11-wireless'),
28+
# 'autoconnect': ('b', False)},
29+
# '802-11-wireless': {'mode': ('s', 'infrastructure'),
30+
# 'security': ('s', '802-11-wireless-security'),
31+
# 'ssid': ('ay', b'CafeSSID')},
32+
# '802-11-wireless-security': {'key-mgmt': ('s', 'wpa-psk'),
33+
# 'auth-alg': ('s', 'open'),
34+
# 'psk': ('s', 'Coffee!!')},
35+
# 'ipv4': {'method': ('s', 'auto')},
36+
# 'ipv6': {'method': ('s', 'auto')}}
37+
#
38+
# Connection Profile settings are described at:
39+
# https://networkmanager.dev/docs/api/latest/ref-settings.html
40+
#
41+
# Note: By default, it uses add_connection_unsaved() to add a temporary
42+
# memory-only connection which is not saved to the system-connections folder:
43+
# For reference, see: https://networkmanager.dev/docs/api/latest/spec.html
44+
# -> org.freedesktop.NetworkManager.Settings (Settings Profile Manager)
45+
46+
import asyncio
47+
import functools
48+
import pprint
49+
import sdbus
50+
import uuid
51+
from argparse import ArgumentParser, Namespace
52+
from sdbus_async.networkmanager import NetworkManagerSettings
53+
from sdbus_async.networkmanager import NetworkManagerConnectionProperties
54+
55+
56+
async def add_wifi_psk_connection_profile_async(args: Namespace) -> None:
57+
"""Add a temporary (not yet saved) network connection profile"""
58+
59+
# If we add many connections passing the same id, things get messy. Check:
60+
if await NetworkManagerSettings().get_connections_by_id(args.conn_id):
61+
print(f'Connection "{args.conn_id}" exists, remove it first')
62+
print(f'Run: nmcli connection delete "{args.conn_id}"')
63+
return
64+
65+
properties: NetworkManagerConnectionProperties = {
66+
"connection": {
67+
"id": ("s", args.conn_id),
68+
"uuid": ("s", str(uuid.uuid4())),
69+
"type": ("s", "802-11-wireless"),
70+
"autoconnect": ("b", args.auto),
71+
},
72+
"802-11-wireless": {
73+
"mode": ("s", "infrastructure"),
74+
"security": ("s", "802-11-wireless-security"),
75+
"ssid": ("ay", args.ssid.encode("utf-8")),
76+
},
77+
"802-11-wireless-security": {
78+
"key-mgmt": ("s", "wpa-psk"),
79+
"auth-alg": ("s", "open"),
80+
"psk": ("s", args.psk),
81+
},
82+
"ipv4": {"method": ("s", "auto")},
83+
"ipv6": {"method": ("s", "auto")},
84+
}
85+
86+
# To bind the new connection to a specific interface, use this:
87+
if args.interface_name:
88+
properties["connection"]["interface-name"] = ("s", args.interface_name)
89+
90+
networkmanager_settings = NetworkManagerSettings()
91+
if args.save:
92+
await networkmanager_settings.add_connection(properties)
93+
print("New connection profile created and saved, show it with:")
94+
else:
95+
await networkmanager_settings.add_connection_unsaved(properties)
96+
print("New unsaved connection profile created, show it with:")
97+
98+
print(f'nmcli connection show "{args.conn_id}"|grep -v -e -- -e default')
99+
print("Settings used:")
100+
functools.partial(pprint.pprint, sort_dicts=False)(properties)
101+
102+
103+
if __name__ == "__main__":
104+
p = ArgumentParser(description="Optional arguments have example values:")
105+
conn_id = "MyConnectionExample"
106+
p.add_argument("-c", dest="conn_id", default=conn_id, help="Connection Id")
107+
p.add_argument("-s", dest="ssid", default="CafeSSID", help="WiFi SSID")
108+
p.add_argument("-p", dest="psk", default="Coffee!!", help="WiFi PSK")
109+
p.add_argument("-i", dest="interface_name", default="", help="WiFi device")
110+
p.add_argument("-a", dest="auto", action="store_true", help="autoconnect")
111+
p.add_argument("--save", dest="save", action="store_true", help="Save")
112+
args = p.parse_args()
113+
sdbus.set_default_bus(sdbus.sd_bus_open_system())
114+
asyncio.run(add_wifi_psk_connection_profile_async(args))

examples/async/device-state-async.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,19 @@ async def list_active_hardware_networkdevice_states(only_hw: bool) -> None:
5151

5252
# Create the strings for the columns using the names of the enums:
5353
dev: str = await generic.interface
54-
type = title(DeviceType(await generic.device_type))
54+
dtype = title(DeviceType(await generic.device_type))
5555
state = title(DeviceState(await generic.state))
5656
connectivity = title(ConnectivityState(await generic.ip4_connectivity))
5757

58-
if await generic.active_connection == "/": # No active connection
59-
id = ""
60-
else:
58+
name: str = ""
59+
if await generic.active_connection != "/": # Connection is active
6160
# ActiveConnection() gets propertites from active connection path:
6261
active_conn = ActiveConnection(await generic.active_connection)
63-
id: str = await active_conn.id
62+
name = await active_conn.id
6463
if await active_conn.default:
65-
id += " [primary connection]"
64+
name += " [primary connection]"
6665

67-
print(f"{dev:<17} {type:<8} {state:<12} {connectivity:<8} {id:<14}")
66+
print(f"{dev:<17} {dtype:<8} {state:<12} {connectivity:<8} {name:<14}")
6867

6968

7069
if __name__ == "__main__":
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#!/usr/bin/env python
2+
# SPDX-License-Identifier: LGPL-2.1-or-later
3+
#
4+
# Example to create a new WiFi-PSK network connection profile:
5+
#
6+
# $ add-wifi-psk-connection.py --help
7+
# usage: add-wifi-psk-connection.py [-h] [-c CONN_ID] [-s SSID] [-p PSK]
8+
# [-i INTERFACE_NAME] [-a] [--save]
9+
#
10+
# Optional arguments have example values:
11+
#
12+
# optional arguments:
13+
# -h, --help show this help message and exit
14+
# -c CONN_ID Connection Id
15+
# -s SSID WiFi SSID
16+
# -p PSK WiFi PSK
17+
# -i INTERFACE_NAME WiFi device
18+
# -a autoconnect
19+
# --save Save
20+
#
21+
# $ add-wifi-psk-connection.py
22+
# New unsaved connection profile created, show it with:
23+
# nmcli connection show "MyConnectionExample"|grep -v -e -- -e default
24+
# Settings used:
25+
# {'connection': {'id': ('s', 'MyConnectionExample'),
26+
# 'uuid': ('s', '90e3bcc8-d3a5-4725-a363-abb788fd47bf'),
27+
# 'type': ('s', '802-11-wireless'),
28+
# 'autoconnect': ('b', False)},
29+
# '802-11-wireless': {'mode': ('s', 'infrastructure'),
30+
# 'security': ('s', '802-11-wireless-security'),
31+
# 'ssid': ('ay', b'CafeSSID')},
32+
# '802-11-wireless-security': {'key-mgmt': ('s', 'wpa-psk'),
33+
# 'auth-alg': ('s', 'open'),
34+
# 'psk': ('s', 'Coffee!!')},
35+
# 'ipv4': {'method': ('s', 'auto')},
36+
# 'ipv6': {'method': ('s', 'auto')}}
37+
#
38+
# Connection Profile settings are described at:
39+
# https://networkmanager.dev/docs/api/latest/ref-settings.html
40+
#
41+
# Note: By default, it uses add_connection_unsaved() to add a temporary
42+
# memory-only connection which is not saved to the system-connections folder:
43+
# For reference, see: https://networkmanager.dev/docs/api/latest/spec.html
44+
# -> org.freedesktop.NetworkManager.Settings (Settings Profile Manager)
45+
46+
import functools
47+
import pprint
48+
import sdbus
49+
import uuid
50+
from argparse import ArgumentParser, Namespace
51+
from sdbus_block.networkmanager import NetworkManagerSettings
52+
from sdbus_block.networkmanager import NetworkManagerConnectionProperties
53+
54+
55+
def add_wifi_psk_connection_profile(args: Namespace) -> None:
56+
"""Add a temporary (not yet saved) network connection profile"""
57+
58+
# If we add many connections passing the same id, things get messy. Check:
59+
if NetworkManagerSettings().get_connections_by_id(args.conn_id):
60+
print(f'Connection "{args.conn_id}" exists, remove it first')
61+
print(f'Run: nmcli connection delete "{args.conn_id}"')
62+
return
63+
64+
properties: NetworkManagerConnectionProperties = {
65+
"connection": {
66+
"id": ("s", args.conn_id),
67+
"uuid": ("s", str(uuid.uuid4())),
68+
"type": ("s", "802-11-wireless"),
69+
"autoconnect": ("b", args.auto),
70+
},
71+
"802-11-wireless": {
72+
"mode": ("s", "infrastructure"),
73+
"security": ("s", "802-11-wireless-security"),
74+
"ssid": ("ay", args.ssid.encode("utf-8")),
75+
},
76+
"802-11-wireless-security": {
77+
"key-mgmt": ("s", "wpa-psk"),
78+
"auth-alg": ("s", "open"),
79+
"psk": ("s", args.psk),
80+
},
81+
"ipv4": {"method": ("s", "auto")},
82+
"ipv6": {"method": ("s", "auto")},
83+
}
84+
85+
# To bind the new connection to a specific interface, use this:
86+
if args.interface_name:
87+
properties["connection"]["interface-name"] = ("s", args.interface_name)
88+
89+
if args.save:
90+
NetworkManagerSettings().add_connection(properties)
91+
print("New connection profile created and saved, show it with:")
92+
else:
93+
NetworkManagerSettings().add_connection_unsaved(properties)
94+
print("New unsaved connection profile created, show it with:")
95+
96+
print(f'nmcli connection show "{args.conn_id}"|grep -v -e -- -e default')
97+
print("Settings used:")
98+
functools.partial(pprint.pprint, sort_dicts=False)(properties)
99+
100+
101+
if __name__ == "__main__":
102+
p = ArgumentParser(description="Optional arguments have example values:")
103+
conn_id = "MyConnectionExample"
104+
p.add_argument("-c", dest="conn_id", default=conn_id, help="Connection Id")
105+
p.add_argument("-s", dest="ssid", default="CafeSSID", help="WiFi SSID")
106+
p.add_argument("-p", dest="psk", default="Coffee!!", help="WiFi PSK")
107+
p.add_argument("-i", dest="interface_name", default="", help="WiFi device")
108+
p.add_argument("-a", dest="auto", action="store_true", help="autoconnect")
109+
p.add_argument("--save", dest="save", action="store_true", help="Save")
110+
args = p.parse_args()
111+
sdbus.set_default_bus(sdbus.sd_bus_open_system())
112+
add_wifi_psk_connection_profile(args)

0 commit comments

Comments
 (0)