moler package

Subpackages

Submodules

moler.abstract_moler_connection module

moler.asyncio_runner module

Asyncio Runner

class moler.asyncio_runner.AsyncioEventThreadsafe(*, loop=None)

Bases: asyncio.locks.Event

clear()

Reset the internal flag to false. Subsequently, coroutines calling wait() will block until set() is called to set the internal flag to true again.

set()

Set the internal flag to true. All coroutines waiting for it to become true are awakened. Coroutine that call wait() once the flag is true will not block at all.

class moler.asyncio_runner.AsyncioInThreadRunner

Bases: moler.asyncio_runner.AsyncioRunner

shutdown()

Cleanup used resources.

submit(connection_observer)

Submit connection observer to background execution. Returns Future that could be used to await for connection_observer done.

wait_for(connection_observer, connection_observer_future, timeout=None)

Await for connection_observer running in background or timeout.

Parameters:
  • connection_observer – The one we are awaiting for.
  • connection_observer_future – Future of connection-observer returned from submit().
  • timeout – Max time (in float seconds) to await before give up. None - use connection_observer.timeout
Returns:

wait_for_iterator(connection_observer, connection_observer_future)

Version of wait_for() intended to be used by Python3 to implement iterable/awaitable object.

Note: we don’t have timeout parameter here. If you want to await with timeout please do use timeout machinery of selected parallelism.

Parameters:
  • connection_observer – The one we are awaiting for.
  • connection_observer_future – Future of connection-observer returned from submit().
Returns:

iterator

class moler.asyncio_runner.AsyncioLoopThread(name='Asyncio')

Bases: moler.io.raw.TillDoneThread

join(timeout=None)

Closing asyncio loop must be done from MainThread to allow for removing signal handlers

run_async_coroutine(coroutine_to_run, timeout)

Start coroutine in dedicated thread and await its result with timeout

start()

We wan’t this method to not return before it ensures that thread and it’s enclosed loop are really running.

start_async_coroutine(coroutine_to_run)

Start coroutine in dedicated thread, don’t await its result

class moler.asyncio_runner.AsyncioRunner(logger_name='moler.runner.asyncio')

Bases: moler.runner.ConnectionObserverRunner

feed(connection_observer, subscribed_data_receiver, observer_lock)

Feeds connection_observer by transferring data from connection and passing it to connection_observer. Should be called from background-processing of connection observer.

last_runner_id = 0
runner_lock = <unlocked _thread.lock object>
shutdown()

Cleanup used resources.

submit(connection_observer)

Submit connection observer to background execution. Returns Future that could be used to await for connection_observer done.

timeout_change(timedelta)

Call this method to notify runner that timeout has been changed in observer :param timedelta: delta timeout in float seconds :return: None

wait_for(connection_observer, connection_observer_future, timeout=None)

Await for connection_observer running in background or timeout.

Parameters:
  • connection_observer – The one we are awaiting for.
  • connection_observer_future – Future of connection-observer returned from submit().
  • timeout – Max time (in float seconds) to await before give up. If None then taken from connection_observer
Returns:

wait_for_iterator(connection_observer, connection_observer_future)

Version of wait_for() intended to be used by Python3 to implement awaitable object.

Note: we don’t have timeout parameter here. If you want to await with timeout please do use asyncio machinery. For ex.: await asyncio.wait_for(connection_observer, timeout=10)

Parameters:
  • connection_observer – The one we are awaiting for.
  • connection_observer_future – Future of connection-observer returned from submit().
Returns:

iterator

class moler.asyncio_runner.LoudEventLoop(*args)

Bases: asyncio.unix_events._UnixSelectorEventLoop

stop()

Stop running the event loop.

Every callback already scheduled will still run. This simply informs run_forever to stop looping after a complete iteration.

class moler.asyncio_runner.LoudEventLoopPolicy

Bases: asyncio.unix_events._UnixDefaultEventLoopPolicy

