<div align="center">
<img src="https://github.com/home-assistant/brands/blob/master/core_brands/ubiquiti/icon.png?raw=true" alt="Ubiquiti airOS Logo" width="150" />
<h1>python-airos</h1>
<p>An asynchronous Python module to interact with Ubiquiti airOS devices, emulating a web browser client.</p>
</div>
<div align="center">
</div>
[](https://github.com/python-airos)
[](https://coderabbit.ai)
[](https://github.com/compatech/python-airos/issues/8)
[](https://pypi.python.org/pypi/airos/)
[](https://github.com/compatech/python-airos/actions)
[](https://github.com/compatech/python-airos/actions)
[](https://www.codefactor.io/repository/github/plugwise/python-airos)
[](https://codecov.io/gh/compatech/python-airos)
[](https://sonarcloud.io/summary/new_code?id=CoMPaTech_python-airos)
[](https://sonarcloud.io/summary/new_code?id=CoMPaTech_python-airos)
[](https://sonarcloud.io/summary/new_code?id=CoMPaTech_python-airos)
# Overview
`python-airos` or [`airos`](https://pypi.org/projects/airos) from pypi is an asynchronous Python library designed to programmatically interact with Ubiquiti airOS devices. It mimics a web browser client to fetch device status, configuration, and perform actions like kicking connected stations.
This library is a key component for a potential future core integration with [Home Assistant](https://www.home-assistant.io), with the initial pull request for core integration targeted for the 2025.8 release.
More details on the integration can be found on the [Ubiquiti UISP airOS](https://www.home-assistant.io/integrations/airos/) page. To add airOS directly feel free to use the button below:
[](https://my.home-assistant.io/redirect/_change/?redirect=config_flow_start%2F%3Fdomain%3Dairos)
## Features
- Asynchronous Operations: Built with `asyncio` and `aiohttp` for non-blocking I/O, which is perfect for integrations and background tasks.
- Client Emulation: Authenticates and interacts with airOS devices by emulating a client browser, ensuring a high degree of compatibility.
- Data Retrieval: Fetches comprehensive device status information, including:
- Wireless mode and signal strength.
- Connected stations and their statistics.
- System information and uptime.
- Device Control: Provides methods to perform actions, such as reconnecting/kicking a connected wireless station.
- Discovery of airOS devices on your local network (by listening to announcements these devices broadcast).
## Installation
You can install python-airos from PyPI using pip:
```Bash
pip install airos
```
## Usage
Here is a more detailed example of how to use the library to connect, fetch status, and perform an action on an airOS device.
```Python
import aiohttp
import asyncio
from airos.airos8 import AirOS
async def main():
"""Main function to demonstrate library usage."""
# Create an aiohttp session with SSL verification disabled.
# Be cautious with this setting; it's useful for self-signed certificates
# but not recommended for production environments without proper validation.
session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False))
# Initialize the AirOS device object.
device = AirOS(
host="192.168.1.2",
username="ubnt",
password="password",
session=session
)
try:
# Step 1: Login to the device.
login_result = await device.login()
print(f"Login successful: {login_result}")
# Step 2: Fetch the device status.
status_data = await device.status()
print("\n--- Device Status ---")
print(f"Device Name: {status_data.host.hostname}")
print(f"Wireless Mode: {status_data.wireless.mode}")
print(f"Firmware Version: {status_data.host.fwversion}")
# Fetch and display connected stations if available
if status_data.wireless.stations:
print("\n--- Connected Stations ---")
for station in status_data.wireless.stations:
print(f" - MAC: {station.mac}")
print(f" Signal: {station.signal} dBm")
print(f" Uptime: {station.uptime} seconds")
# Step 3: Perform an action, e.g., kick a station.
# Replace '01:23:45:67:89:AB' with the MAC address of a station to kick.
# kick_result = await device.stakick("01:23:45:67:89:AB")
# print(f"\nKick station result: {kick_result}")
except Exception as e:
print(f"An error occurred: {e}")
finally:
# Ensure the aiohttp session is closed properly.
await session.close()
if __name__ == "__main__":
asyncio.run(main())
```
## Supported API classes and calls
### Classes
- `airos.data` (directly) as well as `airos.airos8` (indirectly) provides `AirOSData`, a [mashumaro](https://pypi.org/project/mashumaro/) based dataclass
- `airos.discovery` provides `AirOSDiscoveryProtocol` for the actual discovery, we recommend to use the `async_discover_devices` function for consumption as described below
### Calls
- `airos.airos8`: initializes with `host: str, username: str, password: str, session: aiohttp.ClientSession`
- `login()`: Authenticates with the device.
- `status()`: Fetches a comprehensive dictionary of the device's status and statistics.
- `warnings()`: Retrieves warning status dict.
- `stakick(mac_address: str)`: Disconnects a specific station by its MAC address.
- `provmode(active: bool = False)`: Enables or disables the provisioning mode.
- `update_check(force: bool = False)`: Checks if new firmware has been discovered (or force to force check).
- `download()`: Starts downloading (not installing) new firmware.
- `progress()`: Fetches the firmware download (not install!) progress.
- `install()`: Installs the new firmware.
- `airos.discovery`
- `async_discover_devices(timeout: int)` mainly for consumption by HA's `config_flow` returning a dict mapping mac-addresses to discovered info.
#### Information
##### Update
Will return either ```{"update": False}``` or the full information regarding the available update:
```json
{"checksum": "b1bea879a9f518f714ce638172e3a860", "version": "v8.7.19", "security": "", "date": "250811", "url": "https://dl.ubnt.com/firmwares/XC-fw/v8.7.19/WA.v8.7.19.48279.250811.0636.bin", "update": True, "changelog": "https://dl.ubnt.com/firmwares/XC-fw/v8.7.19/changelog.txt"}
```
##### Progress
If no progress to report ```{"progress": -1}``` otherwise a positive value between 0 and 100.
##### Install
Only a positive outcome is expected from the user experience; the call should return:
```json
{
"ok": true,
"code": 0
}
```
#### Warnings
Will respond with something like:
```json
{
"isDefaultPasswd": false,
"customScripts": false,
"isWatchdogReset": 0,
"label": 0,
"chAvailable": false,
"emergReasonCode": -1,
"firmware": {
"isThirdParty": false,
"version": "",
"uploaded": false
}
}
```
## Contributing
We welcome contributions as well as additional codeowners to python-airos.
Raw data
{
"_id": null,
"home_page": null,
"name": "airos",
"maintainer": "CoMPaTech",
"docs_url": null,
"requires_python": ">=3.13",
"maintainer_email": null,
"keywords": "home, automation, ubiquiti, uisp, airos, module",
"author": null,
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/50/47/48a0213df09b227051fcbda920a5855c10eb1082d2a52dbfdc854971f084/airos-0.4.4.tar.gz",
"platform": null,
"description": "<div align=\"center\">\n<img src=\"https://github.com/home-assistant/brands/blob/master/core_brands/ubiquiti/icon.png?raw=true\" alt=\"Ubiquiti airOS Logo\" width=\"150\" />\n<h1>python-airos</h1>\n<p>An asynchronous Python module to interact with Ubiquiti airOS devices, emulating a web browser client.</p>\n</div>\n\n<div align=\"center\">\n\n</div>\n\n[](https://github.com/python-airos)\n[](https://coderabbit.ai)\n[](https://github.com/compatech/python-airos/issues/8)\n\n[](https://pypi.python.org/pypi/airos/)\n[](https://github.com/compatech/python-airos/actions)\n[](https://github.com/compatech/python-airos/actions)\n\n[](https://www.codefactor.io/repository/github/plugwise/python-airos)\n[](https://codecov.io/gh/compatech/python-airos)\n\n[](https://sonarcloud.io/summary/new_code?id=CoMPaTech_python-airos)\n[](https://sonarcloud.io/summary/new_code?id=CoMPaTech_python-airos)\n[](https://sonarcloud.io/summary/new_code?id=CoMPaTech_python-airos)\n\n# Overview\n\n`python-airos` or [`airos`](https://pypi.org/projects/airos) from pypi is an asynchronous Python library designed to programmatically interact with Ubiquiti airOS devices. It mimics a web browser client to fetch device status, configuration, and perform actions like kicking connected stations.\n\nThis library is a key component for a potential future core integration with [Home Assistant](https://www.home-assistant.io), with the initial pull request for core integration targeted for the 2025.8 release.\n\nMore details on the integration can be found on the [Ubiquiti UISP airOS](https://www.home-assistant.io/integrations/airos/) page. To add airOS directly feel free to use the button below:\n\n[](https://my.home-assistant.io/redirect/_change/?redirect=config_flow_start%2F%3Fdomain%3Dairos)\n\n## Features\n\n- Asynchronous Operations: Built with `asyncio` and `aiohttp` for non-blocking I/O, which is perfect for integrations and background tasks.\n- Client Emulation: Authenticates and interacts with airOS devices by emulating a client browser, ensuring a high degree of compatibility.\n- Data Retrieval: Fetches comprehensive device status information, including:\n- Wireless mode and signal strength.\n- Connected stations and their statistics.\n- System information and uptime.\n- Device Control: Provides methods to perform actions, such as reconnecting/kicking a connected wireless station.\n- Discovery of airOS devices on your local network (by listening to announcements these devices broadcast).\n\n## Installation\n\nYou can install python-airos from PyPI using pip:\n\n```Bash\npip install airos\n```\n\n## Usage\n\nHere is a more detailed example of how to use the library to connect, fetch status, and perform an action on an airOS device.\n\n```Python\nimport aiohttp\nimport asyncio\nfrom airos.airos8 import AirOS\n\nasync def main():\n \"\"\"Main function to demonstrate library usage.\"\"\"\n # Create an aiohttp session with SSL verification disabled.\n # Be cautious with this setting; it's useful for self-signed certificates\n # but not recommended for production environments without proper validation.\n session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False))\n\n # Initialize the AirOS device object.\n device = AirOS(\n host=\"192.168.1.2\",\n username=\"ubnt\",\n password=\"password\",\n session=session\n )\n\n try:\n # Step 1: Login to the device.\n login_result = await device.login()\n print(f\"Login successful: {login_result}\")\n\n # Step 2: Fetch the device status.\n status_data = await device.status()\n print(\"\\n--- Device Status ---\")\n print(f\"Device Name: {status_data.host.hostname}\")\n print(f\"Wireless Mode: {status_data.wireless.mode}\")\n print(f\"Firmware Version: {status_data.host.fwversion}\")\n\n # Fetch and display connected stations if available\n if status_data.wireless.stations:\n print(\"\\n--- Connected Stations ---\")\n for station in status_data.wireless.stations:\n print(f\" - MAC: {station.mac}\")\n print(f\" Signal: {station.signal} dBm\")\n print(f\" Uptime: {station.uptime} seconds\")\n\n # Step 3: Perform an action, e.g., kick a station.\n # Replace '01:23:45:67:89:AB' with the MAC address of a station to kick.\n # kick_result = await device.stakick(\"01:23:45:67:89:AB\")\n # print(f\"\\nKick station result: {kick_result}\")\n\n except Exception as e:\n print(f\"An error occurred: {e}\")\n finally:\n # Ensure the aiohttp session is closed properly.\n await session.close()\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\n## Supported API classes and calls\n\n### Classes\n\n- `airos.data` (directly) as well as `airos.airos8` (indirectly) provides `AirOSData`, a [mashumaro](https://pypi.org/project/mashumaro/) based dataclass\n- `airos.discovery` provides `AirOSDiscoveryProtocol` for the actual discovery, we recommend to use the `async_discover_devices` function for consumption as described below\n\n### Calls\n\n- `airos.airos8`: initializes with `host: str, username: str, password: str, session: aiohttp.ClientSession`\n\n - `login()`: Authenticates with the device.\n - `status()`: Fetches a comprehensive dictionary of the device's status and statistics.\n - `warnings()`: Retrieves warning status dict.\n\n - `stakick(mac_address: str)`: Disconnects a specific station by its MAC address.\n - `provmode(active: bool = False)`: Enables or disables the provisioning mode.\n\n - `update_check(force: bool = False)`: Checks if new firmware has been discovered (or force to force check).\n\n - `download()`: Starts downloading (not installing) new firmware.\n - `progress()`: Fetches the firmware download (not install!) progress.\n - `install()`: Installs the new firmware.\n\n- `airos.discovery`\n - `async_discover_devices(timeout: int)` mainly for consumption by HA's `config_flow` returning a dict mapping mac-addresses to discovered info.\n\n#### Information\n\n##### Update\n\nWill return either ```{\"update\": False}``` or the full information regarding the available update:\n\n```json\n{\"checksum\": \"b1bea879a9f518f714ce638172e3a860\", \"version\": \"v8.7.19\", \"security\": \"\", \"date\": \"250811\", \"url\": \"https://dl.ubnt.com/firmwares/XC-fw/v8.7.19/WA.v8.7.19.48279.250811.0636.bin\", \"update\": True, \"changelog\": \"https://dl.ubnt.com/firmwares/XC-fw/v8.7.19/changelog.txt\"}\n```\n\n##### Progress\n\nIf no progress to report ```{\"progress\": -1}``` otherwise a positive value between 0 and 100.\n\n##### Install\n\nOnly a positive outcome is expected from the user experience; the call should return:\n\n```json\n{\n \"ok\": true,\n \"code\": 0\n}\n```\n\n#### Warnings\n\nWill respond with something like:\n\n```json\n{\n \"isDefaultPasswd\": false,\n \"customScripts\": false,\n \"isWatchdogReset\": 0,\n \"label\": 0,\n \"chAvailable\": false,\n \"emergReasonCode\": -1,\n \"firmware\": {\n \"isThirdParty\": false,\n \"version\": \"\",\n \"uploaded\": false\n }\n}\n```\n\n## Contributing\n\nWe welcome contributions as well as additional codeowners to python-airos.\n",
"bugtrack_url": null,
"license": null,
"summary": "Ubiquiti airOS module(s) for Python 3.",
"version": "0.4.4",
"project_urls": {
"Bug Reports": "https://github.com/compatech/python-airos/issues",
"Source Code": "https://github.com/compatech/python-airos"
},
"split_keywords": [
"home",
" automation",
" ubiquiti",
" uisp",
" airos",
" module"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "bd708e95f6c8c643c4c39d1e1cbdc0489a7dcdd5cb07f31fdddea2aea723bb68",
"md5": "170201604b6a7ef7d8cb9a2f6d71e4d9",
"sha256": "0efb05fda68ab3199cc7827e1fac9c3ada5f02a8bd953eb937c3c9f26e48ac03"
},
"downloads": -1,
"filename": "airos-0.4.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "170201604b6a7ef7d8cb9a2f6d71e4d9",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.13",
"size": 16820,
"upload_time": "2025-08-29T05:20:51",
"upload_time_iso_8601": "2025-08-29T05:20:51.149983Z",
"url": "https://files.pythonhosted.org/packages/bd/70/8e95f6c8c643c4c39d1e1cbdc0489a7dcdd5cb07f31fdddea2aea723bb68/airos-0.4.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "504748a0213df09b227051fcbda920a5855c10eb1082d2a52dbfdc854971f084",
"md5": "c6ec68c2de0f0f1f92d8f67a7cf25aaa",
"sha256": "c63201b914be9ed4812a8ea3b3dffb5a3787319d5ac7830de614451c28efa15c"
},
"downloads": -1,
"filename": "airos-0.4.4.tar.gz",
"has_sig": false,
"md5_digest": "c6ec68c2de0f0f1f92d8f67a7cf25aaa",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.13",
"size": 38943,
"upload_time": "2025-08-29T05:20:52",
"upload_time_iso_8601": "2025-08-29T05:20:52.562488Z",
"url": "https://files.pythonhosted.org/packages/50/47/48a0213df09b227051fcbda920a5855c10eb1082d2a52dbfdc854971f084/airos-0.4.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-29 05:20:52",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "compatech",
"github_project": "python-airos",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "aiohttp",
"specs": [
[
"==",
"3.12.15"
]
]
},
{
"name": "mashumaro",
"specs": [
[
"==",
"3.16"
]
]
}
],
"lcname": "airos"
}