lewis.adapters.stream
Members
This class is an implementation of |
|
Objects of this type connect a callable object to a pattern matcher ( |
|
This class defines an interface for general command-matchers that use any kind of technique to match a certain request in string form. |
|
The StreamAdapter is the bridge between the Device Interface and the TCP Stream networking backend implementation. |
|
This class is used to provide a TCP-stream based interface to a device. |
|
|
|
With this implementation of |
|
Implementation of |
|
Interprets the specified pattern as a scanf format. |
- class lewis.adapters.stream.Cmd(func, pattern, argument_mappings=None, return_mapping=<function Cmd.<lambda>>, doc=None)[source]
Bases:
CommandBase
This class is an implementation of
CommandBase
that can expose a callable object or a named method of the device/interface controlled byStreamAdapter
.def random(): return 6 SomeInterface(StreamInterface): commands = { Cmd(lambda: 4, pattern='^R$', doc='Returns a random number.'), Cmd('random', pattern='^RR$', doc='Better random number.'), Cmd(random, pattern='^RRR$', doc='The best random number.'), } def random(self): return 5
The interface defined by the above example has three commands,
R
which calls a lambda function that always returns 4,RR
, which callsSomeInterface.random
and returns 5 and lastlyRRR
which calls the free function defined above and returns the best random number.For a detailed explanation of requirements to the constructor arguments, please refer to the documentation of
Func
, to which the arguments are forwarded.See also
Var
exposes attributes and properties of a device object. The documentation ofFunc
provides more information about the common constructor arguments.- Parameters:
func – Function to be called when pattern matches or member of device/interface.
pattern – Pattern to match (
PatternMatcher
or string).argument_mappings – Iterable with mapping functions from string to some type.
return_mapping – Mapping function for return value of method.
doc – Description of the command. If not supplied, the docstring is used.
- class lewis.adapters.stream.CommandBase(func, pattern, argument_mappings=None, return_mapping=None, doc=None)[source]
Bases:
object
This is the common base class of
Cmd
andVar
. The concept of commands for the stream adapter is based on connecting a callable object to a pattern that matches an inbound request.The type of pattern can be either an implementation of
PatternMatcher
(regex or scanf format specification) or a plain string (which is treated as a regular expression).For free function and lambda expressions this is straightforward: the function object can simply be stored together with the pattern. Most often however, the callable is a method of the device or interface object - these do not exist when the commands are defined.
This problem is solved by introducing a “bind”-step in
StreamAdapter
. So instead of a function object, bothCmd
andVar
store the name of a member of device or interface. At “bind-time”, this is translated into the correct callable.So instead of using
Cmd
orVar
directly, both classes’bind()
-methods return an iterable ofFunc
-objects which can be used for processing requests.StreamAdapter
performs this bind-step when it’s constructed. For details regarding the implementations, please see the corresponding classes.See also
Please take a look at
Cmd
for exposing callable objects or methods of device/interface andVar
for exposing attributes and properties.To see how argument_mappings, return_mapping and doc are applied, please look at
Func
.- Parameters:
func – Function to be called when pattern matches or member of device/interface.
pattern – Pattern to match (
PatternMatcher
or string).argument_mappings – Iterable with mapping functions from string to some type.
return_mapping – Mapping function for return value of method.
doc – Description of the command. If not supplied, the docstring is used.
- class lewis.adapters.stream.Func(func, pattern, argument_mappings=None, return_mapping=None, doc=None)[source]
Bases:
object
Objects of this type connect a callable object to a pattern matcher (
PatternMatcher
), which currently comprisesregex
andscanf
. Strings are also accepted, they are treated like a regular expression internally. This preserves default behavior from older versions of Lewis.In general, Func-objects should not be created directly, instead they are created by one of the sub-classes of
CommandBase
usingbind()
.Function arguments are indicated by groups in the regular expression. The number of groups has to match the number of arguments of the function. In earlier versions of Lewis it was possible to pass flags to
re.compile
, this has been removed for consistency issues inVar
. It is however still possible to use the exact same flags as part of the regular expression. In the documentation of re, this is outlined, simply add a group to the expression that contains the flags, for example(?i)
to make the expression case insensitive. This special group does not count towards the matching groups used for argument capture.The optional argument_mappings can be an iterable of callables with one parameter of the same length as the number of arguments of the function. The first parameter will be transformed using the first function, the second using the second function and so on. This can be useful to automatically transform strings provided by the adapter into a proper data type such as
int
orfloat
before they are passed to the function. In case the pattern is of typescanf
, this is optional (but will override the mappings provided by the matcher).The return_mapping argument is similar, it should map the return value of the function to a string. The default map function only does that when the supplied value is not None. It can also be set to a numeric value or a string constant so that the command always returns the same value. If it is
None
, the return value is not modified at all.Finally, documentation can be provided by passing the doc-argument. If it is omitted, the docstring of the bound function is used and if that is not present, left empty.
- Parameters:
func – Function to be called when pattern matches or member of device/interface.
argument_mappings – Iterable with mapping functions from string to some type.
return_mapping – Mapping function for return value of method.
doc – Description of the command. If not supplied, the docstring is used.
- Raises:
RuntimeError: If the function cannot be mapped for any reason.
- map_arguments(arguments)[source]
Returns the mapped function arguments. If no mapping functions are defined, the arguments are returned as they were supplied.
- Parameters:
arguments – List of arguments for bound function as strings.
- Returns:
Mapped arguments.
- map_return_value(return_value)[source]
Returns the mapped return_value of a processed request. If no return_mapping has been defined, the value is returned as is. If return_mapping is a static value, that value is returned, ignoring return_value completely.
- Parameters:
return_value – Value to map.
- Returns:
Mapped return value.
- class lewis.adapters.stream.PatternMatcher(pattern)[source]
Bases:
object
This class defines an interface for general command-matchers that use any kind of technique to match a certain request in string form. It is used by
Func
to check whether a request can be processed using a function and to extract any function arguments.Sub-classes must implement all defined abstract methods/properties.
- property arg_count: NoReturn
Number of arguments that are matched in a request.
- property argument_mappings: NoReturn
Mapping functions that can be applied to the arguments returned by
match()
.
- match(request) NoReturn [source]
Tries to match the request against the internally stored pattern. Returns any matched function arguments.
- Parameters:
request – Request to attempt matching.
- Returns:
List of matched argument values (possibly empty) or None if not matching.
- property pattern
The pattern definition used for matching a request.
- class lewis.adapters.stream.StreamAdapter(options=None)[source]
Bases:
Adapter
The StreamAdapter is the bridge between the Device Interface and the TCP Stream networking backend implementation.
Available adapter options are:
bind_address: IP of network adapter to bind on (defaults to 0.0.0.0, or all adapters)
port: Port to listen on (defaults to 9999)
telnet_mode: When True, overrides in- and out-terminator for CRNL (defaults to False)
- Parameters:
options – Dictionary with options.
- property documentation
This property can be overridden in a sub-class to provide protocol documentation to users at runtime. By default it returns the indentation cleaned-up docstring of the class.
- handle(cycle_delay=0.1) None [source]
Spend approximately
cycle_delay
seconds to process requests to the server.- Parameters:
cycle_delay – S
- property is_running
This property indicates whether the Adapter’s server is running and listening. The result of calls to
start_server()
andstop_server()
should be reflected as expected.
- start_server() None [source]
Starts the TCP stream server, binding to the configured host and port. Host and port are configured via the command line arguments.
Note
The server does not process requests unless
handle()
is called in regular intervals.
- stop_server() None [source]
This method must be re-implemented to stop and tear down anything that has been setup in
start_server()
. This method should close all connections to clients that have been established since the adapter has been started.Note
This method may be called multiple times over the lifetime of the Adapter, so it is important to make sure that this does not cause problems.
- class lewis.adapters.stream.StreamInterface[source]
Bases:
InterfaceBase
This class is used to provide a TCP-stream based interface to a device.
Many hardware devices use a protocol that is based on exchanging text with a client via a TCP stream. Sometimes RS232-based devices are also exposed this way via an adapter-box. This adapter makes it easy to mimic such a protocol.
This class has the following attributes which may be overridden by subclasses:
protocol: What this interface is called for purposes of the -p commandline option. Defaults to “stream”.
in_terminator, out_terminator: These define how lines are terminated when transferred to and from the device respectively. They are stripped/added automatically. Inverse of protocol file InTerminator and OutTerminator. The default is
\\r
.readtimeout: How many msec to wait for additional data between packets, once transmission of an incoming command has begun. Inverse of ReadTimeout in protocol files. Defaults to 100 (ms). Set to 0 to disable timeout completely.
commands: A list of
CommandBase
-objects that define mappings between protocol and device/interface methods/attributes.
By default, commands are expressed as regular expressions, a simple example may look like this:
class SimpleDeviceStreamInterface(StreamInterface): commands = [ Cmd('set_speed', r'^S=([0-9]+)$', argument_mappings=[int]), Cmd('get_speed', r'^S\?$') Var('speed', read_pattern=r'^V\?$', write_pattern=r'^V=([0-9]+)$') ] def set_speed(self, new_speed): self.device.speed = new_speed def get_speed(self): return self.device.speed
The interface has two commands,
S?
to return the speed andS=10
to set the speed to an integer value. It also exposes the same speed attribute as a variable, using auto- generatedV?
andV=10
commands.As in the
lewis.adapters.epics.EpicsInterface
, it does not matter whether the wrapped method is a part of the device or of the interface, this is handled automatically when a new device is assigned to thedevice
-property.In addition, the
handle_error()
-method can be overridden. It is called when an exception is raised while handling commands.- property adapter
Adapter type that is required to process and expose interfaces of this type. Must be implemented in subclasses.
- handle_error(request, error) None [source]
Override this method to handle exceptions that are raised during command processing. The default implementation does nothing, so that any errors are silently ignored.
- Parameters:
request – The request that resulted in the error.
error – The exception that was raised.
- class lewis.adapters.stream.Var(target_member, read_pattern=None, write_pattern=None, argument_mappings=None, return_mapping=<function Var.<lambda>>, doc=None)[source]
Bases:
CommandBase
With this implementation of
CommandBase
it’s possible to expose plain data attributes or properties of device or interface. Getting and setting a value are separate procedures which both have their own pattern, read_pattern and write_pattern to match a command each. Please note that write_pattern has to have exactly one group defined to match a parameter.Due to this separation, parameters can be made read-only, write-only or read-write in the interface:
class SomeInterface(StreamInterface): commands = { Var('foo', read_pattern='^F$', write_pattern=r'^F=(\d+)$', argument_mappings=(int,), doc='An integer attribute.'), Var('bar' read_pattern='^B$') } foo = 10 @property def bar(self): return self.foo + 5 @bar.setter def bar(self, new_bar): self.foo = new_bar - 5
In the above example, the foo attribute can be read and written, it’s automatically converted to an integer, while bar is a property that can only be read via the stream protocol.
See also
For exposing methods and free functions, there’s the
Cmd
-class.- Parameters:
target_member – Attribute or property of device/interface to expose.
read_pattern – Pattern to match for getter (
PatternMatcher
or string).write_pattern – Pattern to match for setter (
PatternMatcher
or string).argument_mappings – Iterable with mapping functions from string to some type, only applied to setter.
return_mapping – Mapping function for return value of method, applied to getter and setter.
doc – Description of the command. If not supplied, the docstring is used. For plain data attributes the only way to get docs is to supply this argument.
- class lewis.adapters.stream.regex(pattern)[source]
Bases:
PatternMatcher
Implementation of
PatternMatcher
that compiles the specified pattern into a regular expression.- property arg_count
Number of arguments that are matched in a request.
- class lewis.adapters.stream.scanf(pattern, exact_match=True)[source]
Bases:
regex
Interprets the specified pattern as a scanf format. Internally, the scanf package is used to transform the format into a regular expression. Please consult the documentation of scanf for valid pattern specifications.
By default, the resulting regular expression matches exactly. Consider this example:
exact = scanf("T=%f") not_exact = scanf("T=%f", exact_match=False)
The first pattern only matches the string
T=4.0
, whereas the second would also matchT=4.0garbage
. Please note that the specifiers like%f
are automatically turned into groups in the generated regular expression.- Parameters:
pattern – Scanf format specification.
exact_match – Match only if the entire string matches.
- property argument_mappings
Mapping functions that can be applied to the arguments returned by
match()
.
- property pattern
The pattern definition used for matching a request.