Skip to content

BLISS utils

bliss.common.utils module contains a collection of classes and functions used to ease programming BLISS.

class handling

wrap_methods(from_object, target_object):

add_property(inst, name, method):

data structures operations

grouped(iterable, n):

Group elements of an iterable n by n. Return a zip object. s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), (s2n,s2n+1,s2n+2,...s3n-1), ... Excedentary elements are discarded.

DEMO [8]: from bliss.common.utils import grouped
DEMO [5]: list(grouped([1,2,3,4,5], 2))
 Out [5]: [(1, 2), (3, 4)]

grouped_with_tail(iterable, n):

Like grouped(), but do not remove last elements if they not reach the given length n.

DEMO [09]: from bliss.common.utils import grouped_with_tail
DEMO [10]: list(grouped_with_tail([1,2,3,4,5], 2))
 Out [10]: [[1, 2], [3, 4], [5]]

flatten_gen(items):

Flatten nested structures.

DEMO [11]: from bliss.common.utils import flatten_gen
DEMO [13]: list(flatten_gen([1, [2, 3,[4, 5], 6]]))
 Out [13]: [1, 2, 3, 4, 5, 6]

flatten(items):

Idem but return a list.

DEMO [14]: from bliss.common.utils import flatten
DEMO [15]: flatten([1, [2, 3,[4, 5], 6]])
 Out [15]: [1, 2, 3, 4, 5, 6]

merge(items):

Merge a list of list, first level only.

merge([ [1,2], [3] ]) -> [1,2,3]
merge([ [1,2], [[3,4]], [5] ]) -> [1,2,[3,4],5]

DEMO [16]: from bliss.common.utils import merge
DEMO [17]: merge([ [1,2], [[3,4]], [5] ])
 Out [17]: [1, 2, [3, 4], 5]

all_equal(iterable):

Objects customization

Functions to add custom attributes and commands to an object.

Decorators for set/get methods to access to custom attributes

add_object_method(obj, method)

object_method()

Decorator to add a custom method to an object.

The same as add_object_method but its purpose is to be used as a decorator to the controller method which is to be exported as object method.

Return a method where object_method attribute is filled with a dict of elements to characterize it.

object_method_type()

add_object_attribute()

object_attribute_type_get()

object_attribute_get()

object_attribute_type_set()

object_attribute_set()

set_custom_members

Creates custom methods and attributes for <target_obj> object using <src_object> object definitions. Populates __custom_methods_list and __custom_attributes_dict for tango device server.

with_custom_members

A class decorator to enable custom attributes and custom methods.

Various classes and functions

Null

StripIt(object)

Encapsulate object with a short str/repr/format. Useful to have in log messages since it only computes the representation if the log message is recorded.

periodic_exec

safe_get

human_time_fmt

Statistics

Calculate statistics from a profiling dictionary

  • key == function name
  • values == list of tuple (start_time, end_time)
DEMO [29]: from bliss.common.utils import Statistics
DEMO [30]: profile = {"init()":[(0.1, 0.22)], "finalize()":[(0.01, 0.045)]}
DEMO [31]: Statistics(profile)
 Out [31]: func_name    min        mean       max            std
           -----------  ---------  ---------  ---------  -------
           finalize()   35.000ms   35.000ms   35.000ms   0.00000
           init()       120.000ms  120.000ms  120.000ms  0.00000

autocomplete_property

A custom property class that will be added to jedi’s ALLOWED_DESCRIPTOR_ACCESS

UserNamespace

deep_update

Do a deep merge of one dict into another.

Types

is_basictype

is_complextype

is_mutsequence

is_mutmapping

is_sametype

Tree

prudent_update(d, u):

Updates a MutableMapping or MutalbeSequence ‘d’ from another one ‘u’. The update is done trying to minimize changes: the update is done only on leaves of the tree if possible. This is to preserve the original object as much as possible.

