Aiviro Utilities

The section is a hub for essential tools like constants, methods, and classes. It’s sorted into different categories, each handling specific tasks like spatial objects, logging, parameter controls, constants, keyboard and exceptions. These tools are vital for different functions within the Aiviro package.

Area & Text

class aiviro.Area(x_min: int, y_min: int, x_max: int, y_max: int)

Rectangular area defined in x and y axes.

Parameters:
  • x_min – Lower x-axis coordinate.

  • y_min – Lower y-axis coordinate.

  • x_min – Upper x-axis coordinate.

  • y_min – Upper y-axis coordinate.

Example:

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> r.add_mask(aiviro.Area(750, 850, 1100, 950))
class aiviro.BoundBox(x_min: int, y_min: int, x_max: int, y_max: int, label: AiviroCoreElementLabels = AiviroCoreElementLabels.DEFAULT, score: float = 0.0, extra: Dict | None = None)

Bounding box, object returned after finding an element.

Example:

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> box = r.get(
...     aiviro.Text(r"^\d\d\.\d\d\.\d\d\d\d$", aiviro.find_method.REGEX),
... )
>>> box.text
'13.11.2020'
>>> box.normalized_text
'13 . 11 . 2020'
>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> or_box = r.get(
...     aiviro.Or(aiviro.Text("not-found"), aiviro.Text("found"))
... )
>>> or_box.or_index
1
class aiviro.Secret(value: str | Secret)

Holds a string value that should not be revealed in logs, tracebacks, etc. To retrieve the value use the str() function.

Example:

>>> Secret("some string")
Secret('********')
>>> str(Secret("some string"))
some string

Note

If you use print() (or its variants) directly with this object it is automatically cast to str(), so it will display the secret value. Use cast repr() to avoid this functionality.

Logging

All logging methods can be accessed by aiviro.* notation.

logging.init_logging(config_file: GlobalConfig | None = None) LoggingContext

Initialize Aiviro logging.

Parameters:
  • log_folder – Path to the folder where logs will be stored. If not specified, the default folder based on the configuration will be used.

  • config_file – GlobalConfig instance. If not specified, the default configuration will be used.

Returns:

LoggingContext instance, which can be used to add additional handlers

Example:

>>> import aiviro
>>> if __name__ == "__main__":
>>>     aiviro.init_logging()
>>>     # some code
>>> import aiviro
>>> from typing import List
>>> from logging import StreamHandler, DEBUG, Filter, LogRecord
>>>
>>> class LoggerNameFilter(Filter):
...     def __init__(self, loggers_name: List[str]):
...         super().__init__()
...         self._loggers_name = loggers_name
...
...     def filter(self, record: LogRecord) -> bool:
...         return record.name in self._loggers_name
...
>>> if __name__ == "__main__":
>>>     l_ctx = aiviro.init_logging()
>>>
>>>     # you can add additional handlers, for example
>>>     # this handler will print only logs from specified loggers to stdout
>>>     stdout_handler = StreamHandler(stream=sys.stdout)
>>>     stdout_handler.setLevel(DEBUG)
>>>     stdout_handler.addFilter(
...         LoggerNameFilter([
...             "aiviro.module.pdf.robot",
...             "aiviro.core.find.GetElements",
...             "aiviro.core.services.SearchObjectService",
...         ])
...     )
>>>     # add handler to the main aiviro logger
>>>     main_logger = l_ctx.main_logger
>>>     main_logger.addHandler(stdout_handler)
logging.stop_logging()

Stop logging and close all handlers.

logging.get_logger() Logger

Get an ‘aiviro’ logger with the specified name.

Parameters:

name – Name of the logger. For aiviro logger the name must start with aiviro.. Otherwise, the logger won’t be a child of the aiviro logger.

Returns:

Logger with the specified name.

Example:

>>> import aiviro
>>> logger = aiviro.get_logger("scenario.module")
>>> logger.info("This is info message")
>>> print(logger.name)
aiviro.scenario.module
logging.get_logger_advanced(robot_id: str = '') AiviroLoggerAdapter

