YAML API

An implementation of logging_strict.logging_yaml_abc.LoggingYamlType

Not on the Public API, but underlies Public API functions dealing with extract and setup of logging.config yaml files

logging is thread-safe. A change in one thread affects every thread. And logging config is dirty, each logger, since it’s a Singleton, stays around for the life of the app. So the app and workers need to be isolated from each other.

multiprocessing.pool.Pool > ThreadPool. Workers should exist as separate processes. The logging state ends along with the worker process.

Another design consideration is avoiding blocking the main app thread. A message queue manager (rabbitmq) can mitigate this issue.

So there needs to be two categories of logging.config yaml files:

  • app

Uses a (logging) handler specific for a particular UI framework

  • worker

(logging) handler is directed at console or files. If log to console (logging.StreamHandler), capture the worker logging output, including it along with the worker output.

Module private variables

logging_strict.logging_api.__all__: tuple[str, str, str, str, str, str] = ("LoggingConfigYaml", "setup_ui_other", "ui_yaml_curated",    "worker_yaml_curated", "setup_worker_other", "LoggingState")

Module exports

Module objects

class logging_strict.logging_api.LoggingConfigYaml(package_name, package_data_folder_start, category, genre=None, flavor=None, version_no='1')

For the UI, extract and setup logging.config yaml file