moler.asyncio_runner.cancel_remaining_feeders(loop, logger_name='moler.runner.asyncio', in_shutdown=False)
moler.asyncio_runner.check_system_resources_limit(connection_observer, observer_lock, logger)
moler.asyncio_runner.cleanup_remaining_tasks(loop, logger)
moler.asyncio_runner.cleanup_selected_tasks(tasks2cancel, loop, logger)
moler.asyncio_runner.feeder_callback(future)

Used to recognize asyncio task as AsyncioRunner feeder

moler.asyncio_runner.get_asyncio_loop_thread()
moler.asyncio_runner.handle_cancelled_feeder(connection_observer, observer_lock, subscribed_data_receiver, logger, future)
moler.asyncio_runner.is_feeder(task)

We recognize asyncio task to be feeder if it has feeder_callback attached

moler.asyncio_runner.system_resources_usage()
moler.asyncio_runner.system_resources_usage_msg(curr_fds_open, curr_threads_nb)
moler.asyncio_runner.thread_secure_get_event_loop(logger_name='moler.runner.asyncio')

Need securing since asyncio.get_event_loop() when called from new thread may raise sthg like: RuntimeError: There is no current event loop in thread ‘Thread-3’ It is so since MainThread has preinstalled loop but other threads must setup own loop by themselves.

Returns:loop of current thread + info if it was newly created

moler.command module

Command is a type of ConnectionObserver. Additionally: - it starts by sending command string over connection - starting CMD(*) - it focuses on parsing the output caused by that CMD - it stores string starting that CMD inside .command_string attribute

(*) we use naming CMD to differentiate from Command class naming: - CMD - command started on some device like ‘ls -l’ that has its own output - Command - Python code automating its startup/parsing/completion

class moler.command.Command(connection=None, runner=None)

Bases: moler.connection_observer.ConnectionObserver

get_long_desc()
get_short_desc()
is_command()
Returns:True if instance of ConnectionObserver is a command. False if not a command.
send_command()

Sends command string over connection.

Returns:None

moler.command_scheduler module

Scheduler for commands and events.

class moler.command_scheduler.CommandScheduler

Bases: object

Scheduler for commands and events.

static dequeue_running_on_connection(connection_observer)

Remove command from queue and/or current executed on connection.

Parameters:connection_observer – Command object to remove from connection
Returns:None
static enqueue_starting_on_connection(connection_observer)

Wait for free slot and runs command when no other command is in run mode.

If connection_observer is not a command then runs immediately. :param connection_observer: Object of ConnectionObserver to run. Maybe a command or an observer. :return: None

static is_waiting_for_execution(connection_observer)

Check if connection_observer waits in queue before passed to runner.

Parameters:connection_observer – ConnectionObserver object.
Returns:True if connection_observer waits in queue and False if it does not wait.

moler.connection module

moler.connection_factory module

One of Moler’s goals is to be IO-agnostic. So it can be used under twisted, asyncio, curio any any other IO system.

Moler’s connection is very thin layer binding Moler’s ConnectionObserver with external IO system. Connection responsibilities: - have a means for sending outgoing data via external IO - have a means for receiving incoming data from external IO - perform data encoding/decoding to let external IO use pure bytes - have a means allowing multiple observers to get it’s received data (data dispatching)

class moler.connection_factory.ConnectionFactory

Bases: object

ConnectionFactory creates plugin-system: external code can register “construction recipe” that will be used to create specific connection.

“Construction recipe” means: class to be used or any other callable that can produce instance of connection.

Specific means type/variant pair. Type is: memory, tcp, udp, ssh, … Variant is: threaded, asyncio, twisted, …

Connection means here: external-IO-connection + moler-connection. Another words - fully operable connection doing IO and data dispatching, ready to be used by ConnectionObserver.

ConnectionFactory responsibilities: - register “recipe” how to build given type/variant of connection - return connection instance created via utilizing registered “recipe”

classmethod available_variants(io_type)

Return variants available for given io_type

Parameters:io_type – ‘tcp’, ‘memory’, ‘ssh’, …
Returns:list of variants, ex. [‘threaded’, ‘twisted’]
classmethod get_connection(io_type, variant, **constructor_kwargs)