Get an advanced logger, containing robot_id and other information. The logger supports providing images and data to the log message.

Parameters:
  • name – Name of the logger. Internally get_logger() is used to get the logger.

  • robot_id – Robot ID, which will be added to every log message.

Example:

>>> import aiviro
>>> from aiviro.core.utils.file_utils import load_image
>>> logger = aiviro.get_logger_advanced("aiviro.scenario.module")
>>> np_image = load_image("path/to/image.png")
>>> logger.info("This is info message", image=np_image)
>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> boxes = r.get(aiviro.Text("some text"))
>>> logger.info("Found boxes", data=boxes)
logging.disable_logger() Generator

Get a context manager which disables the logger with the specified name Upon exiting the context manager, the logger will be enabled again.

Parameters:

name – Name of the logger to disable. Internally get_logger() is used to get the logger.

logging.log_prefect_markdown_text() None

Method will add text in Markdown format into prefect artifact.

Parameters:

markdown_text – Text in Markdown format.

Example:

>>> import aiviro
>>> md_text = "## Title\nLooooong text"
>>> aiviro.log_prefect_markdown_text(md_text)

Control Parameters

class aiviro.core.constants.ui_constants.FindMethod(value)

Different methods to process texts can be used with the alias aiviro.find_method.

Example:

>>> import aiviro
>>> aiviro.Button("Log in", aiviro.find_method.EQUAL)
>>> aiviro.Text(r"^\d\d$", aiviro.find_method.REGEX)
>>> aiviro.Button("OK", aiviro.find_method.EQUAL.CASE_INSENSITIVE)
>>> aiviro.Text(
...     "Total",
...     aiviro.find_method.EQUAL.EXCLUSIVE.CASE_INSENSITIVE
... )
>>> import aiviro
>>> from typing import Tuple
>>> def my_text_normalization(ocr_text: str) -> str:
...     return ocr_text.replace("O", "0")
...
>>> aiviro.user_config.text_normalization = my_text_normalization
>>> aiviro.Text(r"^\d+$", aiviro.find_method.REGEX.USER_NORMALIZATION)
EQUAL = 1

Comparison of text is based on equality. Texts have to be equal with every character to pass

SUBSTRING = 2

Comparison of text is based on substring equality. Text has to be equal to a substring with every character to pass

SIMILAR = 4

Comparison of text is based on their respective similarity. The texts can have minor changes and still pass.

REGEX = 8

Comparison of text is based on regular expression. Text has to exactly match the regular expression to pass.

CASE_INSENSITIVE = 16

Comparison of text is case-insensitive. This option is ignored for REGEX.

EXCLUSIVE = 32

Find elements that contain only the specified text and nothing else. Can be combined with any other comparison method.

GLOBAL = 64

Returns all occurences in line not only the first one.

USER_NORMALIZATION = 128

Apply user’s normalization for text. See UserConfig for more information. Can be combined with any other comparison method.

class aiviro.core.utils.search_objects.TableAnchor(value)

Table anchors can be used with the alias aiviro.table_anchor. It defines which anchor of the element should be used for finding Above or Below elements.

Example:

>>> import aiviro
>>> aiviro.Below(
...     aiviro.Text(r'^\d\w\d$', aiviro.find_method.REGEX),
...     aiviro.Text("Column-header"),
...     aiviro.table_anchor.RIGHT
... )
>>> aiviro.Below(
...     aiviro.Text(""),
...     aiviro.Text("Records on the right"),
...     aiviro.table_anchor.RIGHT.THRESHOLD
... )
>>> aiviro.Below(
...     aiviro.RegexText(r"\d{8}"),
...     aiviro.Text("Customer No."),
...     aiviro.table_anchor.MIDDLE.DISTANCE
... )
LEFT = 1

The distance between the most left point of reference and other objects is calculated, based on x-axis, to find the closest elements.

RIGHT = 2

