Spaces:
				
			
			
	
			
			
		Paused
		
	
	
	
			
			
	
	
	
	
		
		
		Paused
		
	:recycle: [Refactor] Use tclogger, and configure envs better
Browse files- apis/chat_api.py +1 -1
 - constants/env.py +15 -0
 - messagers/message_composer.py +1 -1
 - mocks/stream_chat_mocker.py +1 -1
 - networks/message_streamer.py +3 -5
 - utils/__init__.py +0 -69
 - utils/enver.py +0 -60
 - utils/logger.py +0 -269
 
    	
        apis/chat_api.py
    CHANGED
    
    | 
         @@ -16,7 +16,7 @@ from sse_starlette.sse import EventSourceResponse, ServerSentEvent 
     | 
|
| 16 | 
         
             
            from messagers.message_composer import MessageComposer
         
     | 
| 17 | 
         
             
            from mocks.stream_chat_mocker import stream_chat_mock
         
     | 
| 18 | 
         
             
            from networks.message_streamer import MessageStreamer
         
     | 
| 19 | 
         
            -
            from  
     | 
| 20 | 
         
             
            from constants.models import AVAILABLE_MODELS_DICTS
         
     | 
| 21 | 
         | 
| 22 | 
         | 
| 
         | 
|
| 16 | 
         
             
            from messagers.message_composer import MessageComposer
         
     | 
| 17 | 
         
             
            from mocks.stream_chat_mocker import stream_chat_mock
         
     | 
| 18 | 
         
             
            from networks.message_streamer import MessageStreamer
         
     | 
| 19 | 
         
            +
            from tclogger import logger
         
     | 
| 20 | 
         
             
            from constants.models import AVAILABLE_MODELS_DICTS
         
     | 
| 21 | 
         | 
| 22 | 
         | 
    	
        constants/env.py
    ADDED
    
    | 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
| 
         | 
|
| 1 | 
         
            +
            from pathlib import Path
         
     | 
| 2 | 
         
            +
            from tclogger import logger, OSEnver
         
     | 
| 3 | 
         
            +
             
     | 
| 4 | 
         
            +
            secrets_path = Path(__file__).parents[1] / "secrets.json"
         
     | 
| 5 | 
         
            +
            ENVER = OSEnver(secrets_path)
         
     | 
| 6 | 
         
            +
             
     | 
| 7 | 
         
            +
            http_proxy = ENVER["http_proxy"]
         
     | 
| 8 | 
         
            +
            if http_proxy:
         
     | 
| 9 | 
         
            +
                logger.note(f"> Using proxy: {http_proxy}")
         
     | 
| 10 | 
         
            +
                PROXIES = {
         
     | 
| 11 | 
         
            +
                    "http": http_proxy,
         
     | 
| 12 | 
         
            +
                    "https": http_proxy,
         
     | 
| 13 | 
         
            +
                }
         
     | 
| 14 | 
         
            +
            else:
         
     | 
| 15 | 
         
            +
                PROXIES = None
         
     | 
    	
        messagers/message_composer.py
    CHANGED
    
    | 
         @@ -4,7 +4,7 @@ from pprint import pprint 
     | 
|
| 4 | 
         
             
            from transformers import AutoTokenizer
         
     | 
| 5 | 
         | 
| 6 | 
         
             
            from constants.models import AVAILABLE_MODELS, MODEL_MAP
         
     | 
| 7 | 
         
            -
            from  
     | 
| 8 | 
         | 
| 9 | 
         | 
| 10 | 
         
             
            class MessageComposer:
         
     | 
| 
         | 
|
| 4 | 
         
             
            from transformers import AutoTokenizer
         
     | 
| 5 | 
         | 
| 6 | 
         
             
            from constants.models import AVAILABLE_MODELS, MODEL_MAP
         
     | 
| 7 | 
         
            +
            from tclogger import logger
         
     | 
| 8 | 
         | 
| 9 | 
         | 
| 10 | 
         
             
            class MessageComposer:
         
     | 
    	
        mocks/stream_chat_mocker.py
    CHANGED
    
    | 
         @@ -1,5 +1,5 @@ 
     | 
|
| 1 | 
         
             
            import time
         
     | 
| 2 | 
         
            -
            from  
     | 
| 3 | 
         | 
| 4 | 
         | 
| 5 | 
         
             
            def stream_chat_mock(*args, **kwargs):
         
     | 
| 
         | 
|
| 1 | 
         
             
            import time
         
     | 
| 2 | 
         
            +
            from tclogger import logger
         
     | 
| 3 | 
         | 
| 4 | 
         | 
| 5 | 
         
             
            def stream_chat_mock(*args, **kwargs):
         
     | 
    	
        networks/message_streamer.py
    CHANGED
    
    | 
         @@ -2,6 +2,7 @@ import json 
     | 
|
| 2 | 
         
             
            import re
         
     | 
| 3 | 
         
             
            import requests
         
     | 
