Connect to a WiFi network in Python

Connecting a computer to the internet has become inevitable now. The connection can be made either with Ethernet technology or Wi-Fi technology. Though every Operating System offers way with its simple easy GUI, using the Python script has a nice ring to it. This article explains how a computer can be connected to the internet with Wi-Fi technology using a Python script in Windows and Linux operating systems.

The  netsh and nmcli

netsh is a command-line tool in Windows that offers various facilities for networking. To add a new Wi-Fi connection, Windows requires the credentials to be stored in an XML file.nmcli is a command-line tool in the Linux distributions that offers facilities for networking. Unlike Windows netsh, nmlci is quite simple to use. These commands are used in the Python script to connect to a network.

A Python script to connect with Wi-Fi network

Typing a series of commands every time for connecting to a network can be annoying. With the knowledge of the commands, a Python script can be used to do it. The script works by executing the commands in a subshell. Here is a Python script that connects to a Wi-Fi network, given its name and password (for new networks).

import os
import platform
import getpass

def createNewConnection(name, SSID, key):
    config = """<?xml version=\"1.0\"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
    <name>"""+name+"""</name>
    <SSIDConfig>
        <SSID>
            <name>"""+SSID+"""</name>
        </SSID>
    </SSIDConfig>
    <connectionType>ESS</connectionType>
    <connectionMode>auto</connectionMode>
    <MSM>
        <security>
            <authEncryption>
                <authentication>WPA2PSK</authentication>
                <encryption>AES</encryption>
                <useOneX>false</useOneX>
            </authEncryption>
            <sharedKey>
                <keyType>passPhrase</keyType>
                <protected>false</protected>
                <keyMaterial>"""+key+"""</keyMaterial>
            </sharedKey>
        </security>
    </MSM>
</WLANProfile>"""
    if platform.system() == "Windows":
        command = "netsh wlan add profile filename=\""+name+".xml\""+" interface=Wi-Fi"
        with open(name+".xml", 'w') as file:
            file.write(config)
    elif platform.system() == "Linux":
        command = "nmcli dev wifi connect '"+SSID+"' password '"+key+"'"
    os.system(command)
    if platform.system() == "Windows":
        os.remove(name+".xml")

def connect(name, SSID):
    if platform.system() == "Windows":
        command = "netsh wlan connect name=\""+name+"\" ssid=\""+SSID+"\" interface=Wi-Fi"
    elif platform.system() == "Linux":
        command = "nmcli con up "+SSID
    os.system(command)

def displayAvailableNetworks():
    if platform.system() == "Windows":
        command = "netsh wlan show networks interface=Wi-Fi"
    elif platform.system() == "Linux":
        command = "nmcli dev wifi list"
    os.system(command)

try:
    displayAvailableNetworks()
    option = input("New connection (y/N)? ")
    if option == "N" or option == "":
        name = input("Name: ")
        connect(name, name)
        print("If you aren't connected to this network, try connecting with correct credentials")
    elif option == "y":
        name = input("Name: ")
        key = getpass.getpass("Password: ")
        createNewConnection(name, name, key)
        connect(name, name)
        print("If you aren't connected to this network, try connecting with correct credentials")
except KeyboardInterrupt as e:
    print("\nExiting...")

The script uses platform.system() to identify commands for the appropriate platform. Here the commands are executed in a subshell with os.system() method with a command as its argument. getpass() is a method that can make password invisible when typed. The try-except is used to prevent any runtime exceptions.
Running the script in Windows produces the following output.

Output when connecting to a known network

Interface name : Wi-Fi
There are 1 networks currently visible.

SSID 1 : Lenovo Wi-Fi
    Network type            : Infrastructure      
    Authentication          : WPA2-Personal       
    Encryption              : CCMP

New connection (y/N)?
Name: Lenovo Wi-Fi
Connection request was completed successfully.    
If you aren't connected to this network, try connecting with correct credentials

Output when connecting to a new network

Interface name : Wi-Fi
There are 1 networks currently visible.

SSID 1 : Lenovo Wi-Fi
    Network type            : Infrastructure      
    Authentication          : WPA2-Personal       
    Encryption              : CCMP

New connection (y/N)? y
Attempting to add Profile...
Name: Lenovo Wi-Fi
Password:
Profile Lenovo Wi-Fi is added on interface Wi-Fi.        
Connection request was completed successfully.    
If you aren't connected to this network, try connecting with correct credentials

Running the script in Linux produces some pretty output.

Output when connecting to a known network

IN-USE  BSSID              SSID          MODE   CHAN  RATE       SIGNAL  BARS  SECURITY 
        E4:A7:C5:C1:75:E6  Lenovo Wi-Fi  Infra  11    65 Mbit/s  100     ▂▄▆█  WPA2     
New connection (y/N)? 
Name: Lenovo Wi-Fi
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4)
If you aren't connected to this network, try connecting with correct credentials

Output when connecting to a new network

IN-USE  BSSID              SSID          MODE   CHAN  RATE       SIGNAL  BARS  SECURITY 
        E4:A7:C5:C1:75:E6  Lenovo Wi-Fi  Infra  11    65 Mbit/s  100     ▂▄▆█  WPA2     
New connection (y/N)? y
Name: Lenovo Wi-Fi
Password: 
Device 'wlp2s0' successfully activated with '82005b12-d6a5-4601-9579-113214923eb9'.
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/6)
If you aren't connected to this network, try connecting with correct credentials

I hope you have understood and able to connect with the WiFi network by yourself by writing code in Python.

Leave a Reply

Your email address will not be published. Required fields are marked *