aea.helpers.base
Miscellaneous helpers.
locate
def locate(path: str) -> Any
Locate an object by name or dotted save_path, importing as necessary.
load_
module
def load_module(dotted_path: str, filepath: Path) -> types.ModuleType
Load a module.
Arguments:
dotted_path
: the dotted save_path of the package/module.filepath
: the file to the package/module.
Raises:
ValueError
: if the filepath provided is not a module. # noqa: DAR402Exception
: if the execution of the module raises exception. # noqa: DAR402
Returns:
module type
load_
env_
file
def load_env_file(env_file: str) -> None
Load the content of the environment file into the process environment.
Arguments:
env_file
: save_path to the env file.
sigint_
crossplatform
def sigint_crossplatform(process: subprocess.Popen) -> None
Send a SIGINT, cross-platform.
The reason is because the subprocess module doesn't have an API to send a SIGINT-like signal both on Posix and Windows with a single method.
However, a subprocess.Popen class has the method 'send_signal' that gives more flexibility in this terms.
Arguments:
process
: the process to send the signal to.
win_
popen_
kwargs
def win_popen_kwargs() -> dict
Return kwargs to start a process in windows with new process group.
Help to handle ctrl c properly. Return empty dict if platform is not win32
Returns:
windows popen kwargs
send_
control_
c
def send_control_c(process: subprocess.Popen,
kill_group: bool = False) -> None
Send ctrl-C cross-platform to terminate a subprocess.
Arguments:
process
: the process to send the signal to.kill_group
: whether or not to kill group
RegexConstrainedString Objects
class RegexConstrainedString(UserString)
A string that is constrained by a regex.
The default behaviour is to match anything. Subclass this class and change the 'REGEX' class attribute to implement a different behaviour.
__
init__
def __init__(seq: Union[UserString, str]) -> None
Initialize a regex constrained string.
SimpleId Objects
class SimpleId(RegexConstrainedString)
A simple identifier.
The allowed strings are all the strings that: - have at least length 1 - have at most length 128 - the first character must be between a-z,A-Z or underscore - the other characters must be either the above or digits.
Examples of allowed strings:
SimpleId("an_identifier") 'an_identifier'
Examples of not allowed strings:
SimpleId("0an_identifier") Traceback (most recent call last): ... ValueError: Value 0an_identifier does not match the regular expression re.compile('[a-z_][a-z0-9_]{0,127}')
SimpleId("an identifier") Traceback (most recent call last): ... ValueError: Value an identifier does not match the regular expression re.compile('[a-z_][a-z0-9_]{0,127}')
SimpleId("") Traceback (most recent call last): ... ValueError: Value does not match the regular expression re.compile('[a-z_][a-z0-9_]{0,127}')
SimpleId("An_id") Traceback (most recent call last): ... ValueError: Value An_id does not match the regular expression re.compile('[a-z_][a-z0-9_]{0,127}')
SimpleId("an_Id") Traceback (most recent call last): ... ValueError: Value an_Id does not match the regular expression re.compile('[a-z_][a-z0-9_]{0,127}')
IPFSHash Objects
class IPFSHash(RegexConstrainedString)
A IPFSHash identifier.
The allowed strings are all the strings that: - have length 128 - the first character must be between a-z or underscore - the other characters must be either the above or digits.
Examples of allowed strings:
IPFSHash("bafybeihpjm2sgnrpuwaqicikw4aybltm7xrjmf7cscpp2cy2xdoi6pekbq") 'bafybeihpjm2sgnrpuwaqicikw4aybltm7xrjmf7cscpp2cy2xdoi6pekbq'
Examples of not allowed strings:
IPFSHash("0an_identifier") Traceback (most recent call last): ... ValueError: Value 0an_identifier does not match the regular expression re.compile('((Qm[a-zA-Z0-9]{44})|(ba[a-zA-Z0-9]{57}))')
IPFSHash("an_identifier") Traceback (most recent call last): ... ValueError: Value an_identifier does not match the regular expression re.compile('((Qm[a-zA-Z0-9]{44})|(ba[a-zA-Z0-9]{57}))')
IPFSHash("an identifier") Traceback (most recent call last): ... ValueError: Value an identifier does not match the regular expression re.compile('((Qm[a-zA-Z0-9]{44})|(ba[a-zA-Z0-9]{57}))')
IPFSHash("") Traceback (most recent call last): ... ValueError: Value does not match the regular expression re.compile('((Qm[a-zA-Z0-9]{44})|(ba[a-zA-Z0-9]{57}))')
cd
@contextlib.contextmanager
def cd(path: PathLike) -> Generator
Change working directory temporarily.
get_
logger_
method
def get_logger_method(fn: Callable,
logger_method: Union[str, Callable]) -> Callable
Get logger method for function.
Get logger in fn
definition module or creates logger is module.name.
Or return logger_method if it's callable.
Arguments:
fn
: function to get logger for.logger_method
: logger name or callable.
Returns:
callable to write log with
try_
decorator
def try_decorator(error_message: str,
default_return: Optional[Callable] = None,
logger_method: Any = "error") -> Callable
Run function, log and return default value on exception.
Does not support async or coroutines!
Arguments:
error_message
: message template with one{}
for exceptiondefault_return
: value to return on exception, by default Nonelogger_method
: name of the logger method or callable to print logs
Returns:
the callable
MaxRetriesError Objects
class MaxRetriesError(Exception)
Exception for retry decorator.
retry_
decorator
def retry_decorator(number_of_retries: int,
error_message: str,
delay: float = 0,
logger_method: str = "error") -> Callable
Run function with several attempts.
Does not support async or coroutines!
Arguments:
number_of_retries
: amount of attemptserror_message
: message template with one{}
for exceptiondelay
: number of seconds to sleep between retries. default 0logger_method
: name of the logger method or callable to print logs
Returns:
the callable
exception_
log_
and_
reraise
@contextlib.contextmanager
def exception_log_and_reraise(log_method: Callable, message: str) -> Generator
Run code in context to log and re raise exception.
Arguments:
log_method
: function to print logmessage
: message template to add error text.
Returns:
the generator
recursive_
update
def recursive_update(to_update: Dict,
new_values: Dict,
allow_new_values: bool = False) -> None
Update a dictionary by replacing conflicts with the new values.
It does side-effects to the first dictionary.
to_update = dict(a=1, b=2, subdict=dict(subfield1=1)) new_values = dict(b=3, subdict=dict(subfield1=2)) recursive_update(to_update, new_values) to_update {'a': 1, 'b': 3, 'subdict': {'subfield1': 2}}
Arguments:
to_update
: the dictionary to update.new_values
: the dictionary of new values to replace.allow_new_values
: whether or not to allow new values.
perform_
dict_
override
def perform_dict_override(component_id: Any, overrides: Dict,
updated_configuration: Dict,
new_configuration: Dict) -> None
Perform recursive dict override.
Arguments:
component_id
: Component ID for which the updated will be performedoverrides
: A dictionary containing mapping for Component ID -> List of pathsupdated_configuration
: Configuration which needs to be updatednew_configuration
: Configuration from which the method will perform the update
find_
topological_
order
def find_topological_order(adjacency_list: Dict[T, Set[T]]) -> List[T]
Compute the topological order of a graph (using Kahn's algorithm).
Arguments:
adjacency_list
: the adjacency list of the graph.
Raises:
ValueError
: if the graph contains a cycle.
Returns:
the topological order for the graph (as a sequence of nodes)
reachable_
nodes
def reachable_nodes(adjacency_list: Dict[T, Set[T]],
starting_nodes: Set[T]) -> Dict[T, Set[T]]
Find the reachable subgraph induced by a set of starting nodes.
Arguments:
adjacency_list
: the adjacency list of the full graph.starting_nodes
: the starting nodes of the new graph.
Returns:
the adjacency list of the subgraph.
cached_
property Objects
class cached_property()
Cached property from python3.8 functools.
__
init__
def __init__(func: Callable) -> None
Init cached property.
__
set_
name__
def __set_name__(_: Any, name: Any) -> None
Set name.
__
get__
def __get__(instance: Any, _: Optional[Any] = None) -> Any
Get instance.
ensure_
dir
def ensure_dir(dir_path: str) -> None
Check if dir_path is a directory or create it.
dict_
to_
path_
value
def dict_to_path_value(
data: Mapping,
path: Optional[List] = None) -> Iterable[Tuple[List[str], Any]]
Convert dict to sequence of terminal path build of keys and value.
parse_
datetime_
from_
str
def parse_datetime_from_str(date_string: str) -> datetime.datetime
Parse datetime from string.
CertRequest Objects
class CertRequest()
Certificate request for proof of representation.
__
init__
def __init__(public_key: str, identifier: SimpleIdOrStr,
ledger_id: SimpleIdOrStr, not_before: str, not_after: str,
message_format: str, save_path: str) -> None
Initialize the certificate request.
Arguments:
public_key
: the public key, or the key id.identifier
: certificate identifier.ledger_id
: ledger identifier the request is referring to.not_before
: specify the lower bound for certificate validity. If it is a string, it must follow the format: 'YYYY-MM-DD'. It will be interpreted as timezone UTC-0.not_after
: specify the lower bound for certificate validity. If it is a string, it must follow the format: 'YYYY-MM-DD'. It will be interpreted as timezone UTC-0.message_format
: message format used for signingsave_path
: the save_path where to save the certificate.
public_
key
@property
def public_key() -> Optional[str]
Get the public key.
ledger_
id
@property
def ledger_id() -> str
Get the ledger id.
key_
identifier
@property
def key_identifier() -> Optional[str]
Get the key identifier.
identifier
@property
def identifier() -> str
Get the identifier.
not_
before_
string
@property
def not_before_string() -> str
Get the not_before field as string.
not_
after_
string
@property
def not_after_string() -> str
Get the not_after field as string.
not_
before
@property
def not_before() -> datetime.datetime
Get the not_before field.
not_
after
@property
def not_after() -> datetime.datetime
Get the not_after field.
message_
format
@property
def message_format() -> str
Get the message format.
save_
path
@property
def save_path() -> Path
Get the save path for the certificate.
Note: if the path is not absolute, then the actual save path might depend on the context.
Returns:
the save path
get_
absolute_
save_
path
def get_absolute_save_path(path_prefix: Optional[PathLike] = None) -> Path
Get the absolute save path.
If save_path is an absolute path, then the prefix is ignored. Otherwise, the path prefix is prepended.
Arguments:
path_prefix
: the (absolute) path to prepend to the save path.
Returns:
the actual save path.
public_
key_
or_
identifier
@property
def public_key_or_identifier() -> str
Get the public key or identifier.
get_
message
def get_message(public_key: str) -> bytes
Get the message to sign.
construct_
message
@classmethod
def construct_message(cls, public_key: str, identifier: SimpleIdOrStr,
not_before_string: str, not_after_string: str,
message_format: str) -> bytes
Construct message for singning.
Arguments:
public_key
: the public keyidentifier
: identifier to be signednot_before_string
: signature not valid beforenot_after_string
: signature not valid aftermessage_format
: message format used for signing
Returns:
the message
get_
signature
def get_signature(path_prefix: Optional[PathLike] = None) -> str
Get signature from save_path.
Arguments:
path_prefix
: the path prefix to be prepended to save_path. Defaults to cwd.
Returns:
the signature.
json
@property
def json() -> Dict
Compute the JSON representation.
from_
json
@classmethod
def from_json(cls, obj: Dict) -> "CertRequest"
Compute the JSON representation.
__
eq__
def __eq__(other: Any) -> bool
Check equality.
compute_
specifier_
from_
version
def compute_specifier_from_version(version: Version,
use_version_as_lower: bool = False) -> str
Compute the specifier set from a version.
version specifier is: >=major.minor.0, <next_major.0.0
Arguments:
version
: the versionuse_version_as_lower
: use the version as lower bound for specifier
Returns:
the specifier set
decorator_
with_
optional_
params
def decorator_with_optional_params(decorator: Callable) -> Callable
Make a decorator usable either with or without parameters.
In other words, if a decorator "mydecorator" is decorated with this decorator, It can be used both as:
@mydecorator def myfunction(): ...
or as:
@mydecorator(arg1, kwarg1="value") def myfunction(): ...
Arguments:
decorator
: a decorator callable
Returns:
a decorator callable
delete_
directory_
contents
def delete_directory_contents(directory: Path) -> None
Delete the content of a directory, without deleting it.
prepend_
if_
not_
absolute
def prepend_if_not_absolute(path: PathLike, prefix: PathLike) -> PathLike
Prepend a path with a prefix, but only if not absolute
Arguments:
path
: the path to process.prefix
: the path prefix.
Returns:
the same path if absolute, else the prepended path.