| 4 | 
         | 
| 
         | 
|
| 5 | 
         
             
            from tiktoken import get_encoding as tiktoken_get_encoding
         
     | 
| 6 | 
         
             
            from transformers import AutoTokenizer
         
     | 
| 7 | 
         | 
| 
         @@ -11,13 +12,11 @@ from constants.models import ( 
     | 
|
| 11 | 
         
             
                TOKEN_LIMIT_MAP,
         
     | 
| 12 | 
         
             
                TOKEN_RESERVED,
         
     | 
| 13 | 
         
             
            )
         
     | 
| 
         | 
|
| 14 | 
         
             
            from messagers.message_outputer import OpenaiStreamOutputer
         
     | 
| 15 | 
         
            -
            from utils.logger import logger
         
     | 
| 16 | 
         
            -
            from utils.enver import enver
         
     | 
| 17 | 
         | 
| 18 | 
         | 
| 19 | 
         
             
            class MessageStreamer:
         
     | 
| 20 | 
         
            -
             
     | 
| 21 | 
         
             
                def __init__(self, model: str):
         
     | 
| 22 | 
         
             
                    if model in MODEL_MAP.keys():
         
     | 
| 23 | 
         
             
                        self.model = model
         
     | 
| 
         @@ -120,12 +119,11 @@ class MessageStreamer: 
     | 
|
| 120 | 
         
             
                    #     ]
         
     | 
| 121 | 
         | 
| 122 | 
         
             
                    logger.back(self.request_url)
         
     | 
| 123 | 
         
            -
                    enver.set_envs(proxies=True)
         
     | 
| 124 | 
         
             
                    stream_response = requests.post(
         
     | 
| 125 | 
         
             
                        self.request_url,
         
     | 
| 126 | 
         
             
                        headers=self.request_headers,
         
     | 
| 127 | 
         
             
                        json=self.request_body,
         
     | 
| 128 | 
         
            -
                        proxies= 
     | 
| 129 | 
         
             
                        stream=True,
         
     | 
| 130 | 
         
             
                    )
         
     | 
| 131 | 
         
             
                    status_code = stream_response.status_code
         
     | 
| 
         | 
|
| 2 | 
         
             
            import re
         
     | 
| 3 | 
         
             
            import requests
         
     | 
| 4 | 
         | 
| 5 | 
         
            +
            from tclogger import logger
         
     | 
| 6 | 
         
             
            from tiktoken import get_encoding as tiktoken_get_encoding
         
     | 
| 7 | 
         
             
            from transformers import AutoTokenizer
         
     | 
| 8 | 
         | 
| 
         | 
|
| 12 | 
         
             
                TOKEN_LIMIT_MAP,
         
     | 
| 13 | 
         
             
                TOKEN_RESERVED,
         
     | 
| 14 | 
         
             
            )
         
     | 
| 15 | 
         
            +
            from constants.env import PROXIES
         
     | 
| 16 | 
         
             
            from messagers.message_outputer import OpenaiStreamOutputer
         
     | 
| 
         | 
|
| 
         | 
|
| 17 | 
         | 
| 18 | 
         | 
| 19 | 
         
             
            class MessageStreamer:
         
     | 
| 
         | 
|
| 20 | 
         
             
                def __init__(self, model: str):
         
     | 
| 21 | 
         
             
                    if model in MODEL_MAP.keys():
         
     | 
| 22 | 
         
             
                        self.model = model
         
     | 
| 
         | 
|
| 119 | 
         
             
                    #     ]
         
     | 
| 120 | 
         | 
| 121 | 
         
             
                    logger.back(self.request_url)
         
     | 
| 
         | 
|
| 122 | 
         
             
                    stream_response = requests.post(
         
     | 
| 123 | 
         
             
                        self.request_url,
         
     | 
| 124 | 
         
             
                        headers=self.request_headers,
         
     | 
| 125 | 
         
             
                        json=self.request_body,
         
     | 
| 126 | 
         
            +
                        proxies=PROXIES,
         
     | 
| 127 | 
         
             
                        stream=True,
         
     | 
| 128 | 
         
             
                    )
         
     | 
| 129 | 
         
             
                    status_code = stream_response.status_code
         
     | 
    	
        utils/__init__.py
    DELETED
    
    | 
         @@ -1,69 +0,0 @@ 
     | 
|
| 1 | 
         
            -
            import json
         
     | 
| 2 | 
         
            -
            import requests
         
     | 
| 3 | 
         
            -
            import os
         
     | 
| 4 | 
         
            -
             
     | 
| 5 | 
         
            -
            from pathlib import Path
         
     | 
| 6 | 
         
            -
             
     | 
| 7 | 
         
            -
             
     | 
| 8 | 
         
            -
            class OSEnver:
         
     | 
| 9 | 
         
            -
                def __init__(self):
         
     | 
| 10 | 
         
            -
                    self.envs_stack = []
         
     | 
