defget_parser(env_prefix:str="",default_env:bool=True,**kwargs:Any)->ArgumentParser:"""Get an argument parser with configurable APPL configs."""parser=ArgumentParser(env_prefix=env_prefix,default_env=default_env,**kwargs)parser.add_argument("--appl",type=APPLConfigs,default=global_vars.configs)returnparser
definit(**kwargs:Any)->None:"""Overwrite APPL configs. see [default configs](../setup/#default-configs) for more details. Examples: ```python import appl appl.init(servers={"default": "gpt-4o"}) ``` """logger.warning(f"appl.init() is not mandatory to initialize APPL for appl>=0.2.0, ""please remove it if you are not changing the configs.")ifkwargs:logger.info(f"Updating APPL configs with: \n{yaml.dump(kwargs)}")new_configs=merge_configs(global_vars.configs,**kwargs)update_appl_configs(new_configs)
@contextmanagerdefinit_within_thread(log_file_prefix:Optional[str]=None,gen_name_prefix:Optional[str]=None)->Any:"""Initialize APPL to work with multi-threading, including logging and tracing. Args: log_file_prefix: The prefix for the log file. Defaults to use the path of the main log file. gen_name_prefix: The prefix for the generation name. Defaults to use the thread name. Examples: ```python def function_run_in_thread(): with appl.init_within_thread(): # do something within the thread ``` """handler_id=Nonetry:thread_name=threading.current_thread().namelogging_settings=global_vars.configs.settings.loggingdeffilter_thread_record(record:Dict)->bool:asserthasattr(record["thread"],"name")# Use prefix match to filter the log records in different threadsname=record["thread"].namereturnname==thread_nameorname.startswith(thread_name+"_")iflogging_settings.enable_file:iflog_file_prefixisNone:assert(global_vars.metadata.log_fileisnotNone),"should have log file set"thread_log_path=os.path.join(global_vars.metadata.log_file[:-len(".log")]+"_logs",f"{thread_name}.log",)else:thread_log_path=f"{log_file_prefix}_{thread_name}.log"log_level=(logging_settings.log_file.log_levelorlogging_settings.log_level)# The logger append to the file by default, not overwrite.handler_id=logger.add(thread_log_path,level=log_level,format=logging_settings.format,filter=filter_thread_record,# type: ignore)ifgen_name_prefix:set_gen_name_prefix(gen_name_prefix)# ? shall we reset the prefix after exiting the context?logger.info(f"Thread {thread_name}, set generation name prefix as: {gen_name_prefix}")ifhandler_idisNone:logger.warning("logging is not enabled")yieldthread_log_pathexceptExceptionase:logger.error(f"Error in thread: {e}")raiseefinally:ifhandler_id:logger.remove(handler_id)