You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Of these steps, only the first one really is unique to each API method. The last three are redundant and could be automatised. Here is a suggestion of improvement based on decorated methods.
Suggestion
Let's consider the following canonical example, from file core_backup.py:
And similarly for other methods. One could imagine cases where the name=<api_name> and method=<method_name> arguments would not need to be provided. Respectively when the static class attribute _API_NAME = '...' is provided and assumed to be the default API name for methods of that class ; and when the name of the python method unambiguously matches the name of the SYNO API method. Here is a possible example from file core_iscsi.py:
classLUN(base_api.BaseApi):
_API_NAME="SYNO.Core.ISCSI.LUN"# In the @api decorator below,# -> Default api name = self._API_NAME = "SYNO.Core.ISCSI.LUN"# -> Default method name = 'delete'@apidefdelete(self, uuid_or_uuids_list: str|Sequence[str]) ->dict:
return {
"uuid": '""',
"uuids": _json(_ensure_list(uuid_or_uuids_list))
}
Advantages
There are multiple advantages in using such a decorator implementation for API methods:
Redundant building of meta-arguments for requests in systematised in some common framework (version, api_path). The decorator is defined once and imported in each file.
Internal api_name used by method is clearly built in the decorator arguments (useful for documentation parsing, where currently an assignment to the variable self.api_name = '...' is enforced)
The distinction between API-request (decorated) and utility methods (non-decorated) is unambiguous
The decorator mechanism could be used to register methods in a single common class/object, as suggested in Reorganization of the wrapper by apps #259, at class-import time. For instance, importing the classes from the examples above could dynamically populate a common SYNO or DSM object, leading to possible calls of the API methods through e.g.SYNO.Backup.Repository.get() and SYNO.Core.ISCSI.LUN.delete(). This reconciles the currently implemented approach and the reorganisation of methods per API path suggested in Reorganization of the wrapper by apps #259 ; while maintaining full backward compatibility.
Context
The vast majority (all but higher-level wrappers) of methods consist in:
paramsdictionaryparamsdictionary with API method's name ('method' : ...) and version ('version' : ...)api_pathfromBaseAPI.gen_list[api_name]['path']BaseAPI.request_data(api_name, api_path, params)Of these steps, only the first one really is unique to each API method. The last three are redundant and could be automatised. Here is a suggestion of improvement based on decorated methods.
Suggestion
Let's consider the following canonical example, from file
core_backup.py:The decorated implementation of method
backup_repository_get()would look like:And similarly for other methods. One could imagine cases where the
name=<api_name>andmethod=<method_name>arguments would not need to be provided. Respectively when the static class attribute_API_NAME = '...'is provided and assumed to be the default API name for methods of that class ; and when the name of the python method unambiguously matches the name of the SYNO API method. Here is a possible example from filecore_iscsi.py:Advantages
There are multiple advantages in using such a decorator implementation for API methods:
version,api_path). The decorator is defined once and imported in each file.api_nameused by method is clearly built in the decorator arguments (useful for documentation parsing, where currently an assignment to the variableself.api_name = '...'is enforced)SYNOorDSMobject, leading to possible calls of the API methods through e.g.SYNO.Backup.Repository.get()andSYNO.Core.ISCSI.LUN.delete(). This reconciles the currently implemented approach and the reorganisation of methods per API path suggested in Reorganization of the wrapper by apps #259 ; while maintaining full backward compatibility.