| 11 | 
         
            -
                    self.envs = os.environ.copy()
         
     | 
| 12 | 
         
            -
             
     | 
| 13 | 
         
            -
                def store_envs(self):
         
     | 
| 14 | 
         
            -
                    self.envs_stack.append(self.envs)
         
     | 
| 15 | 
         
            -
             
     | 
| 16 | 
         
            -
                def restore_envs(self):
         
     | 
| 17 | 
         
            -
                    self.envs = self.envs_stack.pop()
         
     | 
| 18 | 
         
            -
                    if self.global_scope:
         
     | 
| 19 | 
         
            -
                        os.environ = self.envs
         
     | 
| 20 | 
         
            -
             
     | 
| 21 | 
         
            -
                def set_envs(self, secrets=True, proxies=None, store_envs=True):
         
     | 
| 22 | 
         
            -
                    # caller_info = inspect.stack()[1]
         
     | 
| 23 | 
         
            -
                    # logger.back(f"OS Envs is set by: {caller_info.filename}")
         
     | 
| 24 | 
         
            -
             
     | 
| 25 | 
         
            -
                    if store_envs:
         
     | 
| 26 | 
         
            -
                        self.store_envs()
         
     | 
| 27 | 
         
            -
             
     | 
| 28 | 
         
            -
                    if secrets:
         
     | 
| 29 | 
         
            -
                        secrets_path = Path(__file__).parents[1] / "secrets.json"
         
     | 
| 30 | 
         
            -
                        if secrets_path.exists():
         
     | 
| 31 | 
         
            -
                            with open(secrets_path, "r") as rf:
         
     | 
| 32 | 
         
            -
                                secrets = json.load(rf)
         
     | 
| 33 | 
         
            -
                        else:
         
     | 
| 34 | 
         
            -
                            secrets = {}
         
     | 
| 35 | 
         
            -
             
     | 
| 36 | 
         
            -
                    if proxies:
         
     | 
| 37 | 
         
            -
                        for proxy_env in ["http_proxy", "https_proxy"]:
         
     | 
| 38 | 
         
            -
                            if isinstance(proxies, str):
         
     | 
| 39 | 
         
            -
                                self.envs[proxy_env] = proxies
         
     | 
| 40 | 
         
            -
                            elif "http_proxy" in secrets.keys():
         
     | 
| 41 | 
         
            -
                                self.envs[proxy_env] = secrets["http_proxy"]
         
     | 
| 42 | 
         
            -
                            elif os.getenv("http_proxy"):
         
     | 
| 43 | 
         
            -
                                self.envs[proxy_env] = os.getenv("http_proxy")
         
     | 
| 44 | 
         
            -
                            else:
         
     | 
| 45 | 
         
            -
                                continue
         
     | 
| 46 | 
         
            -
             
     | 
| 47 | 
         
            -
                    self.proxy = (
         
     | 
| 48 | 
         
            -
                        self.envs.get("all_proxy")
         
     | 
| 49 | 
         
            -
                        or self.envs.get("http_proxy")
         
     | 
| 50 | 
         
            -
                        or self.envs.get("https_proxy")
         
     | 
| 51 | 
         
            -
                        or None
         
     | 
| 52 | 
         
            -
                    )
         
     | 
| 53 | 
         
            -
                    self.requests_proxies = {
         
     | 
| 54 | 
         
            -
                        "http": self.proxy,
         
     | 
| 55 | 
         
            -
                        "https": self.proxy,
         
     | 
| 56 | 
         
            -
                    }
         
     | 
| 57 | 
         
            -
             
     | 
| 58 | 
         
            -
                    # https://www.proxynova.com/proxy-server-list/country-us/
         
     | 
| 59 | 
         
            -
             
     | 
| 60 | 
         
            -
                    print(f"Using proxy: [{self.proxy}]")
         
     | 
| 61 | 
         
            -
                    # r = requests.get(
         
     | 
| 62 | 
         
            -
                    #     "http://ifconfig.me/ip",
         
     | 
| 63 | 
         
            -
                    #     proxies=self.requests_proxies,
         
     | 
| 64 | 
         
            -
                    #     timeout=10,
         
     | 
| 65 | 
         
            -
                    # )
         
     | 
| 66 | 
         
            -
                    # print(f"[r.status_code] r.text")
         
     | 
| 67 | 
         
            -
             
     | 
| 68 | 
         
            -
             
     | 
| 69 | 
         
            -
            enver = OSEnver()
         
     | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
    	
        utils/enver.py
    DELETED
    
    | 
         @@ -1,60 +0,0 @@ 
     | 
|
| 1 | 
         
            -
            import json
         
     | 
| 2 | 
         
            -
            import os
         
     | 
| 3 | 
         
            -
             
     | 
| 4 | 
         
            -
            from pathlib import Path
         
     | 
| 5 | 
         
            -
            from utils.logger import logger
         
     | 
| 6 | 
         
            -
             
     | 