The distance between the most right points of reference and other objects is calculated, based on x-axis, to find the closest elements.

MIDDLE = 4

The distance between the middle point of reference and other objects is calculated, based on x-axis, to find the closest elements.

DISTANCE = 8

The distance option must be used with a LEFT, RIGHT, MIDDLE option, it calculates the distance between reference and other objects based on both axis.

THRESHOLD = 16

The threshold is applied for distance between reference and searching object, it finds strictly aligned objects, based on the selected anchor

NONE = 32

All elements Below or Above from reference object are found.

class aiviro.core.constants.ui_constants.LayoutAnchor(value)

Anchor positions can be used with the alias aiviro.layout_anchor.

Example:

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> r.check_are_in_column(  # elements are in column with alignment on the left
...     aiviro.Input("Username"),
...     aiviro.Input("Password"),
...     anchor=aiviro.layout_anchor.LEFT
... )
LEFT = 'LEFT'

Use left points of bounding boxes as anchor points

RIGHT = 'RIGHT'

Use right points of bounding boxes as anchor points

MIDDLE = 'MIDDLE'

Use center points of bounding boxes as anchor points

TOP = 'TOP'

Use top points of bounding boxes as anchor points

BOTTOM = 'BOTTOM'

Use bottom points of bounding boxes as anchor points

BOTH = 'BOTH'

Use both left and right or top and bottom points of bounding boxes as anchor points

class aiviro.core.constants.ui_constants.LayoutPositions(value)

Layout positioning can be used with the alias aiviro.layout_positions.

IS_ABOVE = 0

Above a position

IS_BELOW = 1

Below a position

IS_RIGHT_OF = 2

Right of a position

IS_LEFT_OF = 3

Left of a position

class aiviro.core.constants.ui_constants.LayoutComparisonMode(value)

Layout comparison modes can be used with the alias aiviro.layout_comparison_mode.

Example:

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> r.check_is_positioned(  # the whole Button object is below Input field
...     aiviro.Button("Log in"),
...     aiviro.Input("Username"),
...     direction_type=aiviro.layout_positions.IS_BELOW,
...     comparison_mode=aiviro.layout_comparison_mode.WHOLE
... )
WHOLE = 'COMPARISON_WHOLE'

The entire area is strictly in the specified direction from given object

CENTER = 'COMPARISON_CENTER'

The center is in specified direction from the center of the given object

EXTREME = 'COMPARISON_EXTREME'

there is at least one pixel in the specified direction from the given object

class aiviro.core.constants.ui_constants.ScrollOption(value)

Layout positioning can be used with the alias aiviro.scroll_option.

MOUSE_UP = 'up'

Scroll with the mouse up

MOUSE_DOWN = 'down'

Scroll with the mouse down

PAGE_UP = 'page_up'

Use page up as a scroll

PAGE_DOWN = 'page_down'

Use page down as a scroll

class aiviro.core.constants.ui_constants.BoundaryType(value)

Can be used with the alias aiviro.boundary_type.

Example:

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> r.set_working_area(aiviro.BoundaryArea(
...     aiviro.Button("Login"),
...     aiviro.Button("Cancel"),
...     aiviro.boundary_type.DEFAULT
... ))
>>> r.add_mask(aiviro.BoundaryArea(
...     aiviro.Button("Login"),
...     aiviro.Button("Cancel"),
...     aiviro.boundary_type.EXCLUDE_FIRST.RIGHT_EDGE
... ))
DEFAULT = 1

Both boundaries included into the resulting box

RIGHT_EDGE = 2

Expand right side to the edge of the display

TOP_EDGE = 4

Expand top side to the edge of the display

BOTTOM_EDGE = 8

Expand bottom side to the edge of the display

LEFT_EDGE = 16

Expand left side to the edge of the display

EXCLUDE_FIRST_WIDTH = 32

Exclude width of the first boundary (uses right side of the boundary instead of left)

EXCLUDE_FIRST_HEIGHT = 64

Exclude height of the first boundary (uses bottom side of the boundary instead of top)

