Ska Package Helpers¶
Ska_helpers is a collection of utilities for the Ska3 runtime environment.
Chandra Models Data¶
Logging¶
- ska_helpers.logging.basic_logger(name, format='%(asctime)s %(funcName)s: %(message)s', propagate=False, **kwargs)[source]¶
Create logger
name
using logging.basicConfig.This is a thin wrapper around logging.basicConfig, except:
Uses logger named
name
instead of the root loggerDefaults to a standard format for Ska applications. Specify
format=None
to use the defaultbasicConfig
format.Not recommended for multithreaded or multiprocess applications due to using a temporary monkey-patch of a global variable to create the logger. It will probably work but it is not guaranteed.
This function does nothing if the
name
logger already has handlers configured, unless the keyword argumentforce
is set toTrue
. It is a convenience method intended to do one-shot creation of a logger.The default behaviour is to create a StreamHandler which writes to
sys.stderr
, set a formatter using the format string"%(asctime)s %(funcName)s: %(message)s"
, and add the handler to thename
logger with a level of WARNING.By default the created logger will not propagate to parent loggers. This is to prevent unexpected logging from other packages that set up a root logger. To propagate to parent loggers, set
propagate=True
. See https://docs.python.org/3/howto/logging.html#logging-flow, in particular how the log level of parent loggers is ignored in message handling.Example:
# In __init__.py for a package or in any module from ska_helpers.logging import basic_logger logger = basic_logger(__name__, level='INFO') # In other submodules within a package the normal usage is to inherit # the package logger. import logging logger = logging.getLogger(__name__)
A number of optional keyword arguments may be specified, which can alter the default behaviour.
- filename Specifies that a FileHandler be created, using the specified
filename, rather than a StreamHandler.
- filemode Specifies the mode to open the file, if filename is specified
(if filemode is unspecified, it defaults to ‘a’).
format Use the specified format string for the handler.
datefmt Use the specified date/time format.
- style If a format string is specified, use this to specify the
type of format string (possible values ‘%’, ‘{’, ‘$’, for %-formatting,
str.format()
andstring.Template
- defaults to ‘%’).- level Set the
name
logger level to the specified level. This can be a number (10, 20, …) or a string (‘NOTSET’, ‘DEBUG’, ‘INFO’, ‘WARNING’, ‘ERROR’, ‘CRITICAL’) or
logging.DEBUG
, etc.- stream Use the specified stream to initialize the StreamHandler. Note
that this argument is incompatible with ‘filename’ - if both are present, ‘stream’ is ignored.
- handlers If specified, this should be an iterable of already created
handlers, which will be added to the
name
handler. Any handler in the list which does not have a formatter assigned will be assigned the formatter created in this function.- force If this keyword is specified as true, any existing handlers
attached to the
name
logger are removed and closed, before carrying out the configuration as specified by the other arguments.
Note that you could specify a stream created using open(filename, mode) rather than passing the filename and mode in. However, it should be remembered that StreamHandler does not close its stream (since it may be using sys.stdout or sys.stderr), whereas FileHandler closes its stream when the handler is closed.
Note this function is probably not thread-safe.
- Parameters
- namestr
logger name
- formatstr
format string for handler
- propagate: bool
propagate to parent loggers (default=False)
- **kwargsdict
other keyword arguments for logging.basicConfig
- Returns
- loggerLogger object
Retry¶
Retry package initially copied from https://github.com/invl/retry.
This project appears to be abandoned so moving it to ska_helpers.
LICENSE:
Copyright 2014 invl
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- exception ska_helpers.retry.RetryError(failures)[source]¶
Keep track of the stack of exceptions when trying multiple times.
- Parameters
- failureslist of dict, each with keys ‘type’, ‘value’, ‘trace’.
- ska_helpers.retry.retry(exceptions=<class 'Exception'>, tries=-1, delay=0, max_delay=None, backoff=1, jitter=0, logger=<Logger ska_helpers.retry.api (WARNING)>)[source]¶
Returns a retry decorator.
- Parameters
exceptions – an exception or a tuple of exceptions to catch. default: Exception.
tries – the maximum number of attempts. default: -1 (infinite).
delay – initial delay between attempts. default: 0.
max_delay – the maximum value of delay. default: None (no limit).
backoff – multiplier applied to delay between attempts. default: 1 (no backoff).
jitter – extra seconds added to delay between attempts. default: 0. fixed if a number, random if a range tuple (min, max)
logger – logger.warning(fmt, error, delay) will be called on failed attempts. default: retry.logging_logger. if None, logging is disabled.
- Returns
a retry decorator.
- ska_helpers.retry.retry_call(f, args=None, kwargs=None, exceptions=<class 'Exception'>, tries=-1, delay=0, max_delay=None, backoff=1, jitter=0, logger=<Logger ska_helpers.retry.api (WARNING)>)[source]¶
Calls a function and re-executes it if it failed.
- Parameters
f – the function to execute.
args – the positional arguments of the function to execute.
kwargs – the named arguments of the function to execute.
exceptions – an exception or a tuple of exceptions to catch. default: Exception.
tries – the maximum number of attempts. default: -1 (infinite).
delay – initial delay between attempts. default: 0.
max_delay – the maximum value of delay. default: None (no limit).
backoff – multiplier applied to delay between attempts. default: 1 (no backoff).
jitter – extra seconds added to delay between attempts. default: 0. fixed if a number, random if a range tuple (min, max)
logger – logger.warning(fmt, error, delay) will be called on failed attempts. default: retry.logging_logger. if None, logging is disabled.
- Returns
the result of the f function.
- ska_helpers.retry.tables_open_file(*args, **kwargs)[source]¶
Call tables.open_file(*args, **kwargs) with retry up to 3 times.
This only catches tables.exceptions.HDF5ExtError. After an initial failure it will try again after 2 seconds and once more after 4 seconds.
- Parameters
*args –
args passed through to tables.open_file()
**kwargs –
kwargs passed through to tables.open_file()
- Returns
tables file handle
Setup Helpers¶
- ska_helpers.setup_helper.duplicate_package_info(vals, name_in, name_out)[source]¶
Duplicate a list or dict of values inplace, replacing
name_in
withname_out
.Normally used in setup.py for making a namespace package that copies a flat one. For an example see setup.py in the ska_sun or Ska.Sun repo.
- Parameters
vals – list or dict of values
name_in – string to replace at start of each value
name_out – output string
Utilities¶
- class ska_helpers.utils.LazyDict(load_func, *args, **kwargs)[source]¶
Dict which is lazy-initialized using supplied function
load_func
.This class allows defining a module-level dict that is expensive to initialize, where the initialization is done lazily (only when actually needed).
- Parameters
- load_funcfunction
Reference to a function that returns a dict to init this dict object
- *args
Arguments list for
load_func
- **kwargs
Keyword arguments for
load_func
Examples
from ska_helpers.utils import LazyDict def load_func(a, b): # Some expensive function in practice print('Here in load_func') return {'a': a, 'b': b} ONE = LazyDict(load_func, 1, 2) print('ONE is defined but not yet loaded') print(ONE['a'])
- copy() a shallow copy of D ¶
- get(key, default=None, /)¶
Return the value for key if key is in the dictionary, else default.
- items() a set-like object providing a view on D's items ¶
- keys() a set-like object providing a view on D's keys ¶
- pop(k[, d]) v, remove specified key and return the corresponding value. ¶
If key is not found, d is returned if given, otherwise KeyError is raised
- popitem()¶
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- setdefault(key, default=None, /)¶
Insert key with a value of default if key is not in the dictionary.
Return the value for key if key is in the dictionary, else default.
- values() an object providing a view on D's values ¶
- class ska_helpers.utils.LazyVal(load_func, *args, **kwargs)[source]¶
Value which is lazy-initialized using supplied function
load_func
.This class allows defining a module-level value that is expensive to initialize, where the initialization is done lazily (only when actually needed).
The lazy value is accessed using the
val
property.- Parameters
- load_funcfunction
Reference to a function that returns a dict to init this dict object
- *args
Arguments list for
load_func
- **kwargs
Keyword arguments for
load_func
Examples
from ska_helpers.utils import LazyVal def load_func(a): # Some expensive function in practice print('Here in load_func') return a ONE = LazyVal(load_func, 1) print('ONE is defined but not yet loaded') print(ONE.val)
Version Info¶
The ska_helpers.version
module provides utilities to handle package
versions. The version of a package is determined using pkg_resources if it is
installed, and setuptools_scm
otherwise.
- ska_helpers.version.get_version(package, distribution=None)[source]¶
Get version string for
package
with optionaldistribution
name.If the package is not from an installed distribution then get version from git using setuptools_scm.
- Parameters
- package :
package name, typically __package__
- distribution :
name of distribution if different from
package
(Default value = None)
- Returns
- str
Version string
- ska_helpers.version.parse_version(version)[source]¶
Parse version string and return a dictionary with version information. This only handles the default scheme.
- Parameters
- version :
str
- Returns
- dict
version information
Default versioning scheme¶
What follows is the scheme as described in setuptools_scm’s documentation.
In the standard configuration setuptools_scm
takes a look at three things:
latest tag (with a version number)
the distance to this tag (e.g. number of revisions since latest tag)
workdir state (e.g. uncommitted changes since latest tag)
and uses roughly the following logic to render the version:
- no distance and clean:
{tag}
- distance and clean:
{next_version}.dev{distance}+{scm letter}{revision hash}
- no distance and not clean:
{tag}+dYYYMMMDD
- distance and not clean:
{next_version}.dev{distance}+{scm letter}{revision hash}.dYYYMMMDD
The next version is calculated by adding 1
to the last numeric component of
the tag.
For Git projects, the version relies on git describe,
so you will see an additional g
prepended to the {revision hash}
.
Due to the default behavior it’s necessary to always include a
patch version (the 3
in 1.2.3
), or else the automatic guessing
will increment the wrong part of the SemVer (e.g. tag 2.0
results in
2.1.devX
instead of 2.0.1.devX
). So please make sure to tag
accordingly.
Run time information¶
The ska_helpers.run_info
module provides convenience functions to get
and print relevant run time information such as machine name, user name, date,
program version, and so on. This is aimed at executable scripts and cron jobs.
- ska_helpers.run_info.get_run_info(opt=None, *, version=None, stack_level=1)[source]¶
Get run time information as dict.
- Parameters
- opt :
argparse options (Default value = None)
- version :
program version (default=__version__ in calling module)
- stack_level :
stack level for getting calling module (Default value = 1)
- Returns
- dcit
run information
- ska_helpers.run_info.get_run_info_lines(opt=None, *, version=None, stack_level=2)[source]¶
Get run time information as formatted lines.
- Parameters
- opt :
argparse options (Default value = None)
- version :
program version (default=__version__ in calling module)
- stack_level :
stack level for getting calling module (Default value = 2)
- Returns
- list
formatted information lines
- ska_helpers.run_info.log_run_info(log_func, opt=None, *, version=None, stack_level=3)[source]¶
Output run time information as formatted lines via
log_func
.Each formatted line is passed to
log_func
.- Parameters
- log_func :
logger output function (e.g. logger.info)
- opt :
argparse options (Default value = None)
- version :
program version (default=__version__ in calling module)
- stack_level :
stack level for getting calling module (Default value = 3)