Interpreter
Introduction
The Interpreter module provides a framework for executing Exelent files. It acts as an abstract class to unify various execution layer managers. This guide will demonstrate how to use the interpreter with ROSA as an example interpreter, the same applies for later implementations such as Pyxcel.
Functionalities Overview
All interpreters are located in the ecm/mediator directory. For this example, we will import the RosaInterpreter as follows:
from ecm.mediator.rosa_interpreter import RosaInterpreter, RosaInterpreterSupports
Each interpreter defines a support class that specifies its capabilities. You can visualize the supported properties with the following command:
print(RosaInterpreterSupports())
The core functionality of interpreters is provided by the methods they implement. While interpreters can define additional methods, the predefined ones include:
run
: Receives a ParsedTask object and executes it from start to finish. It may also accept a callback argument to define a function for receiving execution feedback.arun
: Receives a ParsedTask object and executes it asynchronously, accepting a callback argument for feedback.stop
: Stops a running task by its name.hard_stop
: Forcefully stops a running task by its name (use with caution as it may have undesirable effects).wait_for
: Waits for a specific call from the task, such as a status change or task completion.kill
: Closes the interpreter (does not ensure it is capable to be used again in the same process)
Using the Interpreter
To use the RosaInterpreter, first initialize it:
from ecm.mediator.rosa_interpreter import RosaInterpreter
interpreter = RosaInterpreter()
To execute a task, use the run
method. You need to parse an Exelent file with the actions to execute. Optionally, you can provide a callback function to handle task feedback. The callback implementation specifics are documented by the selected interpreter. For this example, we will use the hello_world file found in /tests/resources/hello_world.xlnt.
# This is the .xlnt file
def my_task():
with Sequential(on_fail=DUMP_LOGS):
with Sequential():
click("windows_icon")
click("notepad")
with Sequential():
click("window")
write("Hello World!")
This file defines two actions: click and write. You need to implement these actions before executing the task:
from ecm.tools.registry import ItemRegistry
# Note that just by registering the function will make it available for all interpreters.
@ItemRegistry.register_function
def click(location: str):
print(f"Clicked {location}!")
@ItemRegistry.register_function
def write(text: str):
print(text)
With the Exelent file and the tools set up, you are ready to execute the task:
import ecm.exelent.parser as parser
from ecm.shared import get_root_path
path = get_root_path() / "tests" / "resources" / "hello_world.xlnt"
task = parser.parse(path)
interpreter.run(task, callback="silent")
In this example, we pass the "silent" keyword to the callback. Each interpreter may support different keywords or objects.
>>> interpreter.run(task, callback="silent")
Clicked windows_icon!
Clicked notepad!
Clicked window!
Hello World!
After you have finished using the interpreter, some implementations require cleanup. Therefore, it is good practice to terminate the interpreter.
interpreter.kill()
Conclusion
By following this guide, you now have a foundational understanding of how to utilize the Interpreter module to execute tasks parsed by the Exelent Parser. This knowledge will allow you to manage and control task execution within your projects effectively. Remember to clean up by terminating the interpreter when it's no longer needed to maintain system integrity. Happy coding!