fire2a
This is Wildfires/Forest Fire Advanced Analytics (fire2a) algorithms library 🌲🔥🧠📚 api documentation.
Get it from PyPI: pip install fire2a-lib
Important links:
End user documentation : https://fire2a.github.io/docs Use our tools with zero coding!
Source code and development tips : https://github.com/fire2a/fire2a-lib Get help or contribute!
Public contact : e-mail
Public website : www.fire2a.com
Please browse or search using the sidebar to the left!
1#!python3 2"""This is Wildfires/Forest Fire Advanced Analytics (fire2a) algorithms library 🌲🔥🧠📚 api documentation. 3 4Get it from [PyPI](https://pypi.org/project/fire2a-lib/): `pip install fire2a-lib` 5 6Important links: 7 8End user documentation : https://fire2a.github.io/docs <font color="red">Use our tools with zero coding!</font> 9 10Source code and development tips : https://github.com/fire2a/fire2a-lib Get help or contribute! 11 12Public contact : <a href="mailto:[fire2a@fire2a.com]">e-mail</a> 13 14Public website : www.fire2a.com 15 16Please browse or search using the sidebar to the left! 17""" 18__author__ = "Fernando Badilla" 19__revision__ = "$Format:%H$" 20 21import logging 22from importlib.metadata import PackageNotFoundError, distribution 23from pathlib import Path 24from typing import Any, Dict, List, Tuple, Union 25 26logger = logging.getLogger(__name__) 27"""@private""" 28 29try: 30 __version__ = distribution("fire2a-lib").version 31 version_from = "importlib" 32except PackageNotFoundError: 33 if (Path(__file__).parent / "_version.py").exists(): 34 from ._version import __version__ 35 36 version_from = "_version.py" 37 else: 38 __version__ = "0.0.0" 39 version_from = "fallback" 40 41# logger.warning("%s Package version: %s, from %s", __name__, __version__, version_from) 42 43 44def setup_logger(name: str = __name__, verbosity: int = 0, logfile: Path = None): 45 r"""Capture the logger and setup name, verbosity, stream handler & rotating logfile if provided. 46 Args: 47 name (str, optional): Name of the logger. Defaults to \__name __ 48 verbosity (str | int): Verbosity level, implemented, WARNING:1, INFO:2 (default), or DEBUG:3 49 logfile (Path, optional): Create a -rotated- logfile (5 files, 25MB each). 50 Returns: 51 logger (Logger): All code in this pkg uses logger.info("..."), logger.debug, etc. 52 53 ## Developers implementing their own logger 54 * All fire2a modules uses `logger = logging.getLogger(__name__)` 55 56 # Regular Usage Guideline 57 logging.critical("Something went wrong, exception info?", exc_info=True) 58 logging.error("Something went wrong, but we keep going?") 59 logging.warning("Default message level") 60 logging.info("Something planned happened") 61 logging.debug("Details of the planned thing that happened") 62 print("Normal program output, not logged") 63 """ # fmt: skip 64 # Capture the logger 65 if name: 66 # specific logger 67 logger = logging.getLogger(name) 68 else: 69 # root logger 70 logger = logging.getLogger() 71 72 # Create a stream handler 73 import sys 74 75 stream_handler = logging.StreamHandler(sys.stdout) 76 77 # Create a rotating file handler 78 if logfile: 79 from logging.handlers import RotatingFileHandler 80 81 rf_handler = RotatingFileHandler(logfile, maxBytes=25 * 1024, backupCount=5) 82 83 # Set the logs level 84 if verbosity in ["CRITICAL", "FATAL"] or verbosity == -1: 85 level = logging.CRITICAL 86 elif verbosity == "ERROR" or verbosity == 0: 87 level = logging.WARNING 88 elif verbosity == "WARNING" or verbosity == 1: 89 level = logging.WARNING 90 elif verbosity == "INFO" or verbosity == 2: 91 level = logging.INFO 92 elif verbosity == "DEBUG" or verbosity == 3: 93 level = logging.DEBUG 94 else: 95 level = logging.DEBUG 96 logger.setLevel(level) 97 stream_handler.setLevel(level) 98 if logfile: 99 rf_handler.setLevel(level) 100 101 # formatter 102 # "%(asctime)s %(levelname)s %(name)s %(filename)s:%(lineno)d %(message)s", datefmt="%Y-%m-%d %H:%M:%S" 103 formatter = logging.Formatter( 104 "%(asctime)s %(levelname)s %(name)s %(message)s", 105 datefmt="%Y-%m-%d %H:%M:%S", 106 ) 107 stream_handler.setFormatter(formatter) 108 if logfile: 109 rf_handler.setFormatter(formatter) 110 111 # Add the handlers to the logger 112 logger.addHandler(stream_handler) 113 if logfile: 114 logger.addHandler(rf_handler) 115 logger.debug("Logger initialized @level %s", logging.getLevelName(level)) 116 117 return logger 118 119 120def setup_file(name="unknown", filepath=Path().cwd()): 121 """Setups the NAME and FILEPATH variables for modules 122 Tries getting them from __main__.__file__ and __main__.__package__ 123 If it's the __main__ entry point, tries to use the package name 124 Args: 125 main: __main__ from the calling script 126 name: if fails, returns name (default "unknown") 127 here: if fails, returns here Path (default "cwd") 128 """ 129 import __main__ 130 131 if filestr := getattr(__main__, "__file__", None): 132 file = Path(filestr) 133 NAME = file.stem 134 if NAME == "__main__": 135 if package := getattr(__main__, "__package__", None): 136 NAME = package + "_main" 137 else: 138 NAME = name 139 FILEPATH = file.parent 140 else: 141 NAME = name 142 FILEPATH = filepath 143 logger.warning("setup_file(%s, %s) __main__:%s", NAME, FILEPATH, __main__) 144 return NAME, FILEPATH
45def setup_logger(name: str = __name__, verbosity: int = 0, logfile: Path = None): 46 r"""Capture the logger and setup name, verbosity, stream handler & rotating logfile if provided. 47 Args: 48 name (str, optional): Name of the logger. Defaults to \__name __ 49 verbosity (str | int): Verbosity level, implemented, WARNING:1, INFO:2 (default), or DEBUG:3 50 logfile (Path, optional): Create a -rotated- logfile (5 files, 25MB each). 51 Returns: 52 logger (Logger): All code in this pkg uses logger.info("..."), logger.debug, etc. 53 54 ## Developers implementing their own logger 55 * All fire2a modules uses `logger = logging.getLogger(__name__)` 56 57 # Regular Usage Guideline 58 logging.critical("Something went wrong, exception info?", exc_info=True) 59 logging.error("Something went wrong, but we keep going?") 60 logging.warning("Default message level") 61 logging.info("Something planned happened") 62 logging.debug("Details of the planned thing that happened") 63 print("Normal program output, not logged") 64 """ # fmt: skip 65 # Capture the logger 66 if name: 67 # specific logger 68 logger = logging.getLogger(name) 69 else: 70 # root logger 71 logger = logging.getLogger() 72 73 # Create a stream handler 74 import sys 75 76 stream_handler = logging.StreamHandler(sys.stdout) 77 78 # Create a rotating file handler 79 if logfile: 80 from logging.handlers import RotatingFileHandler 81 82 rf_handler = RotatingFileHandler(logfile, maxBytes=25 * 1024, backupCount=5) 83 84 # Set the logs level 85 if verbosity in ["CRITICAL", "FATAL"] or verbosity == -1: 86 level = logging.CRITICAL 87 elif verbosity == "ERROR" or verbosity == 0: 88 level = logging.WARNING 89 elif verbosity == "WARNING" or verbosity == 1: 90 level = logging.WARNING 91 elif verbosity == "INFO" or verbosity == 2: 92 level = logging.INFO 93 elif verbosity == "DEBUG" or verbosity == 3: 94 level = logging.DEBUG 95 else: 96 level = logging.DEBUG 97 logger.setLevel(level) 98 stream_handler.setLevel(level) 99 if logfile: 100 rf_handler.setLevel(level) 101 102 # formatter 103 # "%(asctime)s %(levelname)s %(name)s %(filename)s:%(lineno)d %(message)s", datefmt="%Y-%m-%d %H:%M:%S" 104 formatter = logging.Formatter( 105 "%(asctime)s %(levelname)s %(name)s %(message)s", 106 datefmt="%Y-%m-%d %H:%M:%S", 107 ) 108 stream_handler.setFormatter(formatter) 109 if logfile: 110 rf_handler.setFormatter(formatter) 111 112 # Add the handlers to the logger 113 logger.addHandler(stream_handler) 114 if logfile: 115 logger.addHandler(rf_handler) 116 logger.debug("Logger initialized @level %s", logging.getLevelName(level)) 117 118 return logger
Capture the logger and setup name, verbosity, stream handler & rotating logfile if provided. Args: name (str, optional): Name of the logger. Defaults to __name __ verbosity (str | int): Verbosity level, implemented, WARNING:1, INFO:2 (default), or DEBUG:3 logfile (Path, optional): Create a -rotated- logfile (5 files, 25MB each). Returns: logger (Logger): All code in this pkg uses logger.info("..."), logger.debug, etc.
Developers implementing their own logger
* All fire2a modules uses `logger = logging.getLogger(__name__)`
Regular Usage Guideline
logging.critical("Something went wrong, exception info?", exc_info=True)
logging.error("Something went wrong, but we keep going?")
logging.warning("Default message level")
logging.info("Something planned happened")
logging.debug("Details of the planned thing that happened")
print("Normal program output, not logged")
121def setup_file(name="unknown", filepath=Path().cwd()): 122 """Setups the NAME and FILEPATH variables for modules 123 Tries getting them from __main__.__file__ and __main__.__package__ 124 If it's the __main__ entry point, tries to use the package name 125 Args: 126 main: __main__ from the calling script 127 name: if fails, returns name (default "unknown") 128 here: if fails, returns here Path (default "cwd") 129 """ 130 import __main__ 131 132 if filestr := getattr(__main__, "__file__", None): 133 file = Path(filestr) 134 NAME = file.stem 135 if NAME == "__main__": 136 if package := getattr(__main__, "__package__", None): 137 NAME = package + "_main" 138 else: 139 NAME = name 140 FILEPATH = file.parent 141 else: 142 NAME = name 143 FILEPATH = filepath 144 logger.warning("setup_file(%s, %s) __main__:%s", NAME, FILEPATH, __main__) 145 return NAME, FILEPATH
Setups the NAME and FILEPATH variables for modules Tries getting them from __main__.__file__ and __main__.__package__ If it's the __main__ entry point, tries to use the package name Args: main: __main__ from the calling script name: if fails, returns name (default "unknown") here: if fails, returns here Path (default "cwd")