EXCLUDE_SECOND_WIDTH = 128

Exclude width of the second boundary (uses left side of the boundary instead of right)

EXCLUDE_SECOND_HEIGHT = 256

Exclude height of the second boundary (uses top side of the boundary instead of bottom)

TOP_LEFT_CORNER = 20

Expand boundary to the top left corner of the screen

TOP_RIGHT_CORNER = 6

Expand boundary to the top right corner of the screen

BOTTOM_LEFT_CORNER = 24

Expand boundary to the bottom left corner of the screen

BOTTOM_RIGHT_CORNER = 10

Expand boundary to the bottom right corner of the screen

BOTH_WIDTH = 18

Expand boundary to both vertical sides of the screen

BOTH_HEIGHT = 12

Expand boundary to both horizontal sides of the screen

EXCLUDE_FIRST = 96

Exclude the whole first boundary

EXCLUDE_SECOND = 384

Exclude the whole second boundary

EXCLUDE_BOTH_WIDTH = 160

Exclude width of both boundaries

EXCLUDE_BOTH_HEIGHT = 320

Exclude height of both boundaries

EXCLUDE_BOTH = 480

Exclude both boundaries

class aiviro.core.constants.ui_constants.WorkingAreaLimit(value)

Can be used with the alias aiviro.working_area_limit.

Example:

>>> import aiviro
>>> r = aiviro.create_desktop_robot()
>>> # set some working-area
>>> r.limit_working_area(
...     aiviro.Text("Cancel"),
...     top=aiviro.working_area_limit.MIN,
...     right=aiviro.working_area_limit.MAX
... )
>>> # set another working-area
>>> r.limit_working_area(
...     aiviro.Text("Cancel"),
...     bottom=aiviro.working_area_limit.MAX,
...     right=aiviro.working_area_limit.MIN
... )
MIN = 'min'

Use MIN option for selected axis

MAX = 'max'

Use MAX option for selected axis

Constants

Every constant can be access by aiviro.* notation.

>>> import aiviro
>>> DB_NAME = "production" if aiviro.AIVIRO_DEBUG_VALUE else "testing"
aiviro.core.constants.environment_constants.AIVIRO_DEBUG_KEY = 'AIVIRO_DEBUG'

The name of the environment variable that indicates whether the debug mode is on or off.

aiviro.core.constants.environment_constants.AIVIRO_DEBUG_VALUE = 1

The integer value that indicates whether the debug mode is on or off.

aiviro.core.constants.environment_constants.IS_RUNNING_IN_PREFECT = False

The boolean value that indicates whether script is running in Prefect environment.

aiviro.core.constants.environment_constants.SCENARIO_CONFIG_FOLDER_KEY = 'AIVIRO__CONFIG_FOLDER'

The name of the environment variable that indicates the path to the scenario configuration folder.

aiviro.core.constants.environment_constants.SCENARIO_CONFIG_FOLDER_PATH = None

The path to the folder containing the scenario configuration files.

aiviro.core.utils.locale.LOCALE_KEY = 'AIVIRO__LOCALE'

The name of the environment variable that indicates which localization should be used.

aiviro.core.utils.locale.LOCALE_VALUE = 'cs_CZ'

The value of loaded localization, defaults to “cs_CZ”.

Keyboard

class aiviro.core.services.device.keyboard.BaseKey(value)

can be used with the alias aiviro.key.

