Metadata-Version: 2.4
Name: glinet4
Version: 0.2.4
Summary: A Python 3 async API wrapper for GL.iNet routers (firmware 4.x JSON-RPC API)
Keywords: gl-inet,glinet,router,openwrt,json-rpc,async,home-assistant
Author: glinet4 contributors
License-Expression: GPL-3.0-or-later
License-File: LICENSE
License-File: NOTICE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Framework :: AsyncIO
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: System :: Networking
Classifier: Topic :: Home Automation
Classifier: Typing :: Typed
Requires-Dist: libpass>=1.8.0
Requires-Dist: semver>=3.0.0
Requires-Dist: aiohttp>=3.10
Requires-Python: >=3.11
Project-URL: Homepage, https://github.com/glinet4/glinet4
Project-URL: Repository, https://github.com/glinet4/glinet4
Project-URL: Issues, https://github.com/glinet4/glinet4/issues
Description-Content-Type: text/markdown

<p align="center">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/glinet4/branding/main/assets/dark_logo.png">
    <img alt="glinet4" src="https://raw.githubusercontent.com/glinet4/branding/main/assets/logo.png" width="300">
  </picture>
</p>

# glinet4

[![PyPI](https://img.shields.io/pypi/v/glinet4)](https://pypi.org/project/glinet4/) [![License: GPL-3.0](https://img.shields.io/badge/License-GPLv3-blue.svg)](LICENSE)

## Quickstart

```python
import asyncio

from glinet4 import GLinet


async def main() -> None:
    async with GLinet("http://192.168.8.1/rpc") as router:
        await router.login("root", "your-router-password")
        info = await router.router_info()
        print(info["model"], info["firmware_version"])


asyncio.run(main())
```

Swap in your router's host, username and password. `login()` must succeed before any
other call — see [API coverage](#api-coverage) below for the full method list, and
[CONTRIBUTING.md](CONTRIBUTING.md) for how the test suite talks to a live router.

An async Python 3 API wrapper for [GL.iNet](https://www.gl-inet.com/) routers running version 4.x firmware.

GL.iNet routers are built on [OpenWRT](https://openwrt.org/) and expose a local [JSON-RPC API](https://web.archive.org/web/20240121142533/https://dev.gl-inet.com/router-4.x-api/). `glinet4` wraps that API for easy integration into other services such as [Home Assistant](https://www.home-assistant.io/).

> `glinet4` began as a fork of [HarvsG/gli4py](https://github.com/HarvsG/gli4py) (GPL-3.0) and has since grown a much larger API surface. See [NOTICE](NOTICE) for attribution.

## Installation
`pip install glinet4`

## Dev setup
1. Clone the repo
2. Ensure you have Python 3.11 or greater (`python3 -V`) and install [uv](https://docs.astral.sh/uv/).
3. `uv sync` — creates the in-project `.venv` and installs the runtime + dev dependencies.
4. `uvx prek install` — sets up the git pre-commit hooks (ruff, mypy, file hygiene).
   Run them on demand with `uvx prek run --all-files`.
5. The tests run against a **live router**, so copy `.env.example` to `.env` and set at least
   `GLINET_PASSWORD` (and `GLINET_HOST` if not `192.168.8.1`). Without it the live suite is skipped.
6. `uv run pytest -s` to see responses.
7. Build with `uv build`. Releases publish to PyPI automatically on a GitHub Release (trusted publishing).

See [CONTRIBUTING.md](CONTRIBUTING.md) for the full contributor flow: running the live
suite safely, the pre-commit/CI gates, and how to submit a device capture.

## API coverage

Session: `login`, `router_reachable`. All other methods require login first.

| Area | Methods |
|---|---|
| System | `router_info`, `router_status`, `router_load`, `router_unixtime`, `router_disk_info`, `router_usb_info`, `router_timezone_config`, `router_mac`, `router_reboot` |
| Network / WAN | `ping`, `wan_upstream_router_detected`, `wan_cable_state`, `wan_status`, `wan_info`, `ethernet_ports_status`, `network_mode`, `network_interfaces_status` |
| Network acceleration | `network_acceleration`, `network_acceleration_set` |
| Network services | `dns_config`, `dns_providers`, `arp_table`, `lan_interfaces`, `ipv6_config`, `ddns_config`, `ddns_status` |
| Multi-WAN / repeater / tethering | `multiwan_config`, `multiwan_status`, `repeater_config`, `repeater_status`, `repeater_saved_aps`, `tethering_status`, `tethering_config` |
| QoS / SQM | `qos_config`, `qos_clients`, `qos_device_groups`, `sqm_config` |
| Flow statistics | `flow_stats_rule`, `flow_stats_set_enabled`, `flow_stats_top_apps`, `flow_stats_clear` |
| Clients | `clients_list`, `static_clients_list`, `connected_clients`, `clients_status`, `clients_speed`, `wan_speed`, `client_set_blocked`, `blocked_client_macs` |
| WiFi | `wifi_ifaces`, `wifi_iface_set_enabled`, `wifi_status`, `wifi_mlo_config` |
| Services | `adguard_config`, `tor_config`, `zerotier_config` |
| Firmware | `firmware_check_online`, `upgrade_config` |
| Firewall | `firewall_port_forward_list`, `firewall_dmz`, `firewall_wan_access`, `firewall_rule_list` |
| LED | `led_config`, `led_set_enabled` |
| WireGuard | `wireguard_client_list`, `wireguard_client_state`, `wireguard_client_start`, `wireguard_client_stop`, `wireguard_server_status`, `wireguard_server_config`, `wireguard_server_setting`, `wireguard_server_peers`, `wireguard_server_routes`, `wireguard_client_groups`, `wireguard_client_configs` |
| OpenVPN | `openvpn_server_status`, `openvpn_server_config`, `openvpn_server_setting`, `openvpn_server_users`, `openvpn_server_routes`, `openvpn_client_groups`, `openvpn_client_configs` |
| VPN tunnel state | `vpn_client_status`, `vpn_client_tunnels` |
| Tailscale | `tailscale_configured`, `tailscale_connection_state`, `tailscale_start`, `tailscale_stop`, `tailscale_auth_url`, `tailscale_exit_node_list`, `tailscale_set_exit_node` |

Responses are typed with `TypedDict`s (see `glinet4/_types.py`); the package ships `py.typed`.
The catalogue of routes still to wrap comes from the sanitised device captures submitted to
[glinet4-registry](https://github.com/glinet4/glinet4-registry) — run `uvx glinet4-profiler`
against your own router to contribute one.

Todo list:
- [x] Decide on useful endpoints to expose
- [ ] Expose said endpoints (ongoing — see the table above and glinet4/glinet4 issues)
- [x] Package correctly
- [x] Test that dev enviroment is re-producable
- [x] Publish on pip
- [x] Static typing

## Versioning & stability

`glinet4` is pre-1.0: breaking changes can land in a minor version bump, not just a
major one. [CHANGELOG.md](CHANGELOG.md) (generated by release-please from conventional
commits) is the authoritative record of what changed in each release — check it before
upgrading.

---

Part of the **[glinet4](https://github.com/glinet4)** project — [glinet4](https://github.com/glinet4/glinet4) (Python library) · [glinet4-ha](https://github.com/glinet4/glinet4-ha) (Home Assistant) · [glinet4-profiler](https://github.com/glinet4/glinet4-profiler) · [glinet4-registry](https://github.com/glinet4/glinet4-registry)
