py-synologydsm-api 2.4.5__py3-none-any.whl
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.
- py_synologydsm_api-2.4.5.dist-info/LICENSE.txt +8 -0
- py_synologydsm_api-2.4.5.dist-info/METADATA +426 -0
- py_synologydsm_api-2.4.5.dist-info/RECORD +32 -0
- py_synologydsm_api-2.4.5.dist-info/WHEEL +5 -0
- py_synologydsm_api-2.4.5.dist-info/entry_points.txt +2 -0
- py_synologydsm_api-2.4.5.dist-info/top_level.txt +1 -0
- synology_dsm/__init__.py +5 -0
- synology_dsm/api/__init__.py +20 -0
- synology_dsm/api/core/__init__.py +1 -0
- synology_dsm/api/core/external_usb.py +270 -0
- synology_dsm/api/core/security.py +87 -0
- synology_dsm/api/core/share.py +92 -0
- synology_dsm/api/core/system.py +142 -0
- synology_dsm/api/core/upgrade.py +55 -0
- synology_dsm/api/core/utilization.py +199 -0
- synology_dsm/api/download_station/__init__.py +125 -0
- synology_dsm/api/download_station/task.py +76 -0
- synology_dsm/api/dsm/__init__.py +1 -0
- synology_dsm/api/dsm/information.py +73 -0
- synology_dsm/api/dsm/network.py +87 -0
- synology_dsm/api/photos/__init__.py +166 -0
- synology_dsm/api/photos/model.py +25 -0
- synology_dsm/api/storage/__init__.py +1 -0
- synology_dsm/api/storage/storage.py +273 -0
- synology_dsm/api/surveillance_station/__init__.py +276 -0
- synology_dsm/api/surveillance_station/camera.py +136 -0
- synology_dsm/api/surveillance_station/const.py +19 -0
- synology_dsm/const.py +171 -0
- synology_dsm/exceptions.py +147 -0
- synology_dsm/helpers.py +50 -0
- synology_dsm/py.typed +0 -0
- synology_dsm/synology_dsm.py +590 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
Copyright (c) 2020 mib1185
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
5
|
+
|
|
6
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
7
|
+
|
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: py-synologydsm-api
|
|
3
|
+
Version: 2.4.5
|
|
4
|
+
Summary: Python API for communication with Synology DSM
|
|
5
|
+
Home-page: https://github.com/mib1185/py-synologydsm-api#readme
|
|
6
|
+
Author: Michael Brussk (mib1185), Quentin POLLET (Quentame), FG van Zeelst (ProtoThis)
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Changelog, https://github.com/mib1185/py-synologydsm-api/releases
|
|
9
|
+
Project-URL: Repository, https://github.com/mib1185/py-synologydsm-api
|
|
10
|
+
Project-URL: Documentation, https://github.com/mib1185/py-synologydsm-api#readme
|
|
11
|
+
Keywords: synology-dsm,synology
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
20
|
+
Requires-Python: >=3.8.0
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE.txt
|
|
23
|
+
Requires-Dist: aiohttp
|
|
24
|
+
|
|
25
|
+
# Asynchronous Python API for Synology DSM
|
|
26
|
+
|
|
27
|
+
[](https://github.com/mib1185/py-synologydsm-api/actions?query=workflow%3ATests+branch%3Amaster)
|
|
28
|
+
[](https://pypi.org/project/py-synologydsm-api)
|
|
29
|
+
[](https://pypi.org/project/py-synologydsm-api)
|
|
30
|
+
[](https://pypi.org/project/py-synologydsm-api)
|
|
31
|
+
[](https://github.com/psf/black)
|
|
32
|
+
|
|
33
|
+
# Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
[sudo] pip install py-synologydsm-api
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
# Usage
|
|
40
|
+
|
|
41
|
+
You can import the module as `synology_dsm`.
|
|
42
|
+
|
|
43
|
+
## Constructor
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
SynologyDSM(
|
|
47
|
+
session,
|
|
48
|
+
dsm_ip,
|
|
49
|
+
dsm_port,
|
|
50
|
+
username,
|
|
51
|
+
password,
|
|
52
|
+
use_https=False,
|
|
53
|
+
timeout=10,
|
|
54
|
+
device_token=None,
|
|
55
|
+
debugmode=False,
|
|
56
|
+
)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For `session` a valid `aiohttp.ClientSession` needs to be provided. If ssl verification should be truned off, configure the session accordingly (eq. `aiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False)`)
|
|
60
|
+
|
|
61
|
+
`device_token` should be added when using a two-step authentication account, otherwise DSM will ask to login with a One Time Password (OTP) and requests will fail (see the login section for more details).
|
|
62
|
+
|
|
63
|
+
Default `timeout` is 10 seconds. `SynologyDSM` also takes a `aiohttp.ClientTimeout` as `timeout`.
|
|
64
|
+
|
|
65
|
+
## Login
|
|
66
|
+
|
|
67
|
+
Use the `login()` function to authenticate first, otherwise a `SynologyDSMNotLoggedInException` is raised.
|
|
68
|
+
|
|
69
|
+
It will return a boolean if it successed or faild to authenticate to DSM.
|
|
70
|
+
|
|
71
|
+
If your account need a two-step authentication (2SA), `login()` will raise `SynologyDSMLogin2SARequiredException`.
|
|
72
|
+
Call the function again with a One Time Password (OTP) as parameter, like `login("123456")` (better to be a string to handle first zero).
|
|
73
|
+
Store the `device_token` property so that you do not need to reconnect with password the next time you open a new `SynologyDSM` session.
|
|
74
|
+
|
|
75
|
+
## Code example
|
|
76
|
+
|
|
77
|
+
Every API has an `update()` function that is needed to get the first data, then the data is cached and updated at the next `update()` call.
|
|
78
|
+
|
|
79
|
+
The `SynologyDSM` class can also `update()` all APIs at once.
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import asyncio
|
|
83
|
+
import aiohttp
|
|
84
|
+
from synology_dsm import SynologyDSM
|
|
85
|
+
|
|
86
|
+
async def main():
|
|
87
|
+
print("Creating Valid API")
|
|
88
|
+
async with aiohttp.ClientSession(
|
|
89
|
+
connector=aiohttp.TCPConnector(verify_ssl=False)
|
|
90
|
+
) as session:
|
|
91
|
+
await do(session)
|
|
92
|
+
|
|
93
|
+
async def do(session: aiohttp.ClientSession):
|
|
94
|
+
api = SynologyDSM(session, "<IP/DNS>", "<port>", "<username>", "<password>")
|
|
95
|
+
await api.login()
|
|
96
|
+
|
|
97
|
+
print("=== Information ===")
|
|
98
|
+
await api.information.update()
|
|
99
|
+
print("Model: " + str(api.information.model))
|
|
100
|
+
print("RAM: " + str(api.information.ram) + " MB")
|
|
101
|
+
print("Serial number: " + str(api.information.serial))
|
|
102
|
+
print("Temperature: " + str(api.information.temperature) + " °C")
|
|
103
|
+
print("Temp. warning: " + str(api.information.temperature_warn))
|
|
104
|
+
print("Uptime: " + str(api.information.uptime))
|
|
105
|
+
print("Full DSM version:" + str(api.information.version_string))
|
|
106
|
+
print("--")
|
|
107
|
+
|
|
108
|
+
print("=== Utilisation ===")
|
|
109
|
+
await api.utilisation.update()
|
|
110
|
+
print("CPU Load: " + str(api.utilisation.cpu_total_load) + " %")
|
|
111
|
+
print("Memory Use: " + str(api.utilisation.memory_real_usage) + " %")
|
|
112
|
+
print("Net Up: " + str(api.utilisation.network_up()))
|
|
113
|
+
print("Net Down: " + str(api.utilisation.network_down()))
|
|
114
|
+
print("--")
|
|
115
|
+
|
|
116
|
+
print("=== Storage ===")
|
|
117
|
+
await api.storage.update()
|
|
118
|
+
for volume_id in api.storage.volumes_ids:
|
|
119
|
+
print("ID: " + str(volume_id))
|
|
120
|
+
print("Status: " + str(api.storage.volume_status(volume_id)))
|
|
121
|
+
print("% Used: " + str(api.storage.volume_percentage_used(volume_id)) + " %")
|
|
122
|
+
print("--")
|
|
123
|
+
|
|
124
|
+
for disk_id in api.storage.disks_ids:
|
|
125
|
+
print("ID: " + str(disk_id))
|
|
126
|
+
print("Name: " + str(api.storage.disk_name(disk_id)))
|
|
127
|
+
print("S-Status: " + str(api.storage.disk_smart_status(disk_id)))
|
|
128
|
+
print("Status: " + str(api.storage.disk_status(disk_id)))
|
|
129
|
+
print("Temp: " + str(api.storage.disk_temp(disk_id)))
|
|
130
|
+
print("--")
|
|
131
|
+
|
|
132
|
+
print("=== Shared Folders ===")
|
|
133
|
+
await api.share.update()
|
|
134
|
+
for share_uuid in api.share.shares_uuids:
|
|
135
|
+
print("Share name: " + str(api.share.share_name(share_uuid)))
|
|
136
|
+
print("Share path: " + str(api.share.share_path(share_uuid)))
|
|
137
|
+
print("Space used: " + str(api.share.share_size(share_uuid, human_readable=True)))
|
|
138
|
+
print("Recycle Bin Enabled: " + str(api.share.share_recycle_bin(share_uuid)))
|
|
139
|
+
print("--")
|
|
140
|
+
|
|
141
|
+
if __name__ == "__main__":
|
|
142
|
+
asyncio.run(main())
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Download Station usage
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
import asyncio
|
|
149
|
+
import aiohttp
|
|
150
|
+
from synology_dsm import SynologyDSM
|
|
151
|
+
|
|
152
|
+
async def main():
|
|
153
|
+
print("Creating Valid API")
|
|
154
|
+
async with aiohttp.ClientSession(
|
|
155
|
+
connector=aiohttp.TCPConnector(verify_ssl=False)
|
|
156
|
+
) as session:
|
|
157
|
+
await do(session)
|
|
158
|
+
|
|
159
|
+
async def do(session: aiohttp.ClientSession):
|
|
160
|
+
api = SynologyDSM(session, "<IP/DNS>", "<port>", "<username>", "<password>")
|
|
161
|
+
await api.login()
|
|
162
|
+
|
|
163
|
+
if "SYNO.DownloadStation.Info" in api.apis:
|
|
164
|
+
|
|
165
|
+
await api.download_station.get_info()
|
|
166
|
+
await api.download_station.get_config()
|
|
167
|
+
|
|
168
|
+
# The download list will be updated after each of the following functions:
|
|
169
|
+
# You should have the right on the (default) directory that the download will be saved, or you will get a 403 or 406 error
|
|
170
|
+
await api.download_station.create("http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
|
|
171
|
+
await api.download_station.pause("dbid_1")
|
|
172
|
+
# Like the other function, you can eather pass a str or a list
|
|
173
|
+
await api.download_station.resume(["dbid_1", "dbid_2"])
|
|
174
|
+
await api.download_station.delete("dbid_3")
|
|
175
|
+
|
|
176
|
+
# Manual update
|
|
177
|
+
await api.download_station.update()
|
|
178
|
+
|
|
179
|
+
if __name__ == "__main__":
|
|
180
|
+
asyncio.run(main())
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## External USB storage usage
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
import asyncio
|
|
187
|
+
import aiohttp
|
|
188
|
+
from synology_dsm import SynologyDSM
|
|
189
|
+
|
|
190
|
+
async def main():
|
|
191
|
+
print("Creating Valid API")
|
|
192
|
+
async with aiohttp.ClientSession(
|
|
193
|
+
connector=aiohttp.TCPConnector(verify_ssl=False)
|
|
194
|
+
) as session:
|
|
195
|
+
await do(session)
|
|
196
|
+
|
|
197
|
+
async def do(session: aiohttp.ClientSession):
|
|
198
|
+
api = SynologyDSM(session, "<IP/DNS>", "<port>", "<username>", "<password>")
|
|
199
|
+
await api.login()
|
|
200
|
+
|
|
201
|
+
await api.external_usb.update()
|
|
202
|
+
for device in api.external_usb.get_devices.values():
|
|
203
|
+
print("Name: " + str(device.device_name))
|
|
204
|
+
print("Size: " + str(device.device_size_total(human_readable=True))
|
|
205
|
+
print("Size in mb: " + str(device.device_size_total())
|
|
206
|
+
print("Partitions size total: " + str(device.partitions_all_size_total(human_readable=True)))
|
|
207
|
+
print("Partitions size used: " + str(device.partitions_all_size_used(human_readable=True)))
|
|
208
|
+
print("Partitions % Used: " + str(device.partitions_all_percentage_used ) + " %")
|
|
209
|
+
print(" === Partitions ===")
|
|
210
|
+
for part in device.device_partitions.values():
|
|
211
|
+
print(" Share name: " + str(part.share_name))
|
|
212
|
+
print(" Filesystem: " + str(part.filesystem))
|
|
213
|
+
print(" Size: " + str(part.partition_size_total(human_readable=True)))
|
|
214
|
+
print(" Used: " + str(part.partition_size_used(human_readable=True)))
|
|
215
|
+
print(" % Used: " + str(part.partition_percentage_used) + " %")
|
|
216
|
+
|
|
217
|
+
if __name__ == "__main__":
|
|
218
|
+
asyncio.run(main())
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Photos usage
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
import asyncio
|
|
225
|
+
import aiohttp
|
|
226
|
+
from synology_dsm import SynologyDSM
|
|
227
|
+
|
|
228
|
+
async def main():
|
|
229
|
+
print("Creating Valid API")
|
|
230
|
+
async with aiohttp.ClientSession(
|
|
231
|
+
connector=aiohttp.TCPConnector(verify_ssl=False)
|
|
232
|
+
) as session:
|
|
233
|
+
await do(session)
|
|
234
|
+
|
|
235
|
+
async def do(session: aiohttp.ClientSession):
|
|
236
|
+
api = SynologyDSM(session, "<IP/DNS>", "<port>", "<username>", "<password>")
|
|
237
|
+
await api.login()
|
|
238
|
+
|
|
239
|
+
albums = await api.photos.get_albums()
|
|
240
|
+
|
|
241
|
+
# download each item of each album
|
|
242
|
+
for album in albums:
|
|
243
|
+
print(f"'{album.name}' has {album.item_count} items")
|
|
244
|
+
|
|
245
|
+
items = await api.photos.get_items_from_album(album)
|
|
246
|
+
for item in items:
|
|
247
|
+
print(f"{item.file_name}")
|
|
248
|
+
with open(item.file_name, "wb") as fh:
|
|
249
|
+
fh.write(await api.photos.download_item(item))
|
|
250
|
+
|
|
251
|
+
# search for items and download them
|
|
252
|
+
items = await api.photos.get_items_from_search("pinky and the brain")
|
|
253
|
+
for item in items:
|
|
254
|
+
with open(item.file_name, "wb") as fh:
|
|
255
|
+
fh.write(await api.photos.download_item(item))
|
|
256
|
+
|
|
257
|
+
if __name__ == "__main__":
|
|
258
|
+
asyncio.run(main())
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Surveillance Station usage
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
import asyncio
|
|
265
|
+
import aiohttp
|
|
266
|
+
from synology_dsm import SynologyDSM
|
|
267
|
+
|
|
268
|
+
async def main():
|
|
269
|
+
print("Creating Valid API")
|
|
270
|
+
async with aiohttp.ClientSession(
|
|
271
|
+
connector=aiohttp.TCPConnector(verify_ssl=False)
|
|
272
|
+
) as session:
|
|
273
|
+
await do(session)
|
|
274
|
+
|
|
275
|
+
async def do(session: aiohttp.ClientSession):
|
|
276
|
+
api = SynologyDSM(session, "<IP/DNS>", "<port>", "<username>", "<password>")
|
|
277
|
+
await api.login()
|
|
278
|
+
|
|
279
|
+
surveillance = api.surveillance_station
|
|
280
|
+
await surveillance.update() # First update is required
|
|
281
|
+
|
|
282
|
+
# Returns a list of cached cameras available
|
|
283
|
+
cameras = surveillance.get_all_cameras()
|
|
284
|
+
|
|
285
|
+
# Assuming there's at least one camera, get the first camera_id
|
|
286
|
+
camera_id = cameras[0].camera_id
|
|
287
|
+
|
|
288
|
+
# Returns cached camera object by camera_id
|
|
289
|
+
camera = surveillance.get_camera(camera_id)
|
|
290
|
+
|
|
291
|
+
# Returns cached motion detection enabled
|
|
292
|
+
motion_setting = camera.is_motion_detection_enabled
|
|
293
|
+
|
|
294
|
+
# Return bytes of camera image
|
|
295
|
+
await surveillance.get_camera_image(camera_id)
|
|
296
|
+
|
|
297
|
+
# Updates all cameras/motion settings and cahce them
|
|
298
|
+
await surveillance.update()
|
|
299
|
+
|
|
300
|
+
# Gets Home Mode status
|
|
301
|
+
home_mode_status = await surveillance.get_home_mode_status()
|
|
302
|
+
|
|
303
|
+
# Sets home mode - true is on, false is off
|
|
304
|
+
await surveillance.set_home_mode(True)
|
|
305
|
+
|
|
306
|
+
if __name__ == "__main__":
|
|
307
|
+
asyncio.run(main())
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## System usage
|
|
311
|
+
|
|
312
|
+
```python
|
|
313
|
+
import asyncio
|
|
314
|
+
import aiohttp
|
|
315
|
+
from synology_dsm import SynologyDSM
|
|
316
|
+
|
|
317
|
+
async def main():
|
|
318
|
+
print("Creating Valid API")
|
|
319
|
+
async with aiohttp.ClientSession(
|
|
320
|
+
connector=aiohttp.TCPConnector(verify_ssl=False)
|
|
321
|
+
) as session:
|
|
322
|
+
await do(session)
|
|
323
|
+
|
|
324
|
+
async def do(session: aiohttp.ClientSession):
|
|
325
|
+
api = SynologyDSM(session, "<IP/DNS>", "<port>", "<username>", "<password>")
|
|
326
|
+
await api.login()
|
|
327
|
+
|
|
328
|
+
system = api.system
|
|
329
|
+
|
|
330
|
+
# Reboot NAS
|
|
331
|
+
await system.reboot()
|
|
332
|
+
|
|
333
|
+
# Shutdown NAS
|
|
334
|
+
await system.shutdown()
|
|
335
|
+
|
|
336
|
+
# Manual update system information
|
|
337
|
+
await system.update()
|
|
338
|
+
|
|
339
|
+
# Get CPU information
|
|
340
|
+
system.cpu_clock_speed
|
|
341
|
+
system.cpu_cores
|
|
342
|
+
system.cpu_family
|
|
343
|
+
system.cpu_series
|
|
344
|
+
|
|
345
|
+
# Get NTP settings
|
|
346
|
+
system.enabled_ntp
|
|
347
|
+
system.ntp_server
|
|
348
|
+
|
|
349
|
+
# Get system information
|
|
350
|
+
system.firmware_ver
|
|
351
|
+
system.model
|
|
352
|
+
system.ram_size
|
|
353
|
+
system.serial
|
|
354
|
+
system.sys_temp
|
|
355
|
+
system.time
|
|
356
|
+
system.time_zone
|
|
357
|
+
system.time_zone_desc
|
|
358
|
+
system.up_time
|
|
359
|
+
|
|
360
|
+
# Get list of all connected USB devices
|
|
361
|
+
system.usb_dev
|
|
362
|
+
|
|
363
|
+
if __name__ == "__main__":
|
|
364
|
+
asyncio.run(main())
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Upgrade usage
|
|
368
|
+
|
|
369
|
+
```python
|
|
370
|
+
import asyncio
|
|
371
|
+
import aiohttp
|
|
372
|
+
from synology_dsm import SynologyDSM
|
|
373
|
+
|
|
374
|
+
async def main():
|
|
375
|
+
print("Creating Valid API")
|
|
376
|
+
async with aiohttp.ClientSession(
|
|
377
|
+
connector=aiohttp.TCPConnector(verify_ssl=False)
|
|
378
|
+
) as session:
|
|
379
|
+
await do(session)
|
|
380
|
+
|
|
381
|
+
async def do(session: aiohttp.ClientSession):
|
|
382
|
+
api = SynologyDSM(session, "<IP/DNS>", "<port>", "<username>", "<password>")
|
|
383
|
+
await api.login()
|
|
384
|
+
upgrade = api.upgrade
|
|
385
|
+
|
|
386
|
+
# Manual update upgrade information
|
|
387
|
+
await upgrade.update()
|
|
388
|
+
|
|
389
|
+
# check if DSM update is available
|
|
390
|
+
if upgrade.update_available:
|
|
391
|
+
do something ...
|
|
392
|
+
|
|
393
|
+
# get available version string (return None if no update available)
|
|
394
|
+
upgrade.available_version
|
|
395
|
+
|
|
396
|
+
# get need of reboot (return None if no update available)
|
|
397
|
+
upgrade.reboot_needed
|
|
398
|
+
|
|
399
|
+
# get need of service restarts (return None if no update available)
|
|
400
|
+
upgrade.service_restarts
|
|
401
|
+
|
|
402
|
+
if __name__ == "__main__":
|
|
403
|
+
asyncio.run(main())
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
# Credits / Special Thanks
|
|
407
|
+
|
|
408
|
+
- [@florianeinfalt](https://github.com/florianeinfalt)
|
|
409
|
+
- [@tchellomello](https://github.com/tchellomello)
|
|
410
|
+
- [@Quentame](https://github.com/Quentame) (Multiple API addition & tests)
|
|
411
|
+
- [@aaska](https://github.com/aaska) (DSM 5 tests)
|
|
412
|
+
- [@chemelli74](https://github.com/chemelli74) (2SA tests)
|
|
413
|
+
- [@snjoetw](https://github.com/snjoetw) (Surveillance Station library)
|
|
414
|
+
- [@shenxn](https://github.com/shenxn) (Surveillance Station tests)
|
|
415
|
+
- [@Gestas](https://github.com/Gestas) (Shared Folders)
|
|
416
|
+
- [@lodesmets](https://github.com/lodesmets) (Synology Photos)
|
|
417
|
+
|
|
418
|
+
Found Synology API "documentation" on this repo : https://github.com/kwent/syno/tree/master/definitions
|
|
419
|
+
|
|
420
|
+
# Official references
|
|
421
|
+
|
|
422
|
+
- [Calendar API documentation (2015-2019)](https://global.download.synology.com/download/Document/Software/DeveloperGuide/Package/Calendar/2.4/enu/Synology_Calendar_API_Guide_enu.pdf)
|
|
423
|
+
- [Download Station API documentation (2012-2014)](https://global.download.synology.com/download/Document/Software/DeveloperGuide/Package/DownloadStation/All/enu/Synology_Download_Station_Web_API.pdf)
|
|
424
|
+
- [File Station API documentation (2013-2019)](https://global.download.synology.com/download/Document/Software/DeveloperGuide/Package/FileStation/All/enu/Synology_File_Station_API_Guide.pdf)
|
|
425
|
+
- [Surveillance Station API documentation (2012-2020)](https://global.download.synology.com/download/Document/Software/DeveloperGuide/Package/SurveillanceStation/All/enu/Surveillance_Station_Web_API.pdf)
|
|
426
|
+
- [Virtual Machine Manager API documentation (2015-2019)](https://global.download.synology.com/download/Document/Software/DeveloperGuide/Package/Virtualization/All/enu/Synology_Virtual_Machine_Manager_API_Guide.pdf)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
synology_dsm/__init__.py,sha256=aInIYAdeWaaOVX_brHfDFdGlj6aaSeJpuA8Tl25OV-4,106
|
|
2
|
+
synology_dsm/const.py,sha256=8aAkaVWl87iDsHbs1v-oCnzB6Z6SlPfmU6Syz0T9Lro,8020
|
|
3
|
+
synology_dsm/exceptions.py,sha256=IaFYeiRr6RmCqzr9ewZQW0NcKvLASc9-Z4ShO-DunkU,4935
|
|
4
|
+
synology_dsm/helpers.py,sha256=7AG1Q7u9CbFwKVXIkpgKbNT9aQ28PwmAsZhLZG5l9MU,1432
|
|
5
|
+
synology_dsm/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
synology_dsm/synology_dsm.py,sha256=xRhbvXa46M54Q6LOhxNgT8c31rhDokCXY4gQ6x8BLiE,20983
|
|
7
|
+
synology_dsm/api/__init__.py,sha256=0qNb81jE2nFKVfPMzKaU7sIt8zg3CM_kjaUXFKk04-w,439
|
|
8
|
+
synology_dsm/api/core/__init__.py,sha256=Sh_dB3xUjd-gkqR4nnp-tlj1wRxaKd-H2KURKg4k0yA,32
|
|
9
|
+
synology_dsm/api/core/external_usb.py,sha256=d0WqM5jAf83EW21i1ZAaAAtKxn8hiWZtLv_3DZE0_dA,9177
|
|
10
|
+
synology_dsm/api/core/security.py,sha256=7YIUnutktfSUIUcchgqVFfWjg2mD5l6yw4bZaUefeAM,2321
|
|
11
|
+
synology_dsm/api/core/share.py,sha256=GwwxvMuRYnvwyhYg2bsZX4dOKrXgLz8-or1Hzcl9p44,3136
|
|
12
|
+
synology_dsm/api/core/system.py,sha256=zCAQu4y74r27abF_fKtR2qSTmS2Mmg3Z35sNoWsYzRo,3599
|
|
13
|
+
synology_dsm/api/core/upgrade.py,sha256=f6WdtIdBgupdyJxj03vNxiqe1YPzO_AWmsNJi15PPK0,1576
|
|
14
|
+
synology_dsm/api/core/utilization.py,sha256=PklyNGXMkcvUoGliYiHEPNW0jbyyBHVqTfQirGmi_Vo,6551
|
|
15
|
+
synology_dsm/api/download_station/__init__.py,sha256=JW-pSPoSZruwJynXjc1qVvpENWW5kbxH6cazaW5T0h4,4213
|
|
16
|
+
synology_dsm/api/download_station/task.py,sha256=8vb0vql4K9WouxSLmRjNEyxeeeqtzCaTxGvlxtnGsTE,1922
|
|
17
|
+
synology_dsm/api/dsm/__init__.py,sha256=8x8iUZWB67DgQabXVMBX6y97Gm5RnpbQV61fc0Cn6JM,31
|
|
18
|
+
synology_dsm/api/dsm/information.py,sha256=47jgz9w7oHLIPO7MpoD6tmd00EZzuU8DaUmiHc3z3R8,1889
|
|
19
|
+
synology_dsm/api/dsm/network.py,sha256=YGDPv5aF4RSGzY2TJuTNgRc0-GLt_fAP1xQ5-XtLJqQ,2305
|
|
20
|
+
synology_dsm/api/photos/__init__.py,sha256=5KuwJ6TG5U24xkRQPU0IgzCmlLjhsyGaHH1KuF2UMWI,5658
|
|
21
|
+
synology_dsm/api/photos/model.py,sha256=7R8ygNhJEtdrp9fC6zzMb1FtSzPjP8Yt7ZwNBxJhkKU,460
|
|
22
|
+
synology_dsm/api/storage/__init__.py,sha256=utx2aAU6aFNAUFLXxODDpnzY1cU4IdaCWZ3PFcZhFcU,35
|
|
23
|
+
synology_dsm/api/storage/storage.py,sha256=olJoVDjnnOmWBm-a6Ag0sabY_Z0fr_NYxta3jBfNHFE,8742
|
|
24
|
+
synology_dsm/api/surveillance_station/__init__.py,sha256=TpYLmC0GSaNbrDE0MB9WNCkRgiEC5VxLOU3ZKMyU0EE,9694
|
|
25
|
+
synology_dsm/api/surveillance_station/camera.py,sha256=mz1hpMniNY0RnnArrtb1OOkQ5DUmpZbPNawXZo39qdE,3804
|
|
26
|
+
synology_dsm/api/surveillance_station/const.py,sha256=DqlhX0J2om-I8FBrmJ6519C1kDPcVi04ugMj6ZjNaVs,523
|
|
27
|
+
py_synologydsm_api-2.4.5.dist-info/LICENSE.txt,sha256=WGCx5VLKE4StlP_eAwVq4Kj4yp-hntiKdTJuKAjzgIk,1081
|
|
28
|
+
py_synologydsm_api-2.4.5.dist-info/METADATA,sha256=6t1L9o0Zzlfa6Ldos6TziKcyNJqzCM1QVpQw-aNoE6Y,15320
|
|
29
|
+
py_synologydsm_api-2.4.5.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
30
|
+
py_synologydsm_api-2.4.5.dist-info/entry_points.txt,sha256=TgCBHUoDqjOdg__EY85BPGjnSyDFgkwK_9H7s9mB85Q,63
|
|
31
|
+
py_synologydsm_api-2.4.5.dist-info/top_level.txt,sha256=sTQIu0LAoi94eaOkhlUsrxVmxibEPEbmhqD2c4VMp-M,13
|
|
32
|
+
py_synologydsm_api-2.4.5.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
synology_dsm
|
synology_dsm/__init__.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Synology API models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Generic, TypeVar
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from synology_dsm import SynologyDSM
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
_DataT = TypeVar("_DataT")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SynoBaseApi(Generic[_DataT]):
|
|
15
|
+
"""Base api class."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, dsm: "SynologyDSM") -> None:
|
|
18
|
+
"""Constructor method."""
|
|
19
|
+
self._dsm = dsm
|
|
20
|
+
self._data: _DataT = {} # type: ignore[assignment]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Synology Core API models."""
|