update_node_info(node, d)

math rounding

rounder

Return rounded string representation of a number according to a template number. Rounding is performed by string formating (ie uses round() ?).

from bliss.common.utils import rounder

assert rounder(0.0001, 16.12345) == "16.1234"
assert rounder(1, 16.123) == "16"
assert rounder(0.1, 8.5) == "8.5"
assert rounder(1e-8, 1.123456789123456789) == "1.12345679"

NB: Used to display axes positions.

Shell

ShellStr

Network

get_open_ports(n):

Colors

  • PURPLE(msg)
  • CYAN(msg)
  • DARKCYAN(msg)
  • BLUE(msg)
  • GREEN(msg)
  • YELLOW(msg)
  • RED(msg)
  • UNDERLINE(msg)
  • BOLD(msg)

Help/Errors

ErrorWithTraceback

WrappedMethod

shorten_signature

By default it is removing the annotation of each parameter or replacing it with a custum one.

custom_error_msg

typecheck_var_args_pattern

modify_annotations

Modify the annotation in an existing signature.

is_pattern

Return true if the input string is a pattern for get_matching_names.

get_matching_names

Search a pattern into a list of names (unix pattern style).

Messages

nonblocking_print

getval

getval_ functions are a set of functions to prompt user to enter interactively various types of inputs: int, float, string, yes/no answer to a question etc.

They rely on click library https://click.palletsprojects.com/en/8.0.x/.

getval_int_range

  • getval_int_range(message, min, max, default): Prompt user for an int number in interval [min, max]
In [1]: from bliss.shell.getval import getval_int_range

In [2]: getval_int_range("Please enter beamline number", min=1, max=32, default=1)

Please enter beamline number [1]: f
Error: f is not a valid integer
Please enter beamline number [1]: 99
Error: 99 is not in the valid range of 1 to 32.
Please enter beamline number [1]: 5
Out[2]: 5

getval_idx_list

  • getval_idx_list(): Return the index and string chosen by user in list of N strings. Selection is done by index in [1..N].

Example:

from bliss.shell.getval import getval_idx_list

dspacing_list = ["111", "311", "642"]
print(getval_idx_list(dspacing_list,"Choose the index of dspacing you want to use"))

Execution of previous example:

1 - 111
2 - 311
3 - 642
Choose the index of dspacing you want to use [1]: 2
311

getval_char_list

from bliss.shell.getval import getval_char_list

actions_list= [("a", "add a roi"), ("r", "remove a roi"), ("m", "modify a roi")]
getval_char_list(actions_list, "Action to do")

Execution of previous example:


getval_yes_no

  • getval_yes_no(message, default=True)
from bliss.shell.getval import getval_yes_no

 In [3]: if getval_yes_no("Do you want to open shutter ?", default="no"):
   ...:     print("ok, openning...")
   ...: else:
   ...:     print("abort...")

Do you want to open shutter ? [Y/n]: 0
Error: invalid input
Do you want to open shutter ? [Y/n]: 1
Error: invalid input
Do you want to open shutter ? [Y/n]: oui
Error: invalid input
Do you want to open shutter ? [Y/n]: YES
ok, openning...

Custom the style

By default the displayed of this function is basic, without any colors.

This can be custom with some style. See the prompt_toolkit documentation for more information.

This can be part of the setup of the BLISS session, to be applied globally.

from bliss.shell import getval as getval_module
from prompt_toolkit.styles import Style
getval_module.STYLE = Style.from_dict(
    {
        # User input (default text).
        "":             "white",
        # Other classes
        "question":     "orange bold",
        "prompt_char":  "yellow",
        "valid_input":  "red bold",
        "separator":    "",
        "description":  "blue"
    }
)

Styled getval helpers

Mostly the style classes follows this template:

[valid_input][separator][description]
[valid_input][separator][description]
[valid_input][separator][description]
[question][valid_input][prompt_char][]