uictlapi 0.1.2__tar.gz → 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,177 @@
1
+ Metadata-Version: 2.4
2
+ Name: uictlapi
3
+ Version: 0.1.4
4
+ Summary: Curl-like CLI for the UniFi Controller / UniFi OS Web UI API, with login and CSRF handled for you.
5
+ Author-email: Roman Akinfeev <akinfold@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/akinfold/uictlapi
8
+ Project-URL: Repository, https://github.com/akinfold/uictlapi
9
+ Project-URL: Issues, https://github.com/akinfold/uictlapi/issues
10
+ Project-URL: Changelog, https://github.com/akinfold/uictlapi/blob/main/CHANGELOG.md
11
+ Keywords: unifi,ubiquiti,api,cli,networking,controller,docker
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: System Administrators
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.8
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Topic :: Internet
25
+ Classifier: Topic :: System :: Networking
26
+ Classifier: Topic :: Utilities
27
+ Requires-Python: >=3.8
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: click>=8.0.0
31
+ Requires-Dist: idna>=3.15
32
+ Requires-Dist: requests>=2.32.4
33
+ Requires-Dist: requests-unifi-auth>=0.2.0
34
+ Provides-Extra: test
35
+ Requires-Dist: pytest>=7.0.0; extra == "test"
36
+ Requires-Dist: pytest-cov>=4.0.0; extra == "test"
37
+ Requires-Dist: ruff>=0.8.0; extra == "test"
38
+ Requires-Dist: packaging>=23.0; extra == "test"
39
+ Dynamic: license-file
40
+
41
+ # uictlapi
42
+
43
+ [![PyPI](https://img.shields.io/pypi/v/uictlapi.svg?logo=pypi&logoColor=white)](https://pypi.org/project/uictlapi/)
44
+ [![Coverage](https://akinfold.github.io/uictlapi/coverage.svg)](https://github.com/akinfold/uictlapi/actions/workflows/test.yml)
45
+ [![Docker](https://img.shields.io/docker/v/akinfold/uictlapi/latest?logo=docker&logoColor=white&label=docker)](https://hub.docker.com/r/akinfold/uictlapi)
46
+ [![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/akinfold/uictlapi/blob/main/LICENSE)
47
+ [![CodeFactor](https://www.codefactor.io/repository/github/akinfold/uictlapi/badge)](https://www.codefactor.io/repository/github/akinfold/uictlapi)
48
+ [![Downloads](https://static.pepy.tech/badge/uictlapi)](https://pepy.tech/project/uictlapi)
49
+
50
+ Curl-like CLI for the UniFi Controller / UniFi OS Web UI API — with login and CSRF
51
+ handled for you.
52
+
53
+ Auth and CSRF come from
54
+ [`requests-unifi-auth`](https://github.com/akinfold/requests-unifi-auth). This package is
55
+ only the HTTP CLI: any Web UI / proxy URL, any method. It is **not** a typed UniFi SDK and
56
+ does not invent domain commands (`routes apply`, inventory, multi-controller orchestration).
57
+
58
+ Live auth/CSRF compatibility against real controllers is tracked in
59
+ [`requests-unifi-auth` COMPATIBILITY.md](https://github.com/akinfold/requests-unifi-auth/blob/main/COMPATIBILITY.md).
60
+ Verified with this CLI: **uictlapi 0.1.3** against **UniFi Network 10.5.67**
61
+ (`GET …/trafficroutes` → HTTP 200, 2026-08-24).
62
+
63
+ See the [changelog](CHANGELOG.md) for release history.
64
+ Security reports are handled through the [security policy](SECURITY.md).
65
+
66
+ ## Installation
67
+
68
+ ### pip
69
+
70
+ ```bash
71
+ pip install uictlapi
72
+ ```
73
+
74
+ Requires `requests>=2.32.4` and `requests-unifi-auth>=0.2.0`.
75
+
76
+ ### Docker
77
+
78
+ ```bash
79
+ docker run --rm akinfold/uictlapi:latest --help
80
+ ```
81
+
82
+ ## Finding API URLs
83
+
84
+ UniFi does not publish a stable public catalog of every Web UI path. Copy them from the
85
+ browser:
86
+
87
+ 1. Open the UniFi Network UI and sign in.
88
+ 2. Open DevTools → **Network**, filter by Fetch/XHR.
89
+ 3. Click the screen that does what you want (traffic routes, clients, …).
90
+ 4. Pick a request to your controller (often under `/proxy/network/...`).
91
+ 5. Copy the full URL (or path) and reuse it with `uictlapi get|post|…`.
92
+
93
+ Paths change between UniFi Network versions; treat DevTools as the source of truth.
94
+
95
+ ## Safety
96
+
97
+ - Create a **dedicated local Admin** for automation (not Owner / Super Admin). Prefer the
98
+ minimum role that can call the endpoints you need.
99
+ - Store credentials in a file with mode `600`, not in the shell history:
100
+
101
+ ```bash
102
+ mkdir -p ~/.config/uictlapi
103
+ printf '%s\n' 'user' 'pass' 'controller.example' > ~/.config/uictlapi/auth
104
+ chmod 600 ~/.config/uictlapi/auth
105
+ ```
106
+
107
+ - Prefer an auth file that includes the **host[:port]** (three-line form or
108
+ `user:pass@host[:port]`). The CLI refuses to send credentials unless the scheme,
109
+ normalized hostname, and effective port match the request URL exactly.
110
+ - TLS certificate verification is enabled by default. Use `--ca-bundle PATH` to trust a
111
+ specific CA bundle. `--no-verify` disables certificate checks and should be limited to
112
+ a trusted lab network.
113
+ - HTTP authentication sends credentials in plaintext and is disabled by default. When
114
+ `--auth` targets an HTTP URL, use `--allow-insecure-http` only when that risk is
115
+ intentional.
116
+ - Never paste passwords, cookies, or CSRF tokens into issues or chat logs.
117
+
118
+ ## Usage
119
+
120
+ Auth (`-a` / `--auth`):
121
+
122
+ - `user:pass@host`
123
+ - three-line file — `username`, `password`, `host` (password may contain `:` and `@`)
124
+ - `user:pass` or two-line `user` / `pass` — host from the request URL (less safe;
125
+ prefer an explicit host in the file)
126
+ - `@/path/to/file` — file contains any of the forms above
127
+
128
+ ```bash
129
+ uictlapi get -a @$HOME/.config/uictlapi/auth \
130
+ 'https://controller.example/proxy/network/v2/api/site/default/trafficroutes'
131
+ ```
132
+
133
+ ```bash
134
+ # Inline (host in the auth string)
135
+ uictlapi get -a 'user:pass@controller.example' \
136
+ 'https://controller.example/proxy/network/v2/api/site/default/trafficroutes'
137
+
138
+ # Same via Docker (mount the auth file)
139
+ docker run --rm -v "$HOME/.config/uictlapi/auth:/auth:ro" akinfold/uictlapi:latest \
140
+ get -a @/auth \
141
+ 'https://controller.example/proxy/network/v2/api/site/default/trafficroutes'
142
+
143
+ # POST JSON body (from string or @file)
144
+ uictlapi post -a @$HOME/.config/uictlapi/auth \
145
+ -j '{"enabled":true}' \
146
+ 'https://controller.example/proxy/network/v2/api/site/default/some-endpoint'
147
+
148
+ uictlapi --version
149
+ ```
150
+
151
+ Common flags mirror curl-ish habits: `-H` / `-p` / `-d` / `-j` / `-o` / `--show-headers` /
152
+ `--status-only` / `--no-verify` / `--ca-bundle` / `--allow-insecure-http` / `-t`. Exit
153
+ status `1` on HTTP ≥ 400, `2` on transport errors (including auth origin mismatch).
154
+
155
+ ## Releasing
156
+
157
+ Version lives in `pyproject.toml` and `src/uictlapi/__init__.py`. Bump on `main` first
158
+ (GitHub Actions → **Bump version**, or locally with `bump-my-version`), then:
159
+
160
+ ```bash
161
+ git tag vX.Y.Z
162
+ git push origin vX.Y.Z
163
+ ```
164
+
165
+ The **Publish** workflow runs tests, uploads to PyPI, pushes multi-arch Docker images
166
+ (`X.Y.Z`, `X.Y`, and `latest` when appropriate), and creates a GitHub Release.
167
+
168
+ ### Auto-sync of `requests-unifi-auth`
169
+
170
+ The **Sync requests-unifi-auth** workflow (schedule every 6 hours, or manual
171
+ `workflow_dispatch`) checks PyPI for a newer `requests-unifi-auth`, raises the
172
+ `>=` floor, bumps this package's patch version, pushes `main` + tag, and
173
+ dispatches **Publish** on that tag.
174
+
175
+ ## License
176
+
177
+ MIT
@@ -0,0 +1,137 @@
1
+ # uictlapi
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/uictlapi.svg?logo=pypi&logoColor=white)](https://pypi.org/project/uictlapi/)
4
+ [![Coverage](https://akinfold.github.io/uictlapi/coverage.svg)](https://github.com/akinfold/uictlapi/actions/workflows/test.yml)
5
+ [![Docker](https://img.shields.io/docker/v/akinfold/uictlapi/latest?logo=docker&logoColor=white&label=docker)](https://hub.docker.com/r/akinfold/uictlapi)
6
+ [![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/akinfold/uictlapi/blob/main/LICENSE)
7
+ [![CodeFactor](https://www.codefactor.io/repository/github/akinfold/uictlapi/badge)](https://www.codefactor.io/repository/github/akinfold/uictlapi)
8
+ [![Downloads](https://static.pepy.tech/badge/uictlapi)](https://pepy.tech/project/uictlapi)
9
+
10
+ Curl-like CLI for the UniFi Controller / UniFi OS Web UI API — with login and CSRF
11
+ handled for you.
12
+
13
+ Auth and CSRF come from
14
+ [`requests-unifi-auth`](https://github.com/akinfold/requests-unifi-auth). This package is
15
+ only the HTTP CLI: any Web UI / proxy URL, any method. It is **not** a typed UniFi SDK and
16
+ does not invent domain commands (`routes apply`, inventory, multi-controller orchestration).
17
+
18
+ Live auth/CSRF compatibility against real controllers is tracked in
19
+ [`requests-unifi-auth` COMPATIBILITY.md](https://github.com/akinfold/requests-unifi-auth/blob/main/COMPATIBILITY.md).
20
+ Verified with this CLI: **uictlapi 0.1.3** against **UniFi Network 10.5.67**
21
+ (`GET …/trafficroutes` → HTTP 200, 2026-08-24).
22
+
23
+ See the [changelog](CHANGELOG.md) for release history.
24
+ Security reports are handled through the [security policy](SECURITY.md).
25
+
26
+ ## Installation
27
+
28
+ ### pip
29
+
30
+ ```bash
31
+ pip install uictlapi
32
+ ```
33
+
34
+ Requires `requests>=2.32.4` and `requests-unifi-auth>=0.2.0`.
35
+
36
+ ### Docker
37
+
38
+ ```bash
39
+ docker run --rm akinfold/uictlapi:latest --help
40
+ ```
41
+
42
+ ## Finding API URLs
43
+
44
+ UniFi does not publish a stable public catalog of every Web UI path. Copy them from the
45
+ browser:
46
+
47
+ 1. Open the UniFi Network UI and sign in.
48
+ 2. Open DevTools → **Network**, filter by Fetch/XHR.
49
+ 3. Click the screen that does what you want (traffic routes, clients, …).
50
+ 4. Pick a request to your controller (often under `/proxy/network/...`).
51
+ 5. Copy the full URL (or path) and reuse it with `uictlapi get|post|…`.
52
+
53
+ Paths change between UniFi Network versions; treat DevTools as the source of truth.
54
+
55
+ ## Safety
56
+
57
+ - Create a **dedicated local Admin** for automation (not Owner / Super Admin). Prefer the
58
+ minimum role that can call the endpoints you need.
59
+ - Store credentials in a file with mode `600`, not in the shell history:
60
+
61
+ ```bash
62
+ mkdir -p ~/.config/uictlapi
63
+ printf '%s\n' 'user' 'pass' 'controller.example' > ~/.config/uictlapi/auth
64
+ chmod 600 ~/.config/uictlapi/auth
65
+ ```
66
+
67
+ - Prefer an auth file that includes the **host[:port]** (three-line form or
68
+ `user:pass@host[:port]`). The CLI refuses to send credentials unless the scheme,
69
+ normalized hostname, and effective port match the request URL exactly.
70
+ - TLS certificate verification is enabled by default. Use `--ca-bundle PATH` to trust a
71
+ specific CA bundle. `--no-verify` disables certificate checks and should be limited to
72
+ a trusted lab network.
73
+ - HTTP authentication sends credentials in plaintext and is disabled by default. When
74
+ `--auth` targets an HTTP URL, use `--allow-insecure-http` only when that risk is
75
+ intentional.
76
+ - Never paste passwords, cookies, or CSRF tokens into issues or chat logs.
77
+
78
+ ## Usage
79
+
80
+ Auth (`-a` / `--auth`):
81
+
82
+ - `user:pass@host`
83
+ - three-line file — `username`, `password`, `host` (password may contain `:` and `@`)
84
+ - `user:pass` or two-line `user` / `pass` — host from the request URL (less safe;
85
+ prefer an explicit host in the file)
86
+ - `@/path/to/file` — file contains any of the forms above
87
+
88
+ ```bash
89
+ uictlapi get -a @$HOME/.config/uictlapi/auth \
90
+ 'https://controller.example/proxy/network/v2/api/site/default/trafficroutes'
91
+ ```
92
+
93
+ ```bash
94
+ # Inline (host in the auth string)
95
+ uictlapi get -a 'user:pass@controller.example' \
96
+ 'https://controller.example/proxy/network/v2/api/site/default/trafficroutes'
97
+
98
+ # Same via Docker (mount the auth file)
99
+ docker run --rm -v "$HOME/.config/uictlapi/auth:/auth:ro" akinfold/uictlapi:latest \
100
+ get -a @/auth \
101
+ 'https://controller.example/proxy/network/v2/api/site/default/trafficroutes'
102
+
103
+ # POST JSON body (from string or @file)
104
+ uictlapi post -a @$HOME/.config/uictlapi/auth \
105
+ -j '{"enabled":true}' \
106
+ 'https://controller.example/proxy/network/v2/api/site/default/some-endpoint'
107
+
108
+ uictlapi --version
109
+ ```
110
+
111
+ Common flags mirror curl-ish habits: `-H` / `-p` / `-d` / `-j` / `-o` / `--show-headers` /
112
+ `--status-only` / `--no-verify` / `--ca-bundle` / `--allow-insecure-http` / `-t`. Exit
113
+ status `1` on HTTP ≥ 400, `2` on transport errors (including auth origin mismatch).
114
+
115
+ ## Releasing
116
+
117
+ Version lives in `pyproject.toml` and `src/uictlapi/__init__.py`. Bump on `main` first
118
+ (GitHub Actions → **Bump version**, or locally with `bump-my-version`), then:
119
+
120
+ ```bash
121
+ git tag vX.Y.Z
122
+ git push origin vX.Y.Z
123
+ ```
124
+
125
+ The **Publish** workflow runs tests, uploads to PyPI, pushes multi-arch Docker images
126
+ (`X.Y.Z`, `X.Y`, and `latest` when appropriate), and creates a GitHub Release.
127
+
128
+ ### Auto-sync of `requests-unifi-auth`
129
+
130
+ The **Sync requests-unifi-auth** workflow (schedule every 6 hours, or manual
131
+ `workflow_dispatch`) checks PyPI for a newer `requests-unifi-auth`, raises the
132
+ `>=` floor, bumps this package's patch version, pushes `main` + tag, and
133
+ dispatches **Publish** on that tag.
134
+
135
+ ## License
136
+
137
+ MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "uictlapi"
7
- version = "0.1.2"
7
+ version = "0.1.4"
8
8
  description = "Curl-like CLI for the UniFi Controller / UniFi OS Web UI API, with login and CSRF handled for you."
9
9
  readme = "README.md"
10
10
  authors = [{name = "Roman Akinfeev", email = "akinfold@gmail.com"}]
@@ -12,8 +12,9 @@ license = {text = "MIT"}
12
12
  requires-python = ">=3.8"
13
13
  dependencies = [
14
14
  "click>=8.0.0",
15
- "requests>=2.25.0",
16
- "requests-unifi-auth>=0.1.5",
15
+ "idna>=3.15",
16
+ "requests>=2.32.4",
17
+ "requests-unifi-auth>=0.2.0",
17
18
  ]
18
19
  keywords = ["unifi", "ubiquiti", "api", "cli", "networking", "controller", "docker"]
19
20
  classifiers = [
@@ -38,6 +39,7 @@ classifiers = [
38
39
  Homepage = "https://github.com/akinfold/uictlapi"
39
40
  Repository = "https://github.com/akinfold/uictlapi"
40
41
  Issues = "https://github.com/akinfold/uictlapi/issues"
42
+ Changelog = "https://github.com/akinfold/uictlapi/blob/main/CHANGELOG.md"
41
43
 
42
44
  [project.scripts]
43
45
  uictlapi = "uictlapi.cli:cli"
@@ -47,6 +49,7 @@ test = [
47
49
  "pytest>=7.0.0",
48
50
  "pytest-cov>=4.0.0",
49
51
  "ruff>=0.8.0",
52
+ "packaging>=23.0",
50
53
  ]
51
54
 
52
55
  [tool.setuptools.packages.find]
@@ -74,7 +77,7 @@ omit = [
74
77
  ]
75
78
 
76
79
  [tool.bumpversion]
77
- current_version = "0.1.2"
80
+ current_version = "0.1.4"
78
81
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
79
82
  serialize = ["{major}.{minor}.{patch}"]
80
83
  search = "{current_version}"
@@ -1,4 +1,4 @@
1
- __version__ = "0.1.2"
1
+ __version__ = "0.1.4"
2
2
 
3
3
  __all__ = [
4
4
  "__version__",