Return connection instance of given io_type/variant

Parameters:
  • io_type – ‘tcp’, ‘memory’, ‘ssh’, …
  • variant – implementation variant, ex. ‘threaded’, ‘twisted’, ‘asyncio’, …
  • constructor_kwargs – arguments specific for given io_type
Returns:

requested connection

classmethod register_construction(io_type, variant, constructor)

Register constructor that will return “connection construction recipe”

Parameters:
  • io_type – ‘tcp’, ‘memory’, ‘ssh’, …
  • variant – implementation variant, ex. ‘threaded’, ‘twisted’, ‘asyncio’, …
  • constructor – callable building connection object
Returns:

None

moler.connection_factory.get_connection(name=None, io_type=None, variant=None, **constructor_kwargs)

Return connection instance of given io_type/variant

Parameters:
  • name – name of connection defined in configuration
  • io_type – ‘tcp’, ‘memory’, ‘ssh’, …
  • variant – implementation variant, ex. ‘threaded’, ‘twisted’, ‘asyncio’, …
  • constructor_kwargs – arguments specific for given io_type
Returns:

requested connection

You may provide either ‘name’ or ‘io_type’ but not both. If you provide ‘name’ then it is searched inside configuration to find io_type and constructor_kwargs assigned to that name.

If variant is not given then it is taken from configuration.

moler.connection_observer module

class moler.connection_observer.ConnectionObserver(connection=None, runner=None)

Bases: object

await_done(timeout=None)

Await completion of connection-observer.

CAUTION: if you call it from asynchronous code (async def) you may block events loop for long time. You should rather await it via: result = await connection_observer or (to have timeout) result = await asyncio.wait_for(connection_observer, timeout=10) or you may delegate blocking call execution to separate thread, see: https://pymotw.com/3/asyncio/executors.html

Parameters:timeout
Returns:observer result
cancel()

Cancel execution of connection-observer.

cancelled()

Return True if the connection-observer has been cancelled.

connection_closed_handler()

Called by Moler (ThreadedMolerConnection) when connection is closed.

Returns:None
data_received(data, recv_time)

Entry point where feeders pass data read from connection Here we perform data parsing to conclude in result setting.

Parameters:
  • data – List of strings sent by device.
  • recv_time – time stamp with the moment when the data was read from connection. Time is given as datetime.datetime instance.
Returns:

None.

done()

Return True if the connection-observer is already done.

extend_timeout(timedelta)
get_logger_name()
get_long_desc()
get_short_desc()
static get_unraised_exceptions(remove=True)
is_command()
Returns:True if instance of ConnectionObserver is a command. False if not a command.
observer_name = 'connection_observer'
on_inactivity()

Callback called when no data is received on connection within self.life_status.inactivity_timeout seconds

Returns:None
on_timeout()

Callback called when observer times out

result()

Retrieve final result of connection-observer

running()

Return True if the connection-observer is currently executing.

set_end_of_life()

Set end of life of object. Dedicated for runners only!

Returns:None
set_exception(exception)

Should be used to indicate some failure during observation.

Parameters:exception – Exception to set
Returns:None
set_result(result)

Should be used to set final result

start(timeout=None, *args, **kwargs)

Start background execution of connection-observer.

start_time
terminating_timeout
timeout

moler.event module

class moler.event.Event(connection=None, till_occurs_times=-1, runner=None)

Bases: moler.connection_observer.ConnectionObserver

add_event_occurred_callback(callback, callback_params=None)
disable_log_occurrence()

Disables to log every occurrence of the event.

Returns:None
enable_log_occurrence()

Enables to log every occurrence of the event.

Returns:None
event_occurred(event_data)

Sets event_data as new item of occurrence ret. :param event_data: data to set as value of occurrence. :return: None

get_last_occurrence()

Returns ret value from last occurrence.

Returns:ret value form last occurrence or None if there is no occurrence.
get_long_desc()

Returns string with description of event.

Returns:String with description.
get_short_desc()

