busylib 0.1.0__tar.gz → 0.2.0__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.
Potentially problematic release.
This version of busylib might be problematic. Click here for more details.
- {busylib-0.1.0 → busylib-0.2.0}/PKG-INFO +4 -4
- {busylib-0.1.0 → busylib-0.2.0}/busylib/client.py +45 -34
- {busylib-0.1.0 → busylib-0.2.0}/busylib/types.py +1 -4
- {busylib-0.1.0 → busylib-0.2.0}/busylib.egg-info/PKG-INFO +4 -4
- {busylib-0.1.0 → busylib-0.2.0}/busylib.egg-info/SOURCES.txt +2 -1
- {busylib-0.1.0 → busylib-0.2.0}/pyproject.toml +4 -4
- {busylib-0.1.0 → busylib-0.2.0}/tests/test_client.py +46 -56
- busylib-0.2.0/tests/test_client_init.py +39 -0
- {busylib-0.1.0 → busylib-0.2.0}/LICENSE +0 -0
- {busylib-0.1.0 → busylib-0.2.0}/README.md +0 -0
- {busylib-0.1.0 → busylib-0.2.0}/busylib/__init__.py +0 -0
- {busylib-0.1.0 → busylib-0.2.0}/busylib/exceptions.py +0 -0
- {busylib-0.1.0 → busylib-0.2.0}/busylib.egg-info/dependency_links.txt +0 -0
- {busylib-0.1.0 → busylib-0.2.0}/busylib.egg-info/requires.txt +0 -0
- {busylib-0.1.0 → busylib-0.2.0}/busylib.egg-info/top_level.txt +0 -0
- {busylib-0.1.0 → busylib-0.2.0}/setup.cfg +0 -0
- {busylib-0.1.0 → busylib-0.2.0}/setup.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: busylib
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Python library for Busy Bar API
|
|
5
|
-
Author-email:
|
|
6
|
-
Project-URL: Homepage, https://github.com/busy-app/busylib
|
|
7
|
-
Project-URL: Repository, https://github.com/busy-app/busylib
|
|
5
|
+
Author-email: flipperdevices <pypi@flipperdevices.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/busy-app/busylib-py
|
|
7
|
+
Project-URL: Repository, https://github.com/busy-app/busylib-py
|
|
8
8
|
Project-URL: Documentation, https://busylib.readthedocs.io
|
|
9
9
|
Classifier: Development Status :: 3 - Alpha
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
@@ -29,9 +29,24 @@ class BusyBar:
|
|
|
29
29
|
Main library class for interacting with the Busy Bar API.
|
|
30
30
|
"""
|
|
31
31
|
|
|
32
|
-
def __init__(
|
|
33
|
-
self
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
addr: str | None = None,
|
|
35
|
+
*,
|
|
36
|
+
token: str | None = None,
|
|
37
|
+
) -> None:
|
|
38
|
+
if addr is None and token is None:
|
|
39
|
+
self.base_url = "http://10.0.4.20"
|
|
40
|
+
elif addr is None:
|
|
41
|
+
self.base_url = "https://proxy.dev.busy.app"
|
|
42
|
+
elif addr is not None:
|
|
43
|
+
if "://" not in addr:
|
|
44
|
+
addr = f"http://{addr}"
|
|
45
|
+
self.base_url = addr
|
|
46
|
+
|
|
34
47
|
self.client = requests.Session()
|
|
48
|
+
if token is not None:
|
|
49
|
+
self.client.headers["Authorization"] = f"Bearer {token}"
|
|
35
50
|
|
|
36
51
|
def __enter__(self):
|
|
37
52
|
return self
|
|
@@ -67,9 +82,7 @@ class BusyBar:
|
|
|
67
82
|
return response.text
|
|
68
83
|
|
|
69
84
|
def get_version(self) -> types.VersionInfo:
|
|
70
|
-
response = self.client.get(
|
|
71
|
-
urllib.parse.urljoin(self.base_url, "/api/v0/version")
|
|
72
|
-
)
|
|
85
|
+
response = self.client.get(urllib.parse.urljoin(self.base_url, "/api/version"))
|
|
73
86
|
data = self._handle_response(response)
|
|
74
87
|
return types.VersionInfo(**data)
|
|
75
88
|
|
|
@@ -81,7 +94,7 @@ class BusyBar:
|
|
|
81
94
|
params["name"] = name
|
|
82
95
|
|
|
83
96
|
response = self.client.post(
|
|
84
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
97
|
+
urllib.parse.urljoin(self.base_url, "/api/update"),
|
|
85
98
|
params=params,
|
|
86
99
|
data=firmware_data,
|
|
87
100
|
headers={"Content-Type": "application/octet-stream"},
|
|
@@ -90,9 +103,7 @@ class BusyBar:
|
|
|
90
103
|
return types.SuccessResponse(**data)
|
|
91
104
|
|
|
92
105
|
def get_status(self) -> types.Status:
|
|
93
|
-
response = self.client.get(
|
|
94
|
-
urllib.parse.urljoin(self.base_url, "/api/v0/status")
|
|
95
|
-
)
|
|
106
|
+
response = self.client.get(urllib.parse.urljoin(self.base_url, "/api/status"))
|
|
96
107
|
data = self._handle_response(response)
|
|
97
108
|
|
|
98
109
|
system = None
|
|
@@ -112,14 +123,14 @@ class BusyBar:
|
|
|
112
123
|
|
|
113
124
|
def get_system_status(self) -> types.StatusSystem:
|
|
114
125
|
response = self.client.get(
|
|
115
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
126
|
+
urllib.parse.urljoin(self.base_url, "/api/status/system")
|
|
116
127
|
)
|
|
117
128
|
data = self._handle_response(response)
|
|
118
129
|
return types.StatusSystem(**data)
|
|
119
130
|
|
|
120
131
|
def get_power_status(self) -> types.StatusPower:
|
|
121
132
|
response = self.client.get(
|
|
122
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
133
|
+
urllib.parse.urljoin(self.base_url, "/api/status/power")
|
|
123
134
|
)
|
|
124
135
|
data = self._handle_response(response)
|
|
125
136
|
|
|
@@ -130,7 +141,7 @@ class BusyBar:
|
|
|
130
141
|
|
|
131
142
|
def write_storage_file(self, path: str, data: bytes) -> types.SuccessResponse:
|
|
132
143
|
response = self.client.post(
|
|
133
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
144
|
+
urllib.parse.urljoin(self.base_url, "/api/storage/write"),
|
|
134
145
|
params={"path": path},
|
|
135
146
|
data=data,
|
|
136
147
|
headers={"Content-Type": "application/octet-stream"},
|
|
@@ -140,14 +151,14 @@ class BusyBar:
|
|
|
140
151
|
|
|
141
152
|
def read_storage_file(self, path: str) -> bytes:
|
|
142
153
|
response = self.client.get(
|
|
143
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
154
|
+
urllib.parse.urljoin(self.base_url, "/api/storage/read"),
|
|
144
155
|
params={"path": path},
|
|
145
156
|
)
|
|
146
157
|
return self._handle_response(response, as_bytes=True)
|
|
147
158
|
|
|
148
159
|
def list_storage_files(self, path: str) -> types.StorageList:
|
|
149
160
|
response = self.client.get(
|
|
150
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
161
|
+
urllib.parse.urljoin(self.base_url, "/api/storage/list"),
|
|
151
162
|
params={"path": path},
|
|
152
163
|
)
|
|
153
164
|
data = self._handle_response(response)
|
|
@@ -163,7 +174,7 @@ class BusyBar:
|
|
|
163
174
|
|
|
164
175
|
def remove_storage_file(self, path: str) -> types.SuccessResponse:
|
|
165
176
|
response = self.client.delete(
|
|
166
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
177
|
+
urllib.parse.urljoin(self.base_url, "/api/storage/remove"),
|
|
167
178
|
params={"path": path},
|
|
168
179
|
)
|
|
169
180
|
data = self._handle_response(response)
|
|
@@ -171,7 +182,7 @@ class BusyBar:
|
|
|
171
182
|
|
|
172
183
|
def create_storage_directory(self, path: str) -> types.SuccessResponse:
|
|
173
184
|
response = self.client.post(
|
|
174
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
185
|
+
urllib.parse.urljoin(self.base_url, "/api/storage/mkdir"),
|
|
175
186
|
params={"path": path},
|
|
176
187
|
)
|
|
177
188
|
data = self._handle_response(response)
|
|
@@ -181,7 +192,7 @@ class BusyBar:
|
|
|
181
192
|
self, app_id: str, filename: str, data: bytes
|
|
182
193
|
) -> types.SuccessResponse:
|
|
183
194
|
response = self.client.post(
|
|
184
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
195
|
+
urllib.parse.urljoin(self.base_url, "/api/assets/upload"),
|
|
185
196
|
params={"app_id": app_id, "file": filename},
|
|
186
197
|
data=data,
|
|
187
198
|
headers={"Content-Type": "application/octet-stream"},
|
|
@@ -191,7 +202,7 @@ class BusyBar:
|
|
|
191
202
|
|
|
192
203
|
def delete_app_assets(self, app_id: str) -> types.SuccessResponse:
|
|
193
204
|
response = self.client.delete(
|
|
194
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
205
|
+
urllib.parse.urljoin(self.base_url, "/api/assets/upload"),
|
|
195
206
|
params={"app_id": app_id},
|
|
196
207
|
)
|
|
197
208
|
data = self._handle_response(response)
|
|
@@ -201,7 +212,7 @@ class BusyBar:
|
|
|
201
212
|
self, display_data: types.DisplayElements
|
|
202
213
|
) -> types.SuccessResponse:
|
|
203
214
|
response = self.client.post(
|
|
204
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
215
|
+
urllib.parse.urljoin(self.base_url, "/api/display/draw"),
|
|
205
216
|
json=_serialize_for_json(display_data),
|
|
206
217
|
headers={"Content-Type": "application/json"},
|
|
207
218
|
)
|
|
@@ -210,14 +221,14 @@ class BusyBar:
|
|
|
210
221
|
|
|
211
222
|
def clear_display(self) -> types.SuccessResponse:
|
|
212
223
|
response = self.client.delete(
|
|
213
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
224
|
+
urllib.parse.urljoin(self.base_url, "/api/display/draw")
|
|
214
225
|
)
|
|
215
226
|
data = self._handle_response(response)
|
|
216
227
|
return types.SuccessResponse(**data)
|
|
217
228
|
|
|
218
229
|
def get_display_brightness(self) -> types.DisplayBrightnessInfo:
|
|
219
230
|
response = self.client.get(
|
|
220
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
231
|
+
urllib.parse.urljoin(self.base_url, "/api/display/brightness")
|
|
221
232
|
)
|
|
222
233
|
data = self._handle_response(response)
|
|
223
234
|
return types.DisplayBrightnessInfo(**data)
|
|
@@ -232,7 +243,7 @@ class BusyBar:
|
|
|
232
243
|
params["back"] = back
|
|
233
244
|
|
|
234
245
|
response = self.client.post(
|
|
235
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
246
|
+
urllib.parse.urljoin(self.base_url, "/api/display/brightness"),
|
|
236
247
|
params=params,
|
|
237
248
|
)
|
|
238
249
|
data = self._handle_response(response)
|
|
@@ -240,7 +251,7 @@ class BusyBar:
|
|
|
240
251
|
|
|
241
252
|
def play_audio(self, app_id: str, path: str) -> types.SuccessResponse:
|
|
242
253
|
response = self.client.post(
|
|
243
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
254
|
+
urllib.parse.urljoin(self.base_url, "/api/audio/play"),
|
|
244
255
|
params={"app_id": app_id, "path": path},
|
|
245
256
|
)
|
|
246
257
|
data = self._handle_response(response)
|
|
@@ -248,21 +259,21 @@ class BusyBar:
|
|
|
248
259
|
|
|
249
260
|
def stop_audio(self) -> types.SuccessResponse:
|
|
250
261
|
response = self.client.delete(
|
|
251
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
262
|
+
urllib.parse.urljoin(self.base_url, "/api/audio/play")
|
|
252
263
|
)
|
|
253
264
|
data = self._handle_response(response)
|
|
254
265
|
return types.SuccessResponse(**data)
|
|
255
266
|
|
|
256
267
|
def get_audio_volume(self) -> types.AudioVolumeInfo:
|
|
257
268
|
response = self.client.get(
|
|
258
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
269
|
+
urllib.parse.urljoin(self.base_url, "/api/audio/volume")
|
|
259
270
|
)
|
|
260
271
|
data = self._handle_response(response)
|
|
261
272
|
return types.AudioVolumeInfo(**data)
|
|
262
273
|
|
|
263
274
|
def set_audio_volume(self, volume: float) -> types.SuccessResponse:
|
|
264
275
|
response = self.client.post(
|
|
265
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
276
|
+
urllib.parse.urljoin(self.base_url, "/api/audio/volume"),
|
|
266
277
|
params={"volume": volume},
|
|
267
278
|
)
|
|
268
279
|
data = self._handle_response(response)
|
|
@@ -270,7 +281,7 @@ class BusyBar:
|
|
|
270
281
|
|
|
271
282
|
def send_input_key(self, key: types.InputKey) -> types.SuccessResponse:
|
|
272
283
|
response = self.client.post(
|
|
273
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
284
|
+
urllib.parse.urljoin(self.base_url, "/api/input"),
|
|
274
285
|
params={"key": key.value},
|
|
275
286
|
)
|
|
276
287
|
data = self._handle_response(response)
|
|
@@ -278,21 +289,21 @@ class BusyBar:
|
|
|
278
289
|
|
|
279
290
|
def enable_wifi(self) -> types.SuccessResponse:
|
|
280
291
|
response = self.client.post(
|
|
281
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
292
|
+
urllib.parse.urljoin(self.base_url, "/api/wifi/enable")
|
|
282
293
|
)
|
|
283
294
|
data = self._handle_response(response)
|
|
284
295
|
return types.SuccessResponse(**data)
|
|
285
296
|
|
|
286
297
|
def disable_wifi(self) -> types.SuccessResponse:
|
|
287
298
|
response = self.client.post(
|
|
288
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
299
|
+
urllib.parse.urljoin(self.base_url, "/api/wifi/disable")
|
|
289
300
|
)
|
|
290
301
|
data = self._handle_response(response)
|
|
291
302
|
return types.SuccessResponse(**data)
|
|
292
303
|
|
|
293
304
|
def get_wifi_status(self) -> types.StatusResponse:
|
|
294
305
|
response = self.client.get(
|
|
295
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
306
|
+
urllib.parse.urljoin(self.base_url, "/api/wifi/status")
|
|
296
307
|
)
|
|
297
308
|
data = self._handle_response(response)
|
|
298
309
|
|
|
@@ -316,7 +327,7 @@ class BusyBar:
|
|
|
316
327
|
|
|
317
328
|
def connect_wifi(self, config: types.ConnectRequestConfig) -> types.SuccessResponse:
|
|
318
329
|
response = self.client.post(
|
|
319
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
330
|
+
urllib.parse.urljoin(self.base_url, "/api/wifi/connect"),
|
|
320
331
|
json=_serialize_for_json(config),
|
|
321
332
|
headers={"Content-Type": "application/json"},
|
|
322
333
|
)
|
|
@@ -325,14 +336,14 @@ class BusyBar:
|
|
|
325
336
|
|
|
326
337
|
def disconnect_wifi(self) -> types.SuccessResponse:
|
|
327
338
|
response = self.client.post(
|
|
328
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
339
|
+
urllib.parse.urljoin(self.base_url, "/api/wifi/disconnect")
|
|
329
340
|
)
|
|
330
341
|
data = self._handle_response(response)
|
|
331
342
|
return types.SuccessResponse(**data)
|
|
332
343
|
|
|
333
344
|
def scan_wifi_networks(self) -> types.NetworkResponse:
|
|
334
345
|
response = self.client.get(
|
|
335
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
346
|
+
urllib.parse.urljoin(self.base_url, "/api/wifi/networks")
|
|
336
347
|
)
|
|
337
348
|
data = self._handle_response(response)
|
|
338
349
|
|
|
@@ -353,7 +364,7 @@ class BusyBar:
|
|
|
353
364
|
|
|
354
365
|
def get_screen_frame(self, display: int) -> bytes:
|
|
355
366
|
response = self.client.get(
|
|
356
|
-
urllib.parse.urljoin(self.base_url, "/api/
|
|
367
|
+
urllib.parse.urljoin(self.base_url, "/api/screen"),
|
|
357
368
|
params={"display": display},
|
|
358
369
|
)
|
|
359
370
|
return self._handle_response(response, as_bytes=True)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: busylib
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Python library for Busy Bar API
|
|
5
|
-
Author-email:
|
|
6
|
-
Project-URL: Homepage, https://github.com/busy-app/busylib
|
|
7
|
-
Project-URL: Repository, https://github.com/busy-app/busylib
|
|
5
|
+
Author-email: flipperdevices <pypi@flipperdevices.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/busy-app/busylib-py
|
|
7
|
+
Project-URL: Repository, https://github.com/busy-app/busylib-py
|
|
8
8
|
Project-URL: Documentation, https://busylib.readthedocs.io
|
|
9
9
|
Classifier: Development Status :: 3 - Alpha
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
@@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "busylib"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "Python library for Busy Bar API"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [
|
|
11
|
-
{name = "
|
|
11
|
+
{name = "flipperdevices", email = "pypi@flipperdevices.com"}
|
|
12
12
|
]
|
|
13
13
|
classifiers = [
|
|
14
14
|
"Development Status :: 3 - Alpha",
|
|
@@ -32,8 +32,8 @@ dev = [
|
|
|
32
32
|
]
|
|
33
33
|
|
|
34
34
|
[project.urls]
|
|
35
|
-
Homepage = "https://github.com/busy-app/busylib"
|
|
36
|
-
Repository = "https://github.com/busy-app/busylib"
|
|
35
|
+
Homepage = "https://github.com/busy-app/busylib-py"
|
|
36
|
+
Repository = "https://github.com/busy-app/busylib-py"
|
|
37
37
|
Documentation = "https://busylib.readthedocs.io"
|
|
38
38
|
|
|
39
39
|
[tool.setuptools]
|
|
@@ -18,12 +18,7 @@ def client(addr):
|
|
|
18
18
|
|
|
19
19
|
@pytest.fixture
|
|
20
20
|
def sample_version_info():
|
|
21
|
-
return types.VersionInfo(
|
|
22
|
-
branch="main",
|
|
23
|
-
version="1.2.0",
|
|
24
|
-
build_date="2024-01-15",
|
|
25
|
-
commit_hash="abc123def456",
|
|
26
|
-
)
|
|
21
|
+
return types.VersionInfo(api_semver="1.2.0")
|
|
27
22
|
|
|
28
23
|
|
|
29
24
|
@pytest.fixture
|
|
@@ -87,26 +82,17 @@ def sample_wifi_config():
|
|
|
87
82
|
|
|
88
83
|
|
|
89
84
|
def test_get_version_success(requests_mock, sample_version_info, client):
|
|
90
|
-
url = "/api/
|
|
91
|
-
requests_mock.get(
|
|
92
|
-
url,
|
|
93
|
-
json={
|
|
94
|
-
"branch": sample_version_info.branch,
|
|
95
|
-
"version": sample_version_info.version,
|
|
96
|
-
"build_date": sample_version_info.build_date,
|
|
97
|
-
"commit_hash": sample_version_info.commit_hash,
|
|
98
|
-
},
|
|
99
|
-
)
|
|
85
|
+
url = "/api/version"
|
|
86
|
+
requests_mock.get(url, json={"api_semver": sample_version_info.api_semver})
|
|
100
87
|
|
|
101
88
|
result = client.get_version()
|
|
102
89
|
|
|
103
90
|
assert isinstance(result, types.VersionInfo)
|
|
104
|
-
assert result.
|
|
105
|
-
assert result.branch == "main"
|
|
91
|
+
assert result.api_semver == "1.2.0"
|
|
106
92
|
|
|
107
93
|
|
|
108
94
|
def test_get_version_error(requests_mock, client):
|
|
109
|
-
url = "/api/
|
|
95
|
+
url = "/api/version"
|
|
110
96
|
requests_mock.get(
|
|
111
97
|
url, json={"error": "Internal server error", "code": 500}, status_code=500
|
|
112
98
|
)
|
|
@@ -119,7 +105,7 @@ def test_get_version_error(requests_mock, client):
|
|
|
119
105
|
|
|
120
106
|
|
|
121
107
|
def test_update_firmware_success(requests_mock, client):
|
|
122
|
-
url = "/api/
|
|
108
|
+
url = "/api/update"
|
|
123
109
|
requests_mock.post(url, json={"result": "OK"})
|
|
124
110
|
|
|
125
111
|
resp = client.update_firmware(b"fake-firmware-data", name="firmware")
|
|
@@ -129,7 +115,7 @@ def test_update_firmware_success(requests_mock, client):
|
|
|
129
115
|
|
|
130
116
|
|
|
131
117
|
def test_get_status_success(requests_mock, sample_status, client):
|
|
132
|
-
url = "/api/
|
|
118
|
+
url = "/api/status"
|
|
133
119
|
requests_mock.get(
|
|
134
120
|
url,
|
|
135
121
|
json={
|
|
@@ -155,7 +141,7 @@ def test_get_status_success(requests_mock, sample_status, client):
|
|
|
155
141
|
|
|
156
142
|
|
|
157
143
|
def test_write_storage_file_success(requests_mock, client):
|
|
158
|
-
url = "/api/
|
|
144
|
+
url = "/api/storage/write"
|
|
159
145
|
requests_mock.post(url, json={"result": "OK"})
|
|
160
146
|
|
|
161
147
|
resp = client.write_storage_file("/file.txt", b"test")
|
|
@@ -165,7 +151,7 @@ def test_write_storage_file_success(requests_mock, client):
|
|
|
165
151
|
|
|
166
152
|
|
|
167
153
|
def test_read_storage_file_success(requests_mock, client):
|
|
168
|
-
url = "/api/
|
|
154
|
+
url = "/api/storage/read"
|
|
169
155
|
content = b"some-binary-contents"
|
|
170
156
|
requests_mock.get(url, content=content)
|
|
171
157
|
|
|
@@ -175,7 +161,7 @@ def test_read_storage_file_success(requests_mock, client):
|
|
|
175
161
|
|
|
176
162
|
|
|
177
163
|
def test_list_storage_files_success(requests_mock, sample_storage_list, client):
|
|
178
|
-
url = "/api/
|
|
164
|
+
url = "/api/storage/list"
|
|
179
165
|
requests_mock.get(url, json=dataclasses.asdict(sample_storage_list))
|
|
180
166
|
|
|
181
167
|
resp = client.list_storage_files("/ext")
|
|
@@ -185,7 +171,7 @@ def test_list_storage_files_success(requests_mock, sample_storage_list, client):
|
|
|
185
171
|
|
|
186
172
|
|
|
187
173
|
def test_remove_storage_file_success(requests_mock, client):
|
|
188
|
-
url = "/api/
|
|
174
|
+
url = "/api/storage/remove"
|
|
189
175
|
requests_mock.delete(url, json={"result": "OK"})
|
|
190
176
|
|
|
191
177
|
resp = client.remove_storage_file("/file.txt")
|
|
@@ -194,7 +180,7 @@ def test_remove_storage_file_success(requests_mock, client):
|
|
|
194
180
|
|
|
195
181
|
|
|
196
182
|
def test_create_storage_directory_success(requests_mock, client):
|
|
197
|
-
url = "/api/
|
|
183
|
+
url = "/api/storage/mkdir"
|
|
198
184
|
requests_mock.post(url, json={"result": "OK"})
|
|
199
185
|
|
|
200
186
|
resp = client.create_storage_directory("/new_dir")
|
|
@@ -203,7 +189,7 @@ def test_create_storage_directory_success(requests_mock, client):
|
|
|
203
189
|
|
|
204
190
|
|
|
205
191
|
def test_draw_on_display_success(requests_mock, sample_display_elements, client):
|
|
206
|
-
url = "/api/
|
|
192
|
+
url = "/api/display/draw"
|
|
207
193
|
requests_mock.post(url, json={"result": "OK"})
|
|
208
194
|
|
|
209
195
|
resp = client.draw_on_display(sample_display_elements)
|
|
@@ -212,7 +198,7 @@ def test_draw_on_display_success(requests_mock, sample_display_elements, client)
|
|
|
212
198
|
|
|
213
199
|
|
|
214
200
|
def test_clear_display_success(requests_mock, client):
|
|
215
|
-
url = "/api/
|
|
201
|
+
url = "/api/display/draw"
|
|
216
202
|
requests_mock.delete(url, json={"result": "OK"})
|
|
217
203
|
|
|
218
204
|
resp = client.clear_display()
|
|
@@ -221,7 +207,7 @@ def test_clear_display_success(requests_mock, client):
|
|
|
221
207
|
|
|
222
208
|
|
|
223
209
|
def test_get_display_brightness_success(requests_mock, client):
|
|
224
|
-
url = "/api/
|
|
210
|
+
url = "/api/display/brightness"
|
|
225
211
|
requests_mock.get(url, json={"front": "auto", "back": "50"})
|
|
226
212
|
|
|
227
213
|
resp = client.get_display_brightness()
|
|
@@ -232,7 +218,7 @@ def test_get_display_brightness_success(requests_mock, client):
|
|
|
232
218
|
|
|
233
219
|
|
|
234
220
|
def test_set_display_brightness_success(requests_mock, client):
|
|
235
|
-
url = "/api/
|
|
221
|
+
url = "/api/display/brightness"
|
|
236
222
|
requests_mock.post(url, json={"result": "OK"})
|
|
237
223
|
|
|
238
224
|
resp = client.set_display_brightness(front="100", back="auto")
|
|
@@ -241,7 +227,7 @@ def test_set_display_brightness_success(requests_mock, client):
|
|
|
241
227
|
|
|
242
228
|
|
|
243
229
|
def test_play_audio_success(requests_mock, client):
|
|
244
|
-
url = "/api/
|
|
230
|
+
url = "/api/audio/play"
|
|
245
231
|
requests_mock.post(url, json={"result": "OK"})
|
|
246
232
|
|
|
247
233
|
resp = client.play_audio("test_app", "notify.snd")
|
|
@@ -249,7 +235,7 @@ def test_play_audio_success(requests_mock, client):
|
|
|
249
235
|
|
|
250
236
|
|
|
251
237
|
def test_stop_audio_success(requests_mock, client):
|
|
252
|
-
url = "/api/
|
|
238
|
+
url = "/api/audio/play"
|
|
253
239
|
requests_mock.delete(url, json={"result": "OK"})
|
|
254
240
|
|
|
255
241
|
resp = client.stop_audio()
|
|
@@ -257,7 +243,7 @@ def test_stop_audio_success(requests_mock, client):
|
|
|
257
243
|
|
|
258
244
|
|
|
259
245
|
def test_get_audio_volume_success(requests_mock, client):
|
|
260
|
-
url = "/api/
|
|
246
|
+
url = "/api/audio/volume"
|
|
261
247
|
requests_mock.get(url, json={"volume": 73.3})
|
|
262
248
|
|
|
263
249
|
resp = client.get_audio_volume()
|
|
@@ -267,7 +253,7 @@ def test_get_audio_volume_success(requests_mock, client):
|
|
|
267
253
|
|
|
268
254
|
|
|
269
255
|
def test_set_audio_volume_success(requests_mock, client):
|
|
270
|
-
url = "/api/
|
|
256
|
+
url = "/api/audio/volume"
|
|
271
257
|
requests_mock.post(url, json={"result": "OK"})
|
|
272
258
|
|
|
273
259
|
resp = client.set_audio_volume(12.0)
|
|
@@ -276,7 +262,7 @@ def test_set_audio_volume_success(requests_mock, client):
|
|
|
276
262
|
|
|
277
263
|
|
|
278
264
|
def test_enable_wifi_success(requests_mock, client):
|
|
279
|
-
url = "/api/
|
|
265
|
+
url = "/api/wifi/enable"
|
|
280
266
|
requests_mock.post(url, json={"result": "OK"})
|
|
281
267
|
|
|
282
268
|
resp = client.enable_wifi()
|
|
@@ -285,7 +271,7 @@ def test_enable_wifi_success(requests_mock, client):
|
|
|
285
271
|
|
|
286
272
|
|
|
287
273
|
def test_disable_wifi_success(requests_mock, client):
|
|
288
|
-
url = "/api/
|
|
274
|
+
url = "/api/wifi/disable"
|
|
289
275
|
requests_mock.post(url, json={"result": "OK"})
|
|
290
276
|
|
|
291
277
|
resp = client.disable_wifi()
|
|
@@ -294,7 +280,7 @@ def test_disable_wifi_success(requests_mock, client):
|
|
|
294
280
|
|
|
295
281
|
|
|
296
282
|
def test_get_wifi_status_success(requests_mock, client):
|
|
297
|
-
url = "/api/
|
|
283
|
+
url = "/api/wifi/status"
|
|
298
284
|
requests_mock.get(
|
|
299
285
|
url,
|
|
300
286
|
json={
|
|
@@ -317,7 +303,7 @@ def test_get_wifi_status_success(requests_mock, client):
|
|
|
317
303
|
|
|
318
304
|
|
|
319
305
|
def test_connect_wifi_success(requests_mock, sample_wifi_config, client):
|
|
320
|
-
url = "/api/
|
|
306
|
+
url = "/api/wifi/connect"
|
|
321
307
|
requests_mock.post(url, json={"result": "OK"})
|
|
322
308
|
|
|
323
309
|
resp = client.connect_wifi(sample_wifi_config)
|
|
@@ -326,7 +312,7 @@ def test_connect_wifi_success(requests_mock, sample_wifi_config, client):
|
|
|
326
312
|
|
|
327
313
|
|
|
328
314
|
def test_disconnect_wifi_success(requests_mock, client):
|
|
329
|
-
url = "/api/
|
|
315
|
+
url = "/api/wifi/disconnect"
|
|
330
316
|
requests_mock.post(url, json={"result": "OK"})
|
|
331
317
|
|
|
332
318
|
resp = client.disconnect_wifi()
|
|
@@ -335,7 +321,7 @@ def test_disconnect_wifi_success(requests_mock, client):
|
|
|
335
321
|
|
|
336
322
|
|
|
337
323
|
def test_scan_wifi_networks_success(requests_mock, client):
|
|
338
|
-
url = "/api/
|
|
324
|
+
url = "/api/wifi/networks"
|
|
339
325
|
requests_mock.get(
|
|
340
326
|
url,
|
|
341
327
|
json={
|
|
@@ -359,7 +345,7 @@ def test_scan_wifi_networks_success(requests_mock, client):
|
|
|
359
345
|
[types.InputKey.UP, types.InputKey.DOWN, types.InputKey.OK, types.InputKey.BACK],
|
|
360
346
|
)
|
|
361
347
|
def test_send_input_key_success(requests_mock, key, client):
|
|
362
|
-
url = "/api/
|
|
348
|
+
url = "/api/input"
|
|
363
349
|
requests_mock.post(url, json={"result": "OK"})
|
|
364
350
|
|
|
365
351
|
resp = client.send_input_key(key)
|
|
@@ -368,7 +354,7 @@ def test_send_input_key_success(requests_mock, key, client):
|
|
|
368
354
|
|
|
369
355
|
|
|
370
356
|
def test_http_404_error(requests_mock, client):
|
|
371
|
-
url = "/api/
|
|
357
|
+
url = "/api/version"
|
|
372
358
|
requests_mock.get(url, json={"error": "Not found", "code": 404}, status_code=404)
|
|
373
359
|
|
|
374
360
|
with pytest.raises(exceptions.BusyBarAPIError) as exc:
|
|
@@ -378,7 +364,7 @@ def test_http_404_error(requests_mock, client):
|
|
|
378
364
|
|
|
379
365
|
|
|
380
366
|
def test_http_500_error_without_json(requests_mock, client):
|
|
381
|
-
url = "/api/
|
|
367
|
+
url = "/api/version"
|
|
382
368
|
requests_mock.get(url, text="Internal Server Error", status_code=500)
|
|
383
369
|
|
|
384
370
|
with pytest.raises(exceptions.BusyBarAPIError) as exc:
|
|
@@ -400,21 +386,13 @@ def test_requests_connection_error(monkeypatch, client):
|
|
|
400
386
|
|
|
401
387
|
def test_integration_workflow(requests_mock, client):
|
|
402
388
|
base = "http://test-device.local"
|
|
403
|
-
requests_mock.get(
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
"version": "1.0.0",
|
|
408
|
-
"build_date": "2024-01-01",
|
|
409
|
-
"commit_hash": "abc123",
|
|
410
|
-
},
|
|
411
|
-
)
|
|
412
|
-
requests_mock.post(f"{base}/api/v0/assets/upload", json={"result": "OK"})
|
|
413
|
-
requests_mock.post(f"{base}/api/v0/display/draw", json={"result": "OK"})
|
|
414
|
-
requests_mock.post(f"{base}/api/v0/audio/play", json={"result": "OK"})
|
|
389
|
+
requests_mock.get(f"{base}/api/version", json={"api_semver": "1.0.0"})
|
|
390
|
+
requests_mock.post(f"{base}/api/assets/upload", json={"result": "OK"})
|
|
391
|
+
requests_mock.post(f"{base}/api/display/draw", json={"result": "OK"})
|
|
392
|
+
requests_mock.post(f"{base}/api/audio/play", json={"result": "OK"})
|
|
415
393
|
|
|
416
394
|
version = client.get_version()
|
|
417
|
-
assert version.
|
|
395
|
+
assert version.api_semver == "1.0.0"
|
|
418
396
|
|
|
419
397
|
resp_asset = client.upload_asset("test_app", "logo.png", b"img")
|
|
420
398
|
assert resp_asset.result == "OK"
|
|
@@ -437,3 +415,15 @@ def test_integration_workflow(requests_mock, client):
|
|
|
437
415
|
|
|
438
416
|
resp_audio = client.play_audio("test_app", "sound.snd")
|
|
439
417
|
assert resp_audio.result == "OK"
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def test_client_with_token(requests_mock):
|
|
421
|
+
requests_mock.get(
|
|
422
|
+
"https://proxy.dev.busy.app/api/version",
|
|
423
|
+
request_headers={"Authorization": "Bearer test-token"},
|
|
424
|
+
json={"api_semver": "1.0.0"},
|
|
425
|
+
)
|
|
426
|
+
bb = BusyBar(token="test-token")
|
|
427
|
+
|
|
428
|
+
version = bb.get_version()
|
|
429
|
+
assert version.api_semver == "1.0.0"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from busylib import BusyBar
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_busybar_init_local():
|
|
7
|
+
bb = BusyBar()
|
|
8
|
+
|
|
9
|
+
assert bb.base_url == "http://10.0.4.20"
|
|
10
|
+
assert "Authorization" not in bb.client.headers
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.mark.parametrize("addr", ["192.168.6.40", "http://192.168.6.40"])
|
|
14
|
+
def test_busybar_init_addr_http(addr: str):
|
|
15
|
+
bb = BusyBar(addr)
|
|
16
|
+
|
|
17
|
+
assert bb.base_url == "http://192.168.6.40"
|
|
18
|
+
assert "Authorization" not in bb.client.headers
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_busybar_init_addr_https():
|
|
22
|
+
bb = BusyBar("https://secure.busy.app")
|
|
23
|
+
|
|
24
|
+
assert bb.base_url == "https://secure.busy.app"
|
|
25
|
+
assert "Authorization" not in bb.client.headers
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_busybar_init_cloud_token():
|
|
29
|
+
bb = BusyBar(token="some-token")
|
|
30
|
+
|
|
31
|
+
assert bb.base_url == "https://proxy.dev.busy.app"
|
|
32
|
+
assert bb.client.headers["Authorization"] == "Bearer some-token"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_busybar_init_addr_token():
|
|
36
|
+
bb = BusyBar("https://proxy.example.net", token="another-token")
|
|
37
|
+
|
|
38
|
+
assert bb.base_url == "https://proxy.example.net"
|
|
39
|
+
assert bb.client.headers["Authorization"] == "Bearer another-token"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|