A category is prefixed to the file suffixes. The final file suffixes becomes:

  • for the UI process

    .logging.config.yaml ‣ .app.logging.config.yaml.

  • for the worker process(es)

    .logging.config.yaml ‣ `.worker.logging.config.yaml

Class variables

Variables:

suffixes (str) –

logging.config yaml file suffixes

value: .logging.config.yaml

A category will be prefix’ed.

For the UI process, the final file suffixes becomes
.logging.config.yaml ‣ .app.logging.config.yaml.

For the worker, the final suffixes would becomes
.logging.config.yaml ‣ .worker.logging.config.yaml

Instance variables

Variables:
  • package_name (str) – The Python package containing the logging.config yaml file(s). Curating in one place, commonly used, yaml files is better than having copies in each and every Python package

  • package_data_folder_start (str) – relative path, within package, to data folder

  • category (logging_strict.constants.LoggingConfigCategory | str | Any | None) –

    LoggingConfigCategory.UI or LoggingConfigCategory.WORKER

    The logging configuration will not be the same for main process and for workers.

    The main process, even if headless is considered to be the UI. Heavy background processing occurs in workers. These are run in a separate process, not merely a thread. This design prevents logging.config changes from polluting other workers or the main process.

  • genre (str | None) – If UI: “textual” or “rich”. If worker: “stream”. Then can have a library of yaml files that can be used with a particular UI framework or worker type

  • flavor (str | None) –

    Unique identifier name given to a particular logging.config yaml. This name is slugified. Meaning period and underscores converted to hyphens

    Flavor is a very terse description, for a LoggingConfigYaml.genre, how this yaml differs from others. If completely generic, call it generic. If different handlers or formatters or filters are used, what is the yaml’s purpose?

  • version_no (Any | None) –

    Default 1. Version of this particular
    genre or genre & flavor

    Not the version of the yaml spec. Don’t confuse the two.

Raises:
property category

Category as a str. Category str either: ‘app’ or ‘worker’

Returns:

Category str

Return type:

str

property dest_folder

Normally xdg user data dir. During testing, temp folder used instead

Returns:

Destination folder

Return type:

pathlib.Path

extract(path_relative_package_dir='')

folder of yaml file is unknown, find the file

Parameters:

path_relative_package_dir (pathlib.Path | str | None) – Default empty string which means search the entire package. Specifying a start folder narrows the search

Returns:

Relative path, within package, to *.*.logging.config.yaml

Return type:

str

Raises:
property file_name

Get the file name. Can raise exceptions if category and/or genre were not provided to the constructor

Returns:

file name

Return type:

str

Raises:
property file_stem

file stem consists of slugs seperated by underscore

Returns:

File name. Which is file stem + suffixes

Return type:

str

Raises:

Todo

slugify

The code and flavor should be only hyphens. Then separate these tokens with underscores

property file_suffix

Suffixes: .[category].logging.config yaml

Returns:

file suffixes

Return type:

str

Raises:
property flavor

Specific implementation of a genre.

E.g. multiple logging.config yaml files for textual

Uses the handler, textual.logging.TextualHandler, but each has some variation. Like custom formaters or filters

So the flavor may be

  • Package that originally uses it and provided it to be curated within logging_strict e.g. asz

  • One word, no hyphen period or underscore, description of the uniqueness of this variation

Returns:

Flavor str

Return type:

str | None

property genre

In constructor can neglect to provide genre.

So can use:

Can’t use

Genre is the UI framwork or worker characteristic

  • imply the handler. e.g. textual or rich

  • imply the characteristics of a worker ep. e.g. mp or mq

Returns:

Genre str

Return type:

str | None

property package

Package name (underscores, not hyphens) where the logging.config yaml file is located.

Ideally should be curated in logging-strict

Returns:

Package name

Return type:

str

suffixes: str = '.logging.config.yaml'
property version

Applies to the genre or genre & flavor.

Default “1”

Do not confuse with yaml spec version

Returns:

logging.config yaml file version

Return type:

str

class logging_strict.logging_api.LoggingState

Singleton to hold the current logging state. To know whether or not, run by app or from cli

logging is redirected to

Knowing the logging mode (or state), first step towards restoring logging mode

Class variables

Variables:
  • _instance – Default None. Holds Singleton instance

  • _lock – Thread lock for Singleton

See also

See textual.logging

Thread safe Singleton [blog post]

property is_state_app

Get logging state

Returns:

True if app logging state otherwise False

Return type:

bool | None

classmethod reset()

A cheat to reset the Singleton state. Use only during testing

logging_strict.logging_api.setup_ui_other(package_name, package_data_folder_start, genre, flavor, version_no='1', package_start_relative_folder='', logger_package_name=None)

Before creating an App instance, seemlessly extracts logging.config yaml file for app, but not worker(s)

Parameters:
  • package_name (str) – Package name containing logging.config yaml file

  • package_data_folder_start (str) – Package base data folder name. Not a relative path. This is the fallback search folder. Use package_start_relative_folder to further narrow the search

  • genre (str) – UI framework or worker implementation characteristic. E.g. textual, rich, mp, or mq

  • flavor (str) – Brand or how variation differs. e.g. asz

  • version_no (Any | None) – Default “1”. Applies to genre or genre & flavor

  • package_start_relative_folder (str | None) –

    Default empty string.

    Relative to package_data_folder_start.
    Relative path to further narrow down which folder contains the
    logging.config yaml file.

    Needed when multiple folders contain logging.config yaml file
    with same file name

  • logger_package_name (str | None) – Default None. Update the dict to set a more appropriate logger package name. Will always want to do this

Returns:

relative path to validated logging config YAML file and the yaml str

Return type:

tuple[str, str]

Raises:
logging_strict.logging_api.setup_worker_other(package_name, package_data_folder_start, genre, flavor, version_no='1', package_start_relative_folder='', logger_package_name=None)

worker_yaml_curated grabs the logging.config yaml from logging-strict. Use this if located in another package

Process 2nd step is calling: setup_logging_yaml()

Parameters:
  • package_name (str) – If logging_strict, use method worker_yaml_curated instead. Otherwise package name which contains the logging.config yaml files

  • package_data_folder_start (str) – Within package_name, base data folder name. Not a relative path. Does not assume data

  • genre (str) – Default “mp”. If UI: “textual” or “rich”. If worker: “mp”. Then can have a library of yaml files that can be used with a particular UI framework or worker type

  • flavor (str) –

    Default “asz”. Unique identifier name given to a particular logging.config yaml. Should be one word w/o special characters

    Flavor is a very terse description, for a genre, how this yaml differs from others. If completely generic, call it generic. If different handlers or formatters or filters are used, what is the yaml’s purpose?

  • version_no (Any | None) – Default 1. Version of this particular genre. Not the version of the yaml spec. Don’t confuse the two.

  • package_start_relative_folder (pathlib.Path | str | None) – Default empty string which means search the entire package. Further narrows down search, so as to differentiate between folders which contain file with the same file name

  • logger_package_name (str | None) – Set logger to the intended package name. Default None which leaves as-is

Returns:

relative destination path to validated logging config YAML file and the yaml str

Return type:

tuple[str, str]

Raises:
logging_strict.logging_api.ui_yaml_curated(genre, flavor, version_no='1', package_start_relative_folder='', logger_package_name=None)

Curated within logging-strict So do not have to provide package and package base data folder name

Parameters:
  • genre (str) – UI framework or worker implementation characteristic. E.g. textual, rich, mp, or mq

  • flavor (str) – Brand or how variation differs. e.g. asz

  • version_no (Any | None) – Default “1”. Applies to genre or genre & flavor

  • package_start_relative_folder (str) –

    Default empty string. Relative to package_data_folder_start. Relative path to further narrow down which folder contains the logging.config yaml file.

    Needed when multiple folders contain logging.config yaml file with same file name

  • logger_package_name (str | None) – In logger dict, instead of the default package name, set a package name. Always desirable.

Returns:

relative destination path to validated logging config YAML file and the yaml str

Return type:

tuple[str, str]

logging_strict.logging_api.worker_yaml_curated(genre='mp', flavor='asz', version_no='1', package_start_relative_folder='', logger_package_name=None)

For multiprocessing workers, retrieve the yaml in this order:

  • xdg user data dir folder

  • logging_strict package

If QA tester, modifies the exported logging.config yaml, those changes are not overwritten

Process 2nd step is calling: setup_logging_yaml()

Parameters:
  • genre (str | None) – Default “mp”. If UI: “textual” or “rich”. If worker: “mp”. Then can have a library of yaml files that can be used with a particular UI framework or worker type

  • flavor (str | None) –

    Default “asz”. Unique identifier name given to a particular logging.config yaml. Should be one word w/o special characters

    Flavor is a very terse description, for a genre, how this yaml differs from others. If completely generic, call it generic. If different handlers or formatters or filters are used, what is the yaml’s purpose?

  • version_no (Any | None) – Default 1. Version of this particular genre. Not the version of the yaml spec. Don’t confuse the two.

  • package_start_relative_folder (pathlib.Path | str | None) – Default empty string which means search the entire package. Further narrows down search, so as to differentiate between folders which contain file with the same file name

  • logger_package_name (str | None) – Set logger to the intended package name. Default None which leaves as-is

Returns:

relative destination path to validated logging config YAML file and the yaml str

Return type:

tuple[str, str]

Raises: