WebAPI Core¶
The next module of this small API implementation focuses on the “FsNetRemoteLib.” All nodes presented here were converted from the Java source code of the app “Medion Lifestream 2.”
The script used for converting the code can be found in the repository. The source code was converted to reduce the manual effort, as the final “_nodes.py” file contained more than 4000 lines of code.
When querying a resource or attempting to set a value to a specific node, there is always a status message that accompanies the response. Common possible values for this status are:
Status |
Body |
Description |
---|---|---|
FS_OK |
True |
If everything goes right the status is set to FS_OK |
FS_PACKET_BAD |
False |
This status code will be returned if a value should be applied to a read-only node. |
FS_NODE_BLOCKED |
False |
Sometimes this status is given, maybe because the node was deactivated on the device. |
FS_NODE_DOES_NOT_EXIST |
False |
As the name already states, the requested node is not implemented on that device. |
FS_TIMEOUT |
False |
The device takes too long to respond |
FS_FAIL |
False |
If the parameters given in the url are mot matching the node criteria, the request will fail. |
- net.nodes = Path ''¶
Global path object for defined API nodes.
This object can be used to search for registered node classes. For instance, following this control flow leads to all available nodes:
>>> available_nodes = list(nodes.iter_nodes())
Each node is mapped to a unique path, which can be accessed by using the true div operation in python:
>>> nodes / "foo" / "bar" Path 'foo.bar'
Alternatively, the amount of operations can be reduced by specifying the complete path directly:
>>> nodes / "foo.bar" Path 'foo.bar'
- net.dynamic = <object object>¶
Specifier for dynamic prototypes.
If the structure of a certain node is not clear, the “dynamic” prototype can be used temporarily to parse incoming XML data.
>>> class foo_nt(Node): ... class Meta: ... path = "foo.bar" ... prototype = dynamic ...
Note that list nodes should extend the
NodeList
class as the parsing workflow is slightly different.
- class fsapi.net.NodeBase(name, bases, attrs: dict, **kwargs)¶
Base class for node classes.
In order to enable access to all defined nodes this class will add each defined node class that specifies a “path” to an internal map. Attributes are defined using an inner “Meta” class that stores special class attributes:
>>> class foo_nt(Node): ... class Meta: ... path = "foo.bar" ... name = "Foo node" ... prototype = [Argument(type=ArgType.ARG_TYPE_U16)] ...
Using the global nodes instance makes it easier to create instances of the previously defined node class.
>>> path = nodes / "foo" / "bar" >>> if path.exists(): ... node: foo_nt = path.create() ...
Note that all attributes defined in the meta class will be accessable as class properties of the defined node class. For instance:
>>> node_class = path.get_node_type() >>> node_class.path 'foo.bar' >>> node.path AttributeError: 'foo.bar' object has no attribute 'path'
- property cacheable: bool¶
Specifies whether this node is cacheable.
- property description: str¶
Documentation of the node.
- property is_list: bool¶
Returns whether this class is a list class.
- property name: str¶
Graphical display name
- property notifying: bool¶
Specifies whether GET_NODTIFIES is applicable.
- property path: str¶
Defines the unique path of a node.
- read(tree: Element) Node ¶
Converts XML input into the corresponding node object.
This method will automatically convert XML list structures to node list items only if the desired node class extends the
NodeList
class.>>> class foo_nt(Node): ... ... # meta is defined here ... >>> node = foo_nt.read(xml_element)
- read_list(tree: Element) Node ¶
Converts XML input to a node extending the
NodeList
class.- Parameters:
cls (Type[NodeList]) – the node class
tree (ElementTree.Element) – the fsapiResponse XML element
- Returns:
a node object storing a list of
NodeListItem
objects- Return type:
- property readonly: bool¶
Returns true if only non-write operations are permitted.
- class fsapi.net.Node(value=None)¶
Base class of all node classes.
Each node stores a value and the node class stores the node’s meta information. Be aware of the difference, a node object is designed to store a node’s value, NOT the meta information. Those are linked to the class instance.
>>> path = NodePath("netRemote.sys.info.version") >>> node_class = path.get_node_type() >>> node_class.path "netRemote.sys.info.version" >>> node = path.create() >>> node.path AttributeError: '...' object has no attribute 'path'
- Parameters:
value – the node’s value
- has_method(method: str) bool ¶
Checks whether the provided method is allowed
- supports_module(module_name: str) bool ¶
Checks whether the provided FS module is supported.
- property value: int | str | List[NodeListItem] | NodeValue¶
The node’s value
- Returns:
the currently applied node value or None
- Return type:
int | str | t.List[NodeListItem] | NodeValue
- class fsapi.net.NodePath(name: str, base: str = None)¶
A class to search and navigate to implemented nodes.
NodePath objects store some utility attributes and capabilities that help searching for implemented notes. For instance, the following code searches for all implemented nodes starting with the path “netRemote.misc”:
>>> path = NodePath("netRemote") / "misc" >>> list(path.iter_nodes()) ['netRemote.misc.fsDebug.component', 'netRemote.misc.fsDebug.traceLevel', ...]
This class is designed to provide access to implemented node classes, create new instances of nodes and to be able to search for specific nodes. In order to verfiy that a certain node is implemented, there is a verification method:
>>> path = NodePath("netRemote") / "misc" / "fsDebug.component" >>> path.exists() True >>> path.create() Node(path="netRemote.misc.fsDebug.component", has_value=True)
- create(*args, **kwargs) Node ¶
Creates a new instance of a node with the given argument values.
- Returns:
the new node instance
- Return type:
- Raises:
KeyError – if the node path does not exists
- exists() bool ¶
Verifies that a certain node exists.
- Returns:
True if the node is implemented, false otherwise
- Return type:
bool
- from_xml(tree: ElementTree) Node ¶
Tries to convert the given XML tree to a node.
- Parameters:
tree (ElementTree.ElementTree) – the XML response of the device
- Raises:
KeyError – if the node does not exists
- Returns:
the new node instance
- Return type:
- get_node_type() Type[Node] ¶
Returns the node type.
- Returns:
the type of the implemented node
- Return type:
Type[Node]
- Raises:
KeyError – if the node path does not exists
- iter_nodes() Iterator[str] ¶
Iterates over all nodes that start with this path.
- Returns:
all filtered nodes as an iterator
- Return type:
Iterator[str]
- class fsapi.net.ArgType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)¶
Value types for node prototypes.
Argument types are used by node prototypes to enable appropriate de-serialization of incoming data.
- ARG_TYPE_C8 = 16¶
C8-Array (char array), type: str
- ARG_TYPE_E8 = 17¶
Type defined by an Enum, type: int
- ARG_TYPE_S16 = 22¶
Signed Int16, type: int
- ARG_TYPE_S32 = 23¶
Signed Int32, type: int
- ARG_TYPE_S8 = 21¶
Signed Int8, type: int
- ARG_TYPE_U = 24¶
Array of data, type: str
- ARG_TYPE_U16 = 19¶
Unsigned Int16, type: int
- ARG_TYPE_U32 = 20¶
Unsigned Int32, type: int
- ARG_TYPE_U8 = 18¶
Unsigned Int8, type: int
- ARG_TYPE_UNKNOWN = -1¶
Invalid type, will be mapped to str
- to_python(value: str) Any ¶
Convert the given value to a Python object based on the ArgType.
This method is used to convert a string representation of a value to a Python object of the appropriate type based on the ArgType.
- Parameters:
value (str) – The value as a string to be converted.
- Returns:
The Python object representing the converted value.
- class fsapi.net.Argument(name: str = 'value', length: int = 1, type: ArgType = ArgType.ARG_TYPE_UNKNOWN)¶
Defines an argument within a node prototype.
A node’s prototype contains arguments in order to parse XML responses back to python values.
- Parameters:
name (str) – The name of this argument, default “value”
length (int) – the length of this value, 1 := one element
type (
ArgType
) – the argument type used to parse the XML content
- class fsapi.net.NodeValue(type: ArgType, value: int | str | None = None)¶
Anonymous value class.
When using dynamic prototypes, this class is used to represent the values in a XML response.
- Parameters:
type – the argument type
- Param:
value: the stored value (enum values won’t be covered)
Node Classes¶
- class fsapi.net.NodeInt(value=None, minimum=0, maximum=0)¶
Defines an integer node with an acceptable range of values.
>>> node = NodeInt(minimum=0, maximum=10) >>> node.value = 11 ValueError: Expected value between 0 and 10 - got 11
- Parameters:
value (int) – the node’s value
minimum (int) – the minimum value that gets accepted
maximum (int) – the maximum value that gets accepted
- class fsapi.net.NodeList(items: list = None)¶
Special node that contains multiple items.
You can use this class with the len function or within a loop.
>>> node_list = ... >>> len(node_list) 2 >>> for item in node_list: ... # inspect item
- Parameters:
items (list) – a list of
NodeListItem
objects
- property items: t.List[NodeListItem]¶
Returns the stored items as a list.
- Returns:
the stored list items
- Return type:
t.List[NodeListItem]
- class fsapi.net.NodeListItem(attributes: dict = None)¶
Content item of a
NodeList
.- property fields: t.List[str]¶
Returns a list of field names.
- Returns:
all field names stored by this item.
- Return type:
t.List[str]
- get(field_name: str, _NodeListItem__default=None) str | NodeE8 | int | NodeValue | None ¶
Return the value for key if key is in the attribites, else default.
- Parameters:
field_name (str) – the field’s name
__default – the default return value, defaults to None
- Returns:
the stored, converted python representation
- Return type:
_NodeListItemValue | None
- class fsapi.net.NodeS8(value: int = 0)¶
Signed Int8 node (min: -127, max: 127)
- class fsapi.net.NodeS16(value: int = 0)¶
Signed Int16 node (min: -0x7FFF, max: 0x7FFF)
- class fsapi.net.NodeS32(value: int = 0)¶
Signed Int32 node (min: -0x7FFFFFFF, max: 0x7FFFFFFF)
- class fsapi.net.NodeU8(value: int = 0)¶
Unsigned Int8 node (min: 0, max: 255)
- class fsapi.net.NodeU16(value: int = 0)¶
Unsigned Int16 node (min: 0, max: 0xFFFF)
- class fsapi.net.NodeU32(value: int = 0)¶
Unsigned Int32 node (min: 0, max: 0xFFFFFFFF)
- class fsapi.net.NodeE8(value=None, defaults=None)¶
Enum node. (internal mapping contains enum names)
- property enum_value: str | Any | None¶
Returns the associated value’s name (if present)
- Returns:
the value’s names
- Return type:
str | Any
- class fsapi.net.NodeC8(value=None, max_size: int = 1024)¶
Character array node (string)