| 7 | 
         
            -
             
     | 
| 8 | 
         
            -
            class OSEnver:
         
     | 
| 9 | 
         
            -
                def __init__(self):
         
     | 
| 10 | 
         
            -
                    self.envs_stack = []
         
     | 
| 11 | 
         
            -
                    self.envs = os.environ.copy()
         
     | 
| 12 | 
         
            -
             
     | 
| 13 | 
         
            -
                def store_envs(self):
         
     | 
| 14 | 
         
            -
                    self.envs_stack.append(self.envs)
         
     | 
| 15 | 
         
            -
             
     | 
| 16 | 
         
            -
                def restore_envs(self):
         
     | 
| 17 | 
         
            -
                    self.envs = self.envs_stack.pop()
         
     | 
| 18 | 
         
            -
             
     | 
| 19 | 
         
            -
                def set_envs(self, secrets=True, proxies=None, store_envs=True):
         
     | 
| 20 | 
         
            -
                    # caller_info = inspect.stack()[1]
         
     | 
| 21 | 
         
            -
                    # logger.back(f"OS Envs is set by: {caller_info.filename}")
         
     | 
| 22 | 
         
            -
             
     | 
| 23 | 
         
            -
                    if store_envs:
         
     | 
| 24 | 
         
            -
                        self.store_envs()
         
     | 
| 25 | 
         
            -
             
     | 
| 26 | 
         
            -
                    if secrets:
         
     | 
| 27 | 
         
            -
                        secrets_path = Path(__file__).parents[1] / "secrets.json"
         
     | 
| 28 | 
         
            -
                        if secrets_path.exists():
         
     | 
| 29 | 
         
            -
                            with open(secrets_path, "r") as rf:
         
     | 
| 30 | 
         
            -
                                secrets = json.load(rf)
         
     | 
| 31 | 
         
            -
                        else:
         
     | 
| 32 | 
         
            -
                            secrets = {}
         
     | 
| 33 | 
         
            -
             
     | 
| 34 | 
         
            -
                    if proxies:
         
     | 
| 35 | 
         
            -
                        for proxy_env in ["http_proxy", "https_proxy"]:
         
     | 
| 36 | 
         
            -
                            if isinstance(proxies, str):
         
     | 
| 37 | 
         
            -
                                self.envs[proxy_env] = proxies
         
     | 
| 38 | 
         
            -
                            elif "http_proxy" in secrets.keys():
         
     | 
| 39 | 
         
            -
                                self.envs[proxy_env] = secrets["http_proxy"]
         
     | 
| 40 | 
         
            -
                            elif os.getenv("http_proxy"):
         
     | 
| 41 | 
         
            -
                                self.envs[proxy_env] = os.getenv("http_proxy")
         
     | 
| 42 | 
         
            -
                            else:
         
     | 
| 43 | 
         
            -
                                continue
         
     | 
| 44 | 
         
            -
             
     | 
| 45 | 
         
            -
                    self.proxy = (
         
     | 
| 46 | 
         
            -
                        self.envs.get("all_proxy")
         
     | 
| 47 | 
         
            -
                        or self.envs.get("http_proxy")
         
     | 
| 48 | 
         
            -
                        or self.envs.get("https_proxy")
         
     | 
| 49 | 
         
            -
                        or None
         
     | 
| 50 | 
         
            -
                    )
         
     | 
| 51 | 
         
            -
                    self.requests_proxies = {
         
     | 
| 52 | 
         
            -
                        "http": self.proxy,
         
     | 
| 53 | 
         
            -
                        "https": self.proxy,
         
     | 
| 54 | 
         
            -
                    }
         
     | 
| 55 | 
         
            -
             
     | 
| 56 | 
         
            -
                    if self.proxy:
         
     | 
| 57 | 
         
            -
                        logger.note(f"Using proxy: [{self.proxy}]")
         
     | 
| 58 | 
         
            -
             
     | 
| 59 | 
         
            -
             
     | 
| 60 | 
         
            -
            enver = OSEnver()
         
     | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
    	
        utils/logger.py
    DELETED
    
    | 
         @@ -1,269 +0,0 @@ 
     | 
|
| 1 | 
         
            -
            import datetime
         
     | 
| 2 | 
         
            -
            import functools
         
     | 
| 3 | 
         
            -
            import inspect
         
     | 
| 4 | 
         
            -
            import logging
         
     | 
| 5 | 
         
            -
            import os
         
     | 
| 6 | 
         
            -
            import shutil
         
     | 
| 7 | 
         
            -
            import subprocess
         
     | 
| 8 | 
         
            -
            from termcolor import colored
         
     | 
| 9 | 
         
            -
             
     | 
| 10 | 
         
            -
             
     | 
| 11 | 
         
            -
            def add_fillers(text, filler="=", fill_side="both"):
         
     | 
| 12 | 
         
            -
                terminal_width = shutil.get_terminal_size().columns
         
     | 
| 13 | 
         
            -
                text = text.strip()
         
     | 
| 14 | 
         
            -
                text_width = len(text)
         
     | 
| 15 | 
         
            -
                if text_width >= terminal_width:
         
     | 
| 16 | 
         
            -
                    return text
         
     | 
| 17 | 
         
            -
             
     | 
| 18 | 
         
            -
                if fill_side[0].lower() == "b":
         
     | 
| 19 | 
         
            -
                    leading_fill_str = filler * ((terminal_width - text_width) // 2 - 1) + " "
         
     | 
| 20 | 
         
            -
                    trailing_fill_str = " " + filler * (
         
     | 
| 21 | 
         
            -
                        terminal_width - text_width - len(leading_fill_str) - 1
         
     | 
| 22 | 
         
            -
                    )
         
     | 
| 23 | 
         
            -
                elif fill_side[0].lower() == "l":
         
     | 
| 24 | 
         
            -
                    leading_fill_str = filler * (terminal_width - text_width - 1) + " "
         
     | 
| 25 | 
         
            -
                    trailing_fill_str = ""
         
     | 
| 26 | 
         
            -
                elif fill_side[0].lower() == "r":
         
     | 
| 27 | 
         
            -
                    leading_fill_str = ""
         
     | 
| 28 | 
         
            -
                    trailing_fill_str = " " + filler * (terminal_width - text_width - 1)
         
     | 
| 29 | 
         
            -
                else:
         
     | 
| 30 | 
         
            -
                    raise ValueError("Invalid fill_side")
         
     | 
| 31 | 
         
            -
             
     | 
| 32 | 
         
            -
                filled_str = f"{leading_fill_str}{text}{trailing_fill_str}"
         
     | 
| 33 | 
         
            -
                return filled_str
         
     | 
| 34 | 
         
            -
             
     | 
| 35 | 
         
            -
             
     | 
| 36 | 
         
            -
            class OSLogger(logging.Logger):
         
     | 
| 37 | 
         
            -
                LOG_METHODS = {
         
     | 
| 38 | 
         
            -
                    "err": ("error", "red"),
         
     | 
| 39 | 
         
            -
                    "warn": ("warning", "light_red"),
         
     | 
| 40 | 
         
            -
                    "note": ("info", "light_magenta"),
         
     | 
| 41 | 
         
            -
                    "mesg": ("info", "light_cyan"),
         
     | 
| 42 | 
         
            -
                    "file": ("info", "light_blue"),
         
     | 
| 43 | 
         
            -
                    "line": ("info", "white"),
         
     | 
| 44 | 
         
            -
                    "success": ("info", "light_green"),
         
     | 
| 45 | 
         
            -
                    "fail": ("info", "light_red"),
         
     | 
| 46 | 
         
            -
                    "back": ("debug", "light_cyan"),
         
     | 
| 47 | 
         
            -
                }
         
     | 
| 48 | 
         
            -
                INDENT_METHODS = [
         
     | 
| 49 | 
         
            -
                    "indent",
         
     | 
| 50 | 
         
            -
                    "set_indent",
         
     | 
| 51 | 
         
            -
                    "reset_indent",
         
     | 
| 52 | 
         
            -
                    "store_indent",
         
     | 
| 53 | 
         
            -
                    "restore_indent",
         
     | 
| 54 | 
         
            -
                    "log_indent",
         
     | 
| 55 | 
         
            -
                ]
         
     | 
| 56 | 
         
            -
                LEVEL_METHODS = [
         
     | 
| 57 | 
         
            -
                    "set_level",
         
     | 
| 58 | 
         
            -
                    "store_level",
         
     | 
| 59 | 
         
            -
                    "restore_level",
         
     | 
| 60 | 
         
            -
                    "quiet",
         
     | 
| 61 | 
         
            -
                    "enter_quiet",
         
     | 
| 62 | 
         
            -
                    "exit_quiet",
         
     | 
| 63 | 
         
            -
                ]
         
     | 
| 64 | 
         
            -
                LEVEL_NAMES = {
         
     | 
| 65 | 
         
            -
                    "critical": logging.CRITICAL,
         
     | 
| 66 | 
         
            -
                    "error": logging.ERROR,
         
     | 
| 67 | 
         
            -
                    "warning": logging.WARNING,
         
     | 
| 68 | 
         
            -
                    "info": logging.INFO,
         
     | 
| 69 | 
         
            -
                    "debug": logging.DEBUG,
         
     | 
| 70 | 
         
            -
                }
         
     | 
| 71 | 
         
            -
             
     | 
| 72 | 
         
            -
                def __init__(self, name=None, prefix=False):
         
     | 
| 73 | 
         
            -
                    if not name:
         
     | 
| 74 | 
         
            -
                        frame = inspect.stack()[1]
         
     | 
| 75 | 
         
            -
                        module = inspect.getmodule(frame[0])
         
     | 
| 76 | 
         
            -
                        name = module.__name__
         
     | 
| 77 | 
         
            -
             
     | 
| 78 | 
         
            -
                    super().__init__(name)
         
     | 
| 79 | 
         
            -
                    self.setLevel(logging.INFO)
         
     | 
| 80 | 
         
            -
             
     | 
| 81 | 
         
            -
                    if prefix:
         
     | 
| 82 | 
         
            -
                        formatter_prefix = "[%(asctime)s] - [%(name)s] - [%(levelname)s]\n"
         
     | 
| 83 | 
         
            -
                    else:
         
     | 
| 84 | 
         
            -
                        formatter_prefix = ""
         
     | 
| 85 | 
         
            -
             
     | 
| 86 | 
         
            -
                    self.formatter = logging.Formatter(formatter_prefix + "%(message)s")
         
     | 
| 87 | 
         
            -
             
     | 
| 88 | 
         
            -
                    stream_handler = logging.StreamHandler()
         
     | 
| 89 | 
         
            -
                    stream_handler.setLevel(logging.INFO)
         
     | 
| 90 | 
         
            -
                    stream_handler.setFormatter(self.formatter)
         
     | 
| 91 | 
         
            -
                    self.addHandler(stream_handler)
         
     | 
| 92 | 
         
            -
             
     | 
| 93 | 
         
            -
                    self.log_indent = 0
         
     | 
| 94 | 
         
            -
                    self.log_indents = []
         
     | 
| 95 | 
         
            -
             
     | 
| 96 | 
         
            -
                    self.log_level = "info"
         
     | 
| 97 | 
         
            -
                    self.log_levels = []
         
     | 
| 98 | 
         
            -
             
     | 
| 99 | 
         
            -
                def indent(self, indent=2):
         
     | 
| 100 | 
         
            -
                    self.log_indent += indent
         
     | 
| 101 | 
         
            -
             
     | 
| 102 | 
         
            -
                def set_indent(self, indent=2):
         
     | 
| 103 | 
         
            -
                    self.log_indent = indent
         
     | 
| 104 | 
         
            -
             
     | 
| 105 | 
         
            -
                def reset_indent(self):
         
     | 
| 106 | 
         
            -
                    self.log_indent = 0
         
     | 
| 107 | 
         
            -
             
     | 
| 108 | 
         
            -
                def store_indent(self):
         
     | 
| 109 | 
         
            -
                    self.log_indents.append(self.log_indent)
         
     | 
| 110 | 
         
            -
             
     | 
| 111 | 
         
            -
                def restore_indent(self):
         
     | 
| 112 | 
         
            -
                    self.log_indent = self.log_indents.pop(-1)
         
     | 
| 113 | 
         
            -
             
     | 
| 114 | 
         
            -
                def set_level(self, level):
         
     | 
| 115 | 
         
            -
                    self.log_level = level
         
     | 
| 116 | 
         
            -
                    self.setLevel(self.LEVEL_NAMES[level])
         
     | 
| 117 | 
         
            -
             
     | 
| 118 | 
         
            -
                def store_level(self):
         
     | 
| 119 | 
         
            -
                    self.log_levels.append(self.log_level)
         
     | 
| 120 | 
         
            -
             
     | 
| 121 | 
         
            -
                def restore_level(self):
         
     | 
| 122 | 
         
            -
                    self.log_level = self.log_levels.pop(-1)
         
     | 
| 123 | 
         
            -
                    self.set_level(self.log_level)
         
     | 
| 124 | 
         
            -
             
     | 
| 125 | 
         
            -
                def quiet(self):
         
     | 
| 126 | 
         
            -
                    self.set_level("critical")
         
     | 
| 127 | 
         
            -
             
     | 
| 128 | 
         
            -
                def enter_quiet(self, quiet=False):
         
     | 
| 129 | 
         
            -
                    if quiet:
         
     | 
| 130 | 
         
            -
                        self.store_level()
         
     | 
| 131 | 
         
            -
                        self.quiet()
         
     | 
| 132 | 
         
            -
             
     | 
| 133 | 
         
            -
                def exit_quiet(self, quiet=False):
         
     | 
| 134 | 
         
            -
                    if quiet:
         
     | 
| 135 | 
         
            -
                        self.restore_level()
         
     | 
| 136 | 
         
            -
             
     | 
| 137 | 
         
            -
                def log(
         
     | 
| 138 | 
         
            -
                    self,
         
     | 
| 139 | 
         
            -
                    level,
         
     | 
| 140 | 
         
            -
                    color,
         
     | 
| 141 | 
         
            -
                    msg,
         
     | 
| 142 | 
         
            -
                    indent=0,
         
     | 
| 143 | 
         
            -
                    fill=False,
         
     | 
| 144 | 
         
            -
                    fill_side="both",
         
     | 
| 145 | 
         
            -
                    end="\n",
         
     | 
| 146 | 
         
            -
                    *args,
         
     | 
| 147 | 
         
            -
                    **kwargs,
         
     | 
| 148 | 
         
            -
                ):
         
     | 
| 149 | 
         
            -
                    if type(msg) == str:
         
     | 
| 150 | 
         
            -
                        msg_str = msg
         
     | 
| 151 | 
         
            -
                    else:
         
     | 
| 152 | 
         
            -
                        msg_str = repr(msg)
         
     | 
| 153 | 
         
            -
                        quotes = ["'", '"']
         
     | 
| 154 | 
         
            -
                        if msg_str[0] in quotes and msg_str[-1] in quotes:
         
     | 
| 155 | 
         
            -
                            msg_str = msg_str[1:-1]
         
     | 
| 156 | 
         
            -
             
     | 
| 157 | 
         
            -
                    indent_str = " " * (self.log_indent + indent)
         
     | 
| 158 | 
         
            -
                    indented_msg = "\n".join([indent_str + line for line in msg_str.split("\n")])
         
     | 
| 159 | 
         
            -
             
     | 
| 160 | 
         
            -
                    if fill:
         
     | 
| 161 | 
         
            -
                        indented_msg = add_fillers(indented_msg, fill_side=fill_side)
         
     | 
| 162 | 
         
            -
             
     | 
| 163 | 
         
            -
                    handler = self.handlers[0]
         
     | 
| 164 | 
         
            -
                    handler.terminator = end
         
     | 
| 165 | 
         
            -
             
     | 
| 166 | 
         
            -
                    getattr(self, level)(colored(indented_msg, color), *args, **kwargs)
         
     | 
| 167 | 
         
            -
             
     | 
| 168 | 
         
            -
                def route_log(self, method, msg, *args, **kwargs):
         
     | 
| 169 | 
         
            -
                    level, method = method
         
     | 
| 170 | 
         
            -
                    functools.partial(self.log, level, method, msg)(*args, **kwargs)
         
     | 
| 171 | 
         
            -
             
     | 
| 172 | 
         
            -
                def err(self, msg: str = "", *args, **kwargs):
         
     | 
| 173 | 
         
            -
                    self.route_log(("error", "red"), msg, *args, **kwargs)
         
     | 
| 174 | 
         
            -
             
     | 
| 175 | 
         
            -
                def warn(self, msg: str = "", *args, **kwargs):
         
     | 
| 176 | 
         
            -
                    self.route_log(("warning", "light_red"), msg, *args, **kwargs)
         
     | 
| 177 | 
         
            -
             
     | 
| 178 | 
         
            -
                def note(self, msg: str = "", *args, **kwargs):
         
     | 
| 179 | 
         
            -
                    self.route_log(("info", "light_magenta"), msg, *args, **kwargs)
         
     | 
| 180 | 
         
            -
             
     | 
| 181 | 
         
            -
                def mesg(self, msg: str = "", *args, **kwargs):
         
     | 
| 182 | 
         
            -
                    self.route_log(("info", "light_cyan"), msg, *args, **kwargs)
         
     | 
| 183 | 
         
            -
             
     | 
| 184 | 
         
            -
                def file(self, msg: str = "", *args, **kwargs):
         
     | 
| 185 | 
         
            -
                    self.route_log(("info", "light_blue"), msg, *args, **kwargs)
         
     | 
| 186 | 
         
            -
             
     | 
| 187 | 
         
            -
                def line(self, msg: str = "", *args, **kwargs):
         
     | 
| 188 | 
         
            -
                    self.route_log(("info", "white"), msg, *args, **kwargs)
         
     | 
| 189 | 
         
            -
             
     | 
| 190 | 
         
            -
                def success(self, msg: str = "", *args, **kwargs):
         
     | 
| 191 | 
         
            -
                    self.route_log(("info", "light_green"), msg, *args, **kwargs)
         
     | 
| 192 | 
         
            -
             
     | 
| 193 | 
         
            -
                def fail(self, msg: str = "", *args, **kwargs):
         
     | 
| 194 | 
         
            -
                    self.route_log(("info", "light_red"), msg, *args, **kwargs)
         
     | 
| 195 | 
         
            -
             
     | 
| 196 | 
         
            -
                def back(self, msg: str = "", *args, **kwargs):
         
     | 
| 197 | 
         
            -
                    self.route_log(("debug", "light_cyan"), msg, *args, **kwargs)
         
     | 
| 198 | 
         
            -
             
     | 
| 199 | 
         
            -
             
     | 
| 200 | 
         
            -
            logger = OSLogger()
         
     | 
| 201 | 
         
            -
             
     | 
| 202 | 
         
            -
             
     | 
| 203 | 
         
            -
            def shell_cmd(cmd, getoutput=False, showcmd=True, env=None):
         
     | 
| 204 | 
         
            -
                if showcmd:
         
     | 
| 205 | 
         
            -
                    logger.info(colored(f"\n$ [{os.getcwd()}]", "light_blue"))
         
     | 
| 206 | 
         
            -
                    logger.info(colored(f"  $ {cmd}\n", "light_cyan"))
         
     | 
| 207 | 
         
            -
                if getoutput:
         
     | 
| 208 | 
         
            -
                    output = subprocess.getoutput(cmd, env=env)
         
     | 
| 209 | 
         
            -
                    return output
         
     | 
| 210 | 
         
            -
                else:
         
     | 
| 211 | 
         
            -
                    subprocess.run(cmd, shell=True, env=env)
         
     | 
| 212 | 
         
            -
             
     | 
| 213 | 
         
            -
             
     | 
| 214 | 
         
            -
            class Runtimer:
         
     | 
| 215 | 
         
            -
                def __enter__(self):
         
     | 
| 216 | 
         
            -
                    self.t1, _ = self.start_time()
         
     | 
| 217 | 
         
            -
                    return self
         
     | 
| 218 | 
         
            -
             
     | 
| 219 | 
         
            -
                def __exit__(self, exc_type, exc_value, traceback):
         
     | 
| 220 | 
         
            -
                    self.t2, _ = self.end_time()
         
     | 
| 221 | 
         
            -
                    self.elapsed_time(self.t2 - self.t1)
         
     | 
| 222 | 
         
            -
             
     | 
| 223 | 
         
            -
                def start_time(self):
         
     | 
| 224 | 
         
            -
                    t1 = datetime.datetime.now()
         
     | 
| 225 | 
         
            -
                    self.logger_time("start", t1)
         
     | 
| 226 | 
         
            -
                    return t1, self.time2str(t1)
         
     | 
| 227 | 
         
            -
             
     | 
| 228 | 
         
            -
                def end_time(self):
         
     | 
| 229 | 
         
            -
                    t2 = datetime.datetime.now()
         
     | 
| 230 | 
         
            -
                    self.logger_time("end", t2)
         
     | 
| 231 | 
         
            -
                    return t2, self.time2str(t2)
         
     | 
| 232 | 
         
            -
             
     | 
| 233 | 
         
            -
                def elapsed_time(self, dt=None):
         
     | 
| 234 | 
         
            -
                    if dt is None:
         
     | 
| 235 | 
         
            -
                        dt = self.t2 - self.t1
         
     | 
| 236 | 
         
            -
                    self.logger_time("elapsed", dt)
         
     | 
| 237 | 
         
            -
                    return dt, self.time2str(dt)
         
     | 
| 238 | 
         
            -
             
     | 
| 239 | 
         
            -
                def logger_time(self, time_type, t):
         
     | 
| 240 | 
         
            -
                    time_types = {
         
     | 
| 241 | 
         
            -
                        "start": "Start",
         
     | 
| 242 | 
         
            -
                        "end": "End",
         
     | 
| 243 | 
         
            -
                        "elapsed": "Elapsed",
         
     | 
| 244 | 
         
            -
                    }
         
     | 
| 245 | 
         
            -
                    time_str = add_fillers(
         
     | 
| 246 | 
         
            -
                        colored(
         
     | 
| 247 | 
         
            -
                            f"{time_types[time_type]} time: [ {self.time2str(t)} ]",
         
     | 
| 248 | 
         
            -
                            "light_magenta",
         
     | 
| 249 | 
         
            -
                        ),
         
     | 
| 250 | 
         
            -
                        fill_side="both",
         
     | 
| 251 | 
         
            -
                    )
         
     | 
| 252 | 
         
            -
                    logger.line(time_str)
         
     | 
| 253 | 
         
            -
             
     | 
| 254 | 
         
            -
                # Convert time to string
         
     | 
| 255 | 
         
            -
                def time2str(self, t):
         
     | 
| 256 | 
         
            -
                    datetime_str_format = "%Y-%m-%d %H:%M:%S"
         
     | 
| 257 | 
         
            -
                    if isinstance(t, datetime.datetime):
         
     | 
| 258 | 
         
            -
                        return t.strftime(datetime_str_format)
         
     | 
| 259 | 
         
            -
                    elif isinstance(t, datetime.timedelta):
         
     | 
| 260 | 
         
            -
                        hours = t.seconds // 3600
         
     | 
| 261 | 
         
            -
                        hour_str = f"{hours} hr" if hours > 0 else ""
         
     | 
| 262 | 
         
            -
                        minutes = (t.seconds // 60) % 60
         
     | 
| 263 | 
         
            -
                        minute_str = f"{minutes:>2} min" if minutes > 0 else ""
         
     | 
| 264 | 
         
            -
                        seconds = t.seconds % 60
         
     | 
| 265 | 
         
            -
                        second_str = f"{seconds:>2} s"
         
     | 
| 266 | 
         
            -
                        time_str = " ".join([hour_str, minute_str, second_str]).strip()
         
     | 
| 267 | 
         
            -
                        return time_str
         
     | 
| 268 | 
         
            -
                    else:
         
     | 
| 269 | 
         
            -
                        return str(t)
         
     | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         |