Package: py-synologydsm-api
Asynchronous Python API for Synology DSMInstallation[sudo]pipinstallpy-synologydsm-apiUsageYou can import the module assynology_dsm.ConstructorSynologyDSM(session,dsm_ip,dsm_port,username,password,use_https=False,timeout=10,device_token=None,debugmode=False,)Forsessiona validaiohttp.ClientSessionneeds to be provided. If ssl verification should be truned off, configure the session accordingly (eq.aiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False))device_tokenshould 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).Defaulttimeoutis 10 seconds.LoginUse thelogin()function to authenticate first, otherwise aSynologyDSMNotLoggedInExceptionis raised.It will return a boolean if it successed or faild to authenticate to DSM.If your account need a two-step authentication (2SA),login()will raiseSynologyDSMLogin2SARequiredException.
Call the function again with a One Time Password (OTP) as parameter, likelogin("123456")(better to be a string to handle first zero).
Store thedevice_tokenproperty so that you do not need to reconnect with password the next time you open a newSynologyDSMsession.Code exampleEvery API has anupdate()function that is needed to get the first data, then the data is cached and updated at the nextupdate()call.TheSynologyDSMclass can alsoupdate()all APIs at once.importasyncioimportaiohttpfromsynology_dsmimportSynologyDSMasyncdefmain():print("Creating Valid API")asyncwithaiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False))assession:awaitdo(session)asyncdefdo(session:aiohttp.ClientSession):api=SynologyDSM(session,"<IP/DNS>","<port>","<username>","<password>")awaitapi.login()print("=== Information ===")awaitapi.information.update()print("Model:           "+str(api.information.model))print("RAM:             "+str(api.information.ram)+" MB")print("Serial number:   "+str(api.information.serial))print("Temperature:     "+str(api.information.temperature)+" °C")print("Temp. warning:   "+str(api.information.temperature_warn))print("Uptime:          "+str(api.information.uptime))print("Full DSM version:"+str(api.information.version_string))print("--")print("=== Utilisation ===")awaitapi.utilisation.update()print("CPU Load:        "+str(api.utilisation.cpu_total_load)+" %")print("Memory Use:      "+str(api.utilisation.memory_real_usage)+" %")print("Net Up:          "+str(api.utilisation.network_up()))print("Net Down:        "+str(api.utilisation.network_down()))print("--")print("=== Storage ===")awaitapi.storage.update()forvolume_idinapi.storage.volumes_ids:print("ID:          "+str(volume_id))print("Status:      "+str(api.storage.volume_status(volume_id)))print("% Used:      "+str(api.storage.volume_percentage_used(volume_id))+" %")print("--")fordisk_idinapi.storage.disks_ids:print("ID:          "+str(disk_id))print("Name:        "+str(api.storage.disk_name(disk_id)))print("S-Status:    "+str(api.storage.disk_smart_status(disk_id)))print("Status:      "+str(api.storage.disk_status(disk_id)))print("Temp:        "+str(api.storage.disk_temp(disk_id)))print("--")print("=== Shared Folders ===")awaitapi.share.update()forshare_uuidinapi.share.shares_uuids:print("Share name:        "+str(api.share.share_name(share_uuid)))print("Share path:        "+str(api.share.share_path(share_uuid)))print("Space used:        "+str(api.share.share_size(share_uuid,human_readable=True)))print("Recycle Bin Enabled: "+str(api.share.share_recycle_bin(share_uuid)))print("--")if__name__=="__main__":asyncio.run(main())Download Station usageimportasyncioimportaiohttpfromsynology_dsmimportSynologyDSMasyncdefmain():print("Creating Valid API")asyncwithaiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False))assession:awaitdo(session)asyncdefdo(session:aiohttp.ClientSession):api=SynologyDSM(session,"<IP/DNS>","<port>","<username>","<password>")awaitapi.login()if"SYNO.DownloadStation.Info"inapi.apis:awaitapi.download_station.get_info()awaitapi.download_station.get_config()# The download list will be updated after each of the following functions:# You should have the right on the (default) directory that the download will be saved, or you will get a 403 or 406 errorawaitapi.download_station.create("http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")awaitapi.download_station.pause("dbid_1")# Like the other function, you can eather pass a str or a listawaitapi.download_station.resume(["dbid_1","dbid_2"])awaitapi.download_station.delete("dbid_3")# Manual updateawaitapi.download_station.update()if__name__=="__main__":asyncio.run(main())External USB storage usageimportasyncioimportaiohttpfromsynology_dsmimportSynologyDSMasyncdefmain():print("Creating Valid API")asyncwithaiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False))assession:awaitdo(session)asyncdefdo(session:aiohttp.ClientSession):api=SynologyDSM(session,"<IP/DNS>","<port>","<username>","<password>")awaitapi.login()awaitapi.external_usb.update()fordeviceinapi.external_usb.get_devices.values():print("Name:                   "+str(device.device_name))print("Size:                   "+str(device.device_size_total(human_readable=True))print("Size in mb:             "+str(device.device_size_total())print("Partitions size total:  "+str(device.partitions_all_size_total(human_readable=True)))print("Partitions size used:   "+str(device.partitions_all_size_used(human_readable=True)))print("Partitions % Used:      "+str(device.partitions_all_percentage_used)+" %")print("    === Partitions ===")forpartindevice.device_partitions.values():print("    Share name:             "+str(part.share_name))print("    Filesystem:             "+str(part.filesystem))print("    Size:                   "+str(part.partition_size_total(human_readable=True)))print("    Used:                   "+str(part.partition_size_used(human_readable=True)))print("    % Used:                 "+str(part.partition_percentage_used)+" %")if__name__=="__main__":asyncio.run(main())Photos usageimportasyncioimportaiohttpfromsynology_dsmimportSynologyDSMasyncdefmain():print("Creating Valid API")asyncwithaiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False))assession:awaitdo(session)asyncdefdo(session:aiohttp.ClientSession):api=SynologyDSM(session,"<IP/DNS>","<port>","<username>","<password>")awaitapi.login()albums=awaitapi.photos.get_albums()# download each item of each albumforalbuminalbums:print(f"'{album.name}' has{album.item_count}items")items=awaitapi.photos.get_items_from_album(album)foriteminitems:print(f"{item.file_name}")withopen(item.file_name,"wb")asfh:fh.write(awaitapi.photos.download_item(item))# search for items and download themitems=awaitapi.photos.get_items_from_search("pinky and the brain")foriteminitems:withopen(item.file_name,"wb")asfh:fh.write(awaitapi.photos.download_item(item))if__name__=="__main__":asyncio.run(main())Surveillance Station usageimportasyncioimportaiohttpfromsynology_dsmimportSynologyDSMasyncdefmain():print("Creating Valid API")asyncwithaiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False))assession:awaitdo(session)asyncdefdo(session:aiohttp.ClientSession):api=SynologyDSM(session,"<IP/DNS>","<port>","<username>","<password>")awaitapi.login()surveillance=api.surveillance_stationawaitsurveillance.update()# First update is required# Returns a list of cached cameras availablecameras=surveillance.get_all_cameras()# Assuming there's at least one camera, get the first camera_idcamera_id=cameras[0].camera_id# Returns cached camera object by camera_idcamera=surveillance.get_camera(camera_id)# Returns cached motion detection enabledmotion_setting=camera.is_motion_detection_enabled# Return bytes of camera imageawaitsurveillance.get_camera_image(camera_id)# Updates all cameras/motion settings and cahce themawaitsurveillance.update()# Gets Home Mode statushome_mode_status=awaitsurveillance.get_home_mode_status()# Sets home mode - true is on, false is offawaitsurveillance.set_home_mode(True)if__name__=="__main__":asyncio.run(main())System usageimportasyncioimportaiohttpfromsynology_dsmimportSynologyDSMasyncdefmain():print("Creating Valid API")asyncwithaiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False))assession:awaitdo(session)asyncdefdo(session:aiohttp.ClientSession):api=SynologyDSM(session,"<IP/DNS>","<port>","<username>","<password>")awaitapi.login()system=api.system# Reboot NASawaitsystem.reboot()# Shutdown NASawaitsystem.shutdown()# Manual update system informationawaitsystem.update()# Get CPU informationsystem.cpu_clock_speedsystem.cpu_coressystem.cpu_familysystem.cpu_series# Get NTP settingssystem.enabled_ntpsystem.ntp_server# Get system informationsystem.firmware_versystem.modelsystem.ram_sizesystem.serialsystem.sys_tempsystem.timesystem.time_zonesystem.time_zone_descsystem.up_time# Get list of all connected USB devicessystem.usb_devif__name__=="__main__":asyncio.run(main())Upgrade usageimportasyncioimportaiohttpfromsynology_dsmimportSynologyDSMasyncdefmain():print("Creating Valid API")asyncwithaiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False))assession:awaitdo(session)asyncdefdo(session:aiohttp.ClientSession):api=SynologyDSM(session,"<IP/DNS>","<port>","<username>","<password>")awaitapi.login()upgrade=api.upgrade# Manual update upgrade informationawaitupgrade.update()# check if DSM update is availableifupgrade.update_available:dosomething...# get available version string (return None if no update available)upgrade.available_version# get need of reboot (return None if no update available)upgrade.reboot_needed# get need of service restarts (return None if no update available)upgrade.service_restartsif__name__=="__main__":asyncio.run(main())Credits / Special Thanks@florianeinfalt@tchellomello@Quentame(Multiple API addition & tests)@aaska(DSM 5 tests)@chemelli74(2SA tests)@snjoetw(Surveillance Station library)@shenxn(Surveillance Station tests)@Gestas(Shared Folders)@lodesmets(Synology Photos)Found Synology API "documentation" on this repo :https://github.com/kwent/syno/tree/master/definitionsOfficial referencesCalendar API documentation (2015-2019)Download Station API documentation (2012-2014)File Station API documentation (2013-2019)Surveillance Station API documentation (2012-2020)Virtual Machine Manager API documentation (2015-2019)