ESCAPE = ('escape',)
F1 = ('f1',)
F2 = ('f2',)
F3 = ('f3',)
F4 = ('f4',)
F5 = ('f5',)
F6 = ('f6',)
F7 = ('f7',)
F8 = ('f8',)
F9 = ('f9',)
F10 = ('f10',)
F11 = ('f11',)
F12 = ('f12',)
GRAVE = ('`',)
KEY_1 = ('1',)
KEY_2 = ('2',)
KEY_3 = ('3',)
KEY_4 = ('4',)
KEY_5 = ('5',)
KEY_6 = ('6',)
KEY_7 = ('7',)
KEY_8 = ('8',)
KEY_9 = ('9',)
KEY_0 = ('0',)
MINUS = ('-',)
EQUAL = ('=',)
DOUBLE_HYPHEN = ('=',)
BACKSPACE = ('\x08',)
TAB = ('\t',)
KEY_Q = ('q',)
KEY_W = ('w',)
KEY_E = ('e',)
KEY_R = ('r',)
KEY_T = ('t',)
KEY_Y = ('y',)
KEY_U = ('u',)
KEY_I = ('i',)
KEY_O = ('o',)
KEY_P = ('p',)
LEFT_SQUARE_BRACKET = ('[',)
RIGHT_SQUARE_BRACKET = (']',)
ENTER = ('enter',)
CAPS_LOCK = ('capslock',)
KEY_A = ('a',)
KEY_S = ('s',)
KEY_D = ('d',)
KEY_F = ('f',)
KEY_G = ('g',)
KEY_H = ('h',)
KEY_J = ('j',)
KEY_K = ('k',)
KEY_L = ('l',)
SEMICOLON = (';',)
APOSTROPHE = ("'",)
LEFT_SHIFT = ('shiftleft',)
KEY_Z = ('z',)
KEY_X = ('x',)
KEY_C = ('c',)
KEY_V = ('v',)
KEY_B = ('b',)
KEY_N = ('n',)
KEY_M = ('m',)
COMMA = (',',)
PERIOD = ('.',)
SLASH = ('/',)
RIGHT_SHIFT = ('shiftright',)
BACKSLASH = ('\\',)
LEFT_CONTROL = ('ctrlleft',)
LEFT_WINDOW = ('winleft',)
LEFT_ALT = ('altleft',)
SPACE = (' ',)
RIGHT_ALT = ('altright',)
MENU = ('menu',)
RIGHT_WINDOW = ('winright',)
RIGHT_CONTROL = ('ctrlright',)
INSERT = ('insert',)
DELETE = ('delete',)
HOME = ('home',)
END = ('end',)
PAGE_UP = ('pageup',)
PAGE_DOWN = ('pagedown',)
LEFT_ARROW = ('left',)
RIGHT_ARROW = ('right',)
UP_ARROW = ('up',)
DOWN_ARROW = ('down',)
NUMPAD_0 = ('kp0',)
NUMPAD_1 = ('kp1',)
NUMPAD_2 = ('kp2',)
NUMPAD_3 = ('kp3',)
NUMPAD_4 = ('kp4',)
NUMPAD_5 = ('kp5',)
NUMPAD_6 = ('kp6',)
NUMPAD_7 = ('kp7',)
NUMPAD_8 = ('kp8',)
NUMPAD_9 = ('kp9',)
NUMPAD_DECIMAL = ('kp.',)
NUMPAD_DIVIDE = ('kp/',)
NUMPAD_ASTERISK = ('kp*',)
NUMPAD_MINUS = ('kp-',)
NUMPAD_PLUS = ('kp+',)
NUMPAD_ENTER = ('kpenter',)

Exceptions

Every exception can be access by aiviro.*Error notation.

>>> import aiviro
>>> try:
...     # some code
>>> except aiviro.CheckCommandError:
...     # process exception
exception aiviro.core.utils.exceptions.SearchObjectError
exception aiviro.core.utils.exceptions.CheckCommandError
exception aiviro.core.utils.exceptions.TooManyElementsError
exception aiviro.core.utils.exceptions.ElementIndexError
exception aiviro.core.utils.exceptions.ReferenceElementError
exception aiviro.core.utils.exceptions.AndElementError
exception aiviro.core.utils.exceptions.WorkingAreaError
exception aiviro.core.utils.exceptions.ScreenNotStableError
exception aiviro.core.utils.exceptions.ScrollEndException
exception aiviro.core.utils.exceptions.ImageNotSetError
exception aiviro.core.utils.exceptions.BoundaryElementError