Returns string with description of event.

Returns:String with description.
notify()

Notifies (call callback).

Returns:None
pause()

Pauses the event. Do not process till resume.

Returns:None.
remove_event_occurred_callback()

Removes callback from the event.

Returns:None
resume()

Resumes processing output from connection by the event.

Returns:None.
start(timeout=None, *args, **kwargs)

Start background execution of command.

moler.event_awaiter module

Event awaiter

class moler.event_awaiter.EventAwaiter

Bases: object

static cancel_all_events(events)
Parameters:events – list of events to cancel
Returns:None
static separate_done_events(events)
Parameters:events – list of events to check and separate
Returns:tuple. 0th element is list of done events, 1st element is list of non done events
static wait_for_all(timeout, events, interval=0.001)

Wait for all events are done or timeout occurs :param timeout: time in seconds :param events: list of events to check :param interval: interval in seconds between checking events :return: True if all events are done, False otherwise

static wait_for_any(timeout, events, interval=0.001)
Parameters:
  • timeout – time in seconds
  • events – list of events to check
  • interval – interval in seconds between checking events
Returns:

True if any event is done, False otherwise

moler.exceptions module

exception moler.exceptions.CancelledError

Bases: moler.exceptions.MolerException

exception moler.exceptions.CommandFailure(command, message)

Bases: moler.exceptions.MolerException

exception moler.exceptions.CommandTimeout(connection_observer, timeout, kind='run', passed_time='')

Bases: moler.exceptions.ConnectionObserverTimeout

exception moler.exceptions.CommandWrongState(command, expected_state, current_state)

Bases: moler.exceptions.MolerException

exception moler.exceptions.ConnectionObserverNotStarted(connection_observer)

Bases: moler.exceptions.InvalidStateError

exception moler.exceptions.ConnectionObserverTimeout(connection_observer, timeout, kind='run', passed_time='')

Bases: moler.exceptions.MolerTimeout

exception moler.exceptions.DeviceChangeStateFailure(device, exception, device_name=None)

Bases: moler.exceptions.DeviceFailure

exception moler.exceptions.DeviceFailure(device, message)

Bases: moler.exceptions.MolerException

exception moler.exceptions.EventWrongState(event, expected_state, current_state)

Bases: moler.exceptions.MolerException

exception moler.exceptions.ExecutionException(msg)

Bases: moler.exceptions.MolerException

exception moler.exceptions.InvalidStateError

Bases: moler.exceptions.MolerException

exception moler.exceptions.MolerException

Bases: Exception

exception moler.exceptions.MolerTimeout(timeout, kind='run', passed_time=0)

Bases: moler.exceptions.MolerException

exception moler.exceptions.NoCommandStringProvided(command)

Bases: moler.exceptions.MolerException

exception moler.exceptions.NoConnectionProvided(connection_observer)

Bases: moler.exceptions.MolerException

exception moler.exceptions.NoDetectPatternProvided(command)

Bases: moler.exceptions.MolerException

exception moler.exceptions.NoResultSinceCancelCalled(connection_observer)

Bases: moler.exceptions.CancelledError

exception moler.exceptions.ParsingDone

Bases: moler.exceptions.MolerException

Indicate that given part of output has been fully parsed and requires no further processing.

exception moler.exceptions.ResultAlreadySet(connection_observer)

Bases: moler.exceptions.InvalidStateError

exception moler.exceptions.ResultNotAvailableYet(connection_observer)

Bases: moler.exceptions.InvalidStateError

exception moler.exceptions.WrongUsage

Bases: moler.exceptions.MolerException

Wrong usage of library

moler.helpers module

Utility/common code of library.

class moler.helpers.ClassProperty

Bases: property

class moler.helpers.ForwardingHandler(target_logger_name)

Bases: logging.Handler

Take log record and pass it to target_logger

emit(record)

Emit a record.

Output the record to the target_logger, catering for rollover as described in doRollover().

moler.helpers.all_chars_to_hex(source)

Converts input string into hex for all chars. :param source: input string. :return: output string witch exchanged chars.

moler.helpers.call_base_class_method_with_same_name(obj)

Run base class method.

Parameters:obj – class object which methods will be decorated.
Returns:class object with decorated methods
moler.helpers.camel_case_to_lower_case_underscore(string)

Split string by upper case letters. F.e. useful to convert camel case strings to underscore separated ones. @return words (list)

moler.helpers.compare_objects(first_object, second_object, ignore_order=False, report_repetition=False, significant_digits=None, exclude_paths=None, exclude_types=None, verbose_level=2)

Return difference between two objects. :param first_object: first object to compare :param second_object: second object to compare :param ignore_order: ignore difference in order :param report_repetition: report when is repetition :param significant_digits: use to properly compare numbers(float arithmetic error) :param exclude_paths: path which be excluded from comparison :param exclude_types: types which be excluded from comparison :param verbose_level: higher verbose level shows you more details - default 0. :return: difference between two objects

moler.helpers.convert_to_int(obj)

Convert element of object structure to int if it’s possible. :param obj: object to convert

moler.helpers.convert_to_number(value)

Convert value to Python number type. :param value: value to convert :return: converted value if possible, otherwise original

moler.helpers.copy_dict(src, deep_copy=False)

Copies dict, if None then returns empty dict :param src: List to copy :param deep_copy: if False then shallow copy, if True then deep copy :return: Copied dict

moler.helpers.copy_list(src, deep_copy=False)

Copies list, if None then returns empty list :param src: List to copy :param deep_copy: if False then shallow copy, if True then deep copy :return: Copied list

moler.helpers.create_object_from_name(full_class_name, constructor_params)
moler.helpers.instance_id(instance)

Return id of instance in hex form. Helps in logs/debugs/development troubleshooting.

moler.helpers.is_digit(value)

Check that value is digit. :param value: value to check :return: True if value is digit, otherwise False

moler.helpers.mark_to_call_base_class_method_with_same_name(func)

Mark method which base class method with same name will be call. :param func: function to mark. :return: marked function

moler.helpers.non_printable_chars_to_hex(source)

Converts input string into hex for all non printable chars, printable chars remain unchanged. :param source: input string. :return: output string witch exchanged chars.

moler.helpers.regexp_without_anchors(regexp)

Remove anchors from beginning (^) and ending ($) of the regexp. :param regexp: compiled regexp :return: compiled regexp without anchors

moler.helpers.remove_all_known_special_chars(line)
Parameters:line – line from terminal
Returns:line without all known special chars
moler.helpers.remove_cursor_visibility_codes(multiline)
Parameters:multiline – string from terminal holding single or multiple lines
Returns:line(s) without terminal escape codes related to cursor visibility
moler.helpers.remove_escape_codes(line)
Parameters:line – line from terminal
Returns:line without terminal escape codes
moler.helpers.remove_fill_spaces_right_codes(multiline)
Parameters:multiline – string from terminal holding single or multiple lines
Returns:line(s) without spaces added till right VT-screen margin
moler.helpers.remove_overwritten_left_write(multiline)
Parameters:multiline – string from terminal holding single or multiple lines
Returns:line without spaces added till right VT-screen margin
moler.helpers.remove_terminal_last_cmd_status(line)
Parameters:line – line from terminal
Returns:line without terminal last cmd status
moler.helpers.remove_text_formatting_codes(multiline)
Parameters:multiline – string from terminal holding single or multiple lines
Returns:line(s) without terminal escape codes related to text formatting
moler.helpers.remove_window_title_codes(multiline)
Parameters:multiline – string from terminal holding single or multiple lines
Returns:line(s) without terminal escape codes setting console window/icon title
moler.helpers.update_dict(target_dict, expand_dict)

moler.instance_loader module

moler.instance_loader.create_class_instance(class_object, constructor_params)

Factory method that creates class instance object according to its definition given in parameters.

Parameters:
  • class_object – class object to be instantiated
  • constructor_params – to be passed into instance constructor
Returns:

instance of requested class

moler.instance_loader.create_instance_from_class_fullname(class_fullname, constructor_parameters)

Factory method that creates class instance object according to its definition given in parameters.

Parameters:
  • class_fullname – full name of class in dotted notation like ‘package1.module1.ClassName1’
  • constructor_parameters – to be passed into instance constructor
Returns:

instance of requested class

moler.instance_loader.load_class_from_class_fullname(class_fullname)

Factory method that loads class object according to its fullname.

Parameters:class_fullname – full name of class in dotted notation like ‘package1.module1.ClassName1’
Returns:requested class object

moler.observable_connection module

One of Moler’s goals is to be IO-agnostic. So it can be used under twisted, asyncio, curio any any other IO system.

Moler’s connection is very thin layer binding Moler’s ConnectionObserver with external IO system. Connection responsibilities: - have a means for sending outgoing data via external IO - have a means for receiving incoming data from external IO - perform data encoding/decoding to let external IO use pure bytes - have a means allowing multiple observers to get it’s received data (data dispatching)

class moler.observable_connection.ObservableConnection(*args, **kwargs)

Bases: moler.threaded_moler_connection.ThreadedMolerConnection

moler.observer_thread_wrapper module

Wrapper for observer registered in ThreadedMolerConnection (old name: ObservableConnection).

class moler.observer_thread_wrapper.ObserverThreadWrapper(observer, observer_self, logger)

Bases: object

Wrapper for observer registered in ThreadedMolerConnection (old name: ObservableConnection).

feed(data, recv_time)

Put data here.

Parameters:
  • data – data to put.
  • recv_time – time when data is received/read from connection.
Returns:

None

request_stop()

Call if you want to stop feed observer.

Returns:None
class moler.observer_thread_wrapper.ObserverThreadWrapperForConnectionObserver(observer, observer_self, logger)

Bases: moler.observer_thread_wrapper.ObserverThreadWrapper

moler.publisher module

Moler implementation of Publisher-Subscriber Design Pattern.

Main characteristic: - allow Subscribers to be garbage collected while still subscribed inside Publisher

This is required since: - both parties may exist in different threads - both parties may keep references to themselves creating reference cycles

class moler.publisher.Publisher

Bases: object

Allows objects to subscribe for notification about data.

Subscription is made by registering function to be called with this data (may be object’s method). Function should have signature like:

def subscriber(data):
# handle that data
handle_subscriber_exception(subscriber_owner, subscriber_function, raised_exception)

Handle exception raised by subscriber during publishing.

Parameters:
  • subscriber_owner – instance of class whose method was subscribed (or None)
  • subscriber_function – subscribed class method or raw function
  • raised_exception – exception raised by subscriber during publishing
Returns:

None

notify_subscribers(*args, **kwargs)

Notify all subscribers passing them notification parameters.

subscribe(subscriber)

Subscribe for ‘data notification’.

Parameters:subscriber – function to be called to notify about data.
unsubscribe(subscriber)

Unsubscribe from ‘data notification’.

Parameters:subscriber – function that was previously subscribed

moler.runner module

Runner abstraction goal is to hide concurrency machinery used to make it exchangeable (threads, asyncio, twisted, curio)

class moler.runner.CancellableFuture(future, observer_lock, stop_running, is_done, stop_timeout=0.5)

Bases: object

cancel(no_wait=False)

Cancel embedded future :param no_wait: if True - just set self._stop_running event to let thread exit loop :return:

class moler.runner.ConnectionObserverRunner

Bases: object

feed(connection_observer)

Feeds connection_observer with data to let it become done. This is a place where runner is a glue between words of connection and connection-observer. Should be called from background-processing of connection observer.

is_in_shutdown()

Call this method to check if runner is in shutdown mode. :return: Is in shutdown

shutdown()

Cleanup used resources.

submit(connection_observer)

Submit connection observer to background execution. Returns Future that could be used to await for connection_observer done.

timeout_change(timedelta)

Call this method to notify runner that timeout has been changed in observer :param timedelta: delta timeout in float seconds :return: None

wait_for(connection_observer, connection_observer_future, timeout=10.0)

Await for connection_observer running in background or timeout.

Parameters:
  • connection_observer – The one we are awaiting for.
  • connection_observer_future – Future of connection-observer returned from submit().
  • timeout – Max time (in float seconds) you want to await before you give up.
Returns:

wait_for_iterator(connection_observer, connection_observer_future)

Version of wait_for() intended to be used by Python3 to implement iterable/awaitable object.

Note: we don’t have timeout parameter here. If you want to await with timeout please do use timeout machinery of selected parallelism.

Parameters:
  • connection_observer – The one we are awaiting for.
  • connection_observer_future – Future of connection-observer returned from submit().
Returns:

iterator

class moler.runner.ThreadPoolExecutorRunner(executor=None)

Bases: moler.runner.ConnectionObserverRunner

feed(connection_observer, subscribed_data_receiver, stop_feeding, feed_done, observer_lock)

Feeds connection_observer by transferring data from connection and passing it to connection_observer. Should be called from background-processing of connection observer.

is_in_shutdown()

Call this method to check if runner is in shutdown mode. :return: Is in shutdown

shutdown()

Cleanup used resources.

submit(connection_observer)

Submit connection observer to background execution. Returns Future that could be used to await for connection_observer done.

timeout_change(timedelta)

Call this method to notify runner that timeout has been changed in observer :param timedelta: delta timeout in float seconds :return: None

wait_for(connection_observer, connection_observer_future, timeout=None)

Await for connection_observer running in background or timeout.

Parameters:
  • connection_observer – The one we are awaiting for.
  • connection_observer_future – Future of connection-observer returned from submit().
  • timeout – Max time (in float seconds) you want to await before you give up. If None then taken from connection_observer
Returns:

wait_for_iterator(connection_observer, connection_observer_future)

Version of wait_for() intended to be used by Python3 to implement iterable/awaitable object.

Note: we don’t have timeout parameter here. If you want to await with timeout please do use timeout machinery of selected parallelism.

Parameters:
  • connection_observer – The one we are awaiting for.
  • connection_observer_future – Future of connection-observer returned from submit().
Returns:

iterator

moler.runner.await_future_or_eol(connection_observer, remain_time, start_time, timeout, logger)
moler.runner.his_remaining_time(prefix, timeout, from_start_time)

Calculate remaining time of “he” object assuming that “he” has .life_status.start_time attribute

Parameters:
  • prefix – string to be used inside ‘remaining time description’
  • timeout – max lifetime of object
  • from_start_time – start of lifetime for the object
Returns:

remaining time as float and related description message

moler.runner.result_for_runners(connection_observer)

When runner takes result from connection-observer it should not modify ConnectionObserver._not_raised_exceptions

Parameters:connection_observer – observer to get result from
Returns:result or raised exception
moler.runner.time_out_observer(connection_observer, timeout, passed_time, runner_logger, kind='background_run')

Set connection_observer status to timed-out

moler.runner_factory module

Runner abstraction goal is to hide concurrency machinery used to make it exchangeable (threads, asyncio, twisted, curio)

class moler.runner_factory.RunnerFactory

Bases: object

RunnerFactory creates plugin-system: external code can register “construction recipe” that will be used to create specific runner.

“Construction recipe” means: class to be used or any other callable that can produce instance of runner.

Specific means runner variant like: threaded, asyncio, twisted, …

ConnectionFactory responsibilities: - register “recipe” how to build given variant of runner - return runner instance created via utilizing registered “recipe”

classmethod available_variants()

Return available variants of runners

Returns:list of variants, ex. [‘threaded’, ‘twisted’]
classmethod get_runner(variant, reuse_last=True, **constructor_kwargs)

Return runner instance of given variant

Parameters:
  • variant – implementation variant, ex. ‘threaded’, ‘twisted’, ‘asyncio’, …
  • reuse_last – should we return cached last runner of given variant
  • constructor_kwargs – arguments specific for given variant
