Coverage for navigaattori/__init__.py: 100.00%
43 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 20:46:10 +00:00
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 20:46:10 +00:00
1"""Navigator (Finnish: navigaattori) guided by conventions."""
3import datetime as dti
4import logging
5import os
6import pathlib
7from typing import List, no_type_check
9# [[[fill git_describe()]]]
10__version__ = '2023.12.4+parent.g61f6a8c6'
11# [[[end]]] (checksum: e9c54065f2ecc530c9d172b09c558834)
12__version_info__ = tuple(
13 e if '-' not in e else e.split('-')[0] for part in __version__.split('+') for e in part.split('.') if e != 'parent'
14)
16APP_ALIAS = str(pathlib.Path(__file__).parent.name)
17APP_ENV = APP_ALIAS.upper()
18APP_NAME = locals()['__doc__']
19DEBUG = bool(os.getenv(f'{APP_ENV}_DEBUG', ''))
20VERBOSE = bool(os.getenv(f'{APP_ENV}_VERBOSE', ''))
21QUIET = False
22STRICT = bool(os.getenv(f'{APP_ENV}_STRICT', ''))
23ENCODING = 'utf-8'
24ENCODING_ERRORS_POLICY = 'ignore'
25DEFAULT_CONFIG_NAME = f'.{APP_ALIAS}.json'
27COMMA = ','
28DEFAULT_LF_ONLY = 'YES'
29GUESSED_STRUCTURES_FOLDER_NAME = 'GUESSED_STRUCTURES'
30STRUCTURES_KEY = 'structures'
31HUB_NAME = f'{STRUCTURES_KEY}.yml'
32DEFAULT_STRUCTURE_NAME = 'structure.yml'
33log = logging.getLogger() # Module level logger is sufficient
34LOG_FOLDER = pathlib.Path('logs')
35LOG_FILE = f'{APP_ALIAS}.log'
36LOG_PATH = pathlib.Path(LOG_FOLDER, LOG_FILE) if LOG_FOLDER.is_dir() else pathlib.Path(LOG_FILE)
37LOG_LEVEL = logging.INFO
39TS_FORMAT_LOG = '%Y-%m-%dT%H:%M:%S'
40TS_FORMAT_PAYLOADS = '%Y-%m-%d %H:%M:%S.%f UTC'
42__all__: List[str] = [
43 'DEFAULT_STRUCTURE_NAME',
44 'ENCODING',
45 'GUESSED_STRUCTURES_FOLDER_NAME',
46 'HUB_NAME',
47 'STRUCTURES_KEY',
48 'log',
49 'parse_csl',
50]
53def parse_csl(csl: str) -> List[str]:
54 """DRY."""
55 return [fmt.strip().lower() for fmt in csl.split(COMMA) if fmt.strip()]
58@no_type_check
59def formatTime_RFC3339(self, record, datefmt=None): # noqa
60 """HACK A DID ACK we could inject .astimezone() to localize ..."""
61 return dti.datetime.fromtimestamp(record.created, dti.timezone.utc).isoformat() # pragma: no cover
64@no_type_check
65def init_logger(name=None, level=None):
66 """Initialize module level logger"""
67 global log # pylint: disable=global-statement
69 log_format = {
70 'format': '%(asctime)s %(levelname)s [%(name)s]: %(message)s',
71 'datefmt': TS_FORMAT_LOG,
72 # 'filename': LOG_PATH,
73 'level': LOG_LEVEL if level is None else level,
74 }
75 logging.Formatter.formatTime = formatTime_RFC3339
76 logging.basicConfig(**log_format)
77 log = logging.getLogger(APP_ENV if name is None else name)
78 log.propagate = True
81init_logger(name=APP_ENV, level=logging.DEBUG if DEBUG else None)