Returns:

requested runner

classmethod register_construction(variant, constructor)

Register constructor that will return “runner construction recipe”

Parameters:
  • variant – implementation variant, ex. ‘threaded’, ‘twisted’, ‘asyncio’, …
  • constructor – callable building runner object
Returns:

None

moler.runner_factory.get_runner(variant=None, reuse_last=True, **constructor_kwargs)

Return runner instance of given variant

Parameters:
  • variant – implementation variant, ex. ‘threaded’, ‘twisted’, ‘asyncio’, …
  • reuse_last – should we return cached last runner of given variant
  • constructor_kwargs – arguments specific for given variant
Returns:

requested runner

If variant is not given then it is taken from configuration.

moler.scheduler module

class moler.scheduler.DecoratedCallable(callback, cancel_on_exception)

Bases: object

call(**kwargs)
class moler.scheduler.Job(job)

Bases: object

cancel()

Method to stop the job :return: None

start()

Method to start the job. :return: None

class moler.scheduler.MolerAsyncioScheduler(gconfig={}, **options)

Bases: apscheduler.schedulers.asyncio.AsyncIOScheduler

forwarding_handler = None
class moler.scheduler.MolerThreadScheduler(gconfig={}, **options)

Bases: apscheduler.schedulers.background.BackgroundScheduler

forwarding_handler = None
class moler.scheduler.Scheduler(scheduler_type=None)

Bases: object

static change_kind(scheduler_type=None)

Static method to change type of scheduler :param scheduler_type: type of new scheduler. Allowed thread (default) or asyncio. If None then default multi

threading model will be used.
Returns:None. If scheduler_type is not supported then it raises object of type moler.exceptions.WrongUsage
static get_job(callback, interval, callback_params=None, cancel_on_exception=False, misfire_grace_time=0)

Static method to create job. :param callback: Reference to callable object (i.e. function, method) :param interval: time in float seconds when fun is called. If time of one execution is longer than interval then

some callbacks are missed. For example: interval is 2s and time of execution is 3s then callback will be called when job ios created after 2s, after 4s will not be executed because still the first excection is running, then after 6s of is called.
Parameters:
  • callback_params – dict of params of fun
  • cancel_on_exception – set True if you want to break next execution of this callback if previous raises an exception
  • misfire_grace_time (int) – seconds after the designated runtime that the job is still allowed to be run
Returns:

Instance of Job.

moler.threaded_moler_connection module

One of Moler’s goals is to be IO-agnostic. So it can be used under twisted, asyncio, curio any any other IO system.

Moler’s connection is very thin layer binding Moler’s ConnectionObserver with external IO system. Connection responsibilities: - have a means for sending outgoing data via external IO - have a means for receiving incoming data from external IO - perform data encoding/decoding to let external IO use pure bytes - have a means allowing multiple observers to get it’s received data (data dispatching)

class moler.threaded_moler_connection.ThreadedMolerConnection(how2send=None, encoder=<function identity_transformation>, decoder=<function identity_transformation>, name=None, newline='n', logger_name='')

Bases: moler.abstract_moler_connection.AbstractMolerConnection

Allows objects to subscribe for notification about connection’s data-received. Subscription is made by registering function to be called with this data (may be object’s method). Function should have signature like:

def observer(data):
# handle that data
data_received(data, recv_time)

Incoming-IO API: external-IO should call this method when data is received

notify_observers(data, recv_time)

Notify all subscribed observers about data received on connection. :param data: data to send to all registered subscribers. :param recv_time: time of data really read form connection. :return None

shutdown()

Closes connection with notifying all observers about closing. :return: None

subscribe(observer, connection_closed_handler)

Subscribe for ‘data-received notification’

Parameters:
  • observer – function to be called to notify when data received.
  • connection_closed_handler – callable to be called when connection is closed.
unsubscribe(observer, connection_closed_handler)

Unsubscribe from ‘data-received notification’ :param observer: function that was previously subscribed :param connection_closed_handler: callable to be called when connection is closed.

Module contents