| 
									
										
										
										
											2024-06-26 17:33:29 +08:00
										 |  |  | from core.ops.ops_trace_manager import OpsTraceManager, provider_config_map | 
					
						
							|  |  |  | from extensions.ext_database import db | 
					
						
							|  |  |  | from models.model import App, TraceAppConfig | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class OpsService: | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def get_tracing_app_config(cls, app_id: str, tracing_provider: str): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Get tracing app config | 
					
						
							|  |  |  |         :param app_id: app id | 
					
						
							|  |  |  |         :param tracing_provider: tracing provider | 
					
						
							|  |  |  |         :return: | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:43:57 +08:00
										 |  |  |         trace_config_data: TraceAppConfig = ( | 
					
						
							|  |  |  |             db.session.query(TraceAppConfig) | 
					
						
							|  |  |  |             .filter(TraceAppConfig.app_id == app_id, TraceAppConfig.tracing_provider == tracing_provider) | 
					
						
							|  |  |  |             .first() | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-06-26 17:33:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if not trace_config_data: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # decrypt_token and obfuscated_token | 
					
						
							|  |  |  |         tenant_id = db.session.query(App).filter(App.id == app_id).first().tenant_id | 
					
						
							| 
									
										
										
										
											2024-08-26 13:43:57 +08:00
										 |  |  |         decrypt_tracing_config = OpsTraceManager.decrypt_tracing_config( | 
					
						
							|  |  |  |             tenant_id, tracing_provider, trace_config_data.tracing_config | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-27 11:25:56 +08:00
										 |  |  |         new_decrypt_tracing_config = OpsTraceManager.obfuscated_decrypt_token(tracing_provider, decrypt_tracing_config) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:43:57 +08:00
										 |  |  |         if tracing_provider == "langfuse" and ( | 
					
						
							|  |  |  |             "project_key" not in decrypt_tracing_config or not decrypt_tracing_config.get("project_key") | 
					
						
							|  |  |  |         ): | 
					
						
							| 
									
										
										
										
											2024-09-13 16:08:08 +08:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 project_key = OpsTraceManager.get_trace_config_project_key(decrypt_tracing_config, tracing_provider) | 
					
						
							|  |  |  |                 new_decrypt_tracing_config.update( | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         "project_url": "{host}/project/{key}".format( | 
					
						
							|  |  |  |                             host=decrypt_tracing_config.get("host"), key=project_key | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |             except Exception: | 
					
						
							|  |  |  |                 new_decrypt_tracing_config.update( | 
					
						
							|  |  |  |                     {"project_url": "{host}/".format(host=decrypt_tracing_config.get("host"))} | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-09-08 13:25:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if tracing_provider == "langsmith" and ( | 
					
						
							|  |  |  |             "project_url" not in decrypt_tracing_config or not decrypt_tracing_config.get("project_url") | 
					
						
							|  |  |  |         ): | 
					
						
							| 
									
										
										
										
											2024-09-13 16:08:08 +08:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 project_url = OpsTraceManager.get_trace_config_project_url(decrypt_tracing_config, tracing_provider) | 
					
						
							|  |  |  |                 new_decrypt_tracing_config.update({"project_url": project_url}) | 
					
						
							|  |  |  |             except Exception: | 
					
						
							|  |  |  |                 new_decrypt_tracing_config.update({"project_url": "https://smith.langchain.com/"}) | 
					
						
							| 
									
										
										
										
											2024-06-26 17:33:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-27 11:25:56 +08:00
										 |  |  |         trace_config_data.tracing_config = new_decrypt_tracing_config | 
					
						
							| 
									
										
										
										
											2024-06-26 17:33:29 +08:00
										 |  |  |         return trace_config_data.to_dict() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def create_tracing_app_config(cls, app_id: str, tracing_provider: str, tracing_config: dict): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Create tracing app config | 
					
						
							|  |  |  |         :param app_id: app id | 
					
						
							|  |  |  |         :param tracing_provider: tracing provider | 
					
						
							|  |  |  |         :param tracing_config: tracing config | 
					
						
							|  |  |  |         :return: | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-12 12:55:45 +08:00
										 |  |  |         if tracing_provider not in provider_config_map and tracing_provider: | 
					
						
							| 
									
										
										
										
											2024-06-26 17:33:29 +08:00
										 |  |  |             return {"error": f"Invalid tracing provider: {tracing_provider}"} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:43:57 +08:00
										 |  |  |         config_class, other_keys = ( | 
					
						
							|  |  |  |             provider_config_map[tracing_provider]["config_class"], | 
					
						
							|  |  |  |             provider_config_map[tracing_provider]["other_keys"], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-06-26 17:33:29 +08:00
										 |  |  |         default_config_instance = config_class(**tracing_config) | 
					
						
							|  |  |  |         for key in other_keys: | 
					
						
							|  |  |  |             if key in tracing_config and tracing_config[key] == "": | 
					
						
							|  |  |  |                 tracing_config[key] = getattr(default_config_instance, key, None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # api check | 
					
						
							|  |  |  |         if not OpsTraceManager.check_trace_config_is_effective(tracing_config, tracing_provider): | 
					
						
							|  |  |  |             return {"error": "Invalid Credentials"} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-08 13:25:27 +08:00
										 |  |  |         # get project url | 
					
						
							|  |  |  |         if tracing_provider == "langfuse": | 
					
						
							|  |  |  |             project_key = OpsTraceManager.get_trace_config_project_key(tracing_config, tracing_provider) | 
					
						
							|  |  |  |             project_url = "{host}/project/{key}".format(host=tracing_config.get("host"), key=project_key) | 
					
						
							|  |  |  |         elif tracing_provider == "langsmith": | 
					
						
							|  |  |  |             project_url = OpsTraceManager.get_trace_config_project_url(tracing_config, tracing_provider) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             project_url = None | 
					
						
							| 
									
										
										
										
											2024-08-23 15:53:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-26 17:33:29 +08:00
										 |  |  |         # check if trace config already exists | 
					
						
							| 
									
										
										
										
											2024-08-26 13:43:57 +08:00
										 |  |  |         trace_config_data: TraceAppConfig = ( | 
					
						
							|  |  |  |             db.session.query(TraceAppConfig) | 
					
						
							|  |  |  |             .filter(TraceAppConfig.app_id == app_id, TraceAppConfig.tracing_provider == tracing_provider) | 
					
						
							|  |  |  |             .first() | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-06-26 17:33:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if trace_config_data: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # get tenant id | 
					
						
							|  |  |  |         tenant_id = db.session.query(App).filter(App.id == app_id).first().tenant_id | 
					
						
							|  |  |  |         tracing_config = OpsTraceManager.encrypt_tracing_config(tenant_id, tracing_provider, tracing_config) | 
					
						
							| 
									
										
										
										
											2024-09-08 13:25:27 +08:00
										 |  |  |         if project_url: | 
					
						
							|  |  |  |             tracing_config["project_url"] = project_url | 
					
						
							| 
									
										
										
										
											2024-06-26 17:33:29 +08:00
										 |  |  |         trace_config_data = TraceAppConfig( | 
					
						
							|  |  |  |             app_id=app_id, | 
					
						
							|  |  |  |             tracing_provider=tracing_provider, | 
					
						
							|  |  |  |             tracing_config=tracing_config, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         db.session.add(trace_config_data) | 
					
						
							|  |  |  |         db.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return {"result": "success"} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def update_tracing_app_config(cls, app_id: str, tracing_provider: str, tracing_config: dict): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Update tracing app config | 
					
						
							|  |  |  |         :param app_id: app id | 
					
						
							|  |  |  |         :param tracing_provider: tracing provider | 
					
						
							|  |  |  |         :param tracing_config: tracing config | 
					
						
							|  |  |  |         :return: | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-12 12:55:45 +08:00
										 |  |  |         if tracing_provider not in provider_config_map: | 
					
						
							| 
									
										
										
										
											2024-06-26 17:33:29 +08:00
										 |  |  |             raise ValueError(f"Invalid tracing provider: {tracing_provider}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # check if trace config already exists | 
					
						
							| 
									
										
										
										
											2024-08-26 13:43:57 +08:00
										 |  |  |         current_trace_config = ( | 
					
						
							|  |  |  |             db.session.query(TraceAppConfig) | 
					
						
							|  |  |  |             .filter(TraceAppConfig.app_id == app_id, TraceAppConfig.tracing_provider == tracing_provider) | 
					
						
							|  |  |  |             .first() | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-06-26 17:33:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if not current_trace_config: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # get tenant id | 
					
						
							|  |  |  |         tenant_id = db.session.query(App).filter(App.id == app_id).first().tenant_id | 
					
						
							|  |  |  |         tracing_config = OpsTraceManager.encrypt_tracing_config( | 
					
						
							|  |  |  |             tenant_id, tracing_provider, tracing_config, current_trace_config.tracing_config | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # api check | 
					
						
							|  |  |  |         # decrypt_token | 
					
						
							|  |  |  |         decrypt_tracing_config = OpsTraceManager.decrypt_tracing_config(tenant_id, tracing_provider, tracing_config) | 
					
						
							|  |  |  |         if not OpsTraceManager.check_trace_config_is_effective(decrypt_tracing_config, tracing_provider): | 
					
						
							|  |  |  |             raise ValueError("Invalid Credentials") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         current_trace_config.tracing_config = tracing_config | 
					
						
							|  |  |  |         db.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return current_trace_config.to_dict() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def delete_tracing_app_config(cls, app_id: str, tracing_provider: str): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Delete tracing app config | 
					
						
							|  |  |  |         :param app_id: app id | 
					
						
							|  |  |  |         :param tracing_provider: tracing provider | 
					
						
							|  |  |  |         :return: | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:43:57 +08:00
										 |  |  |         trace_config = ( | 
					
						
							|  |  |  |             db.session.query(TraceAppConfig) | 
					
						
							|  |  |  |             .filter(TraceAppConfig.app_id == app_id, TraceAppConfig.tracing_provider == tracing_provider) | 
					
						
							|  |  |  |             .first() | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-06-26 17:33:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if not trace_config: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         db.session.delete(trace_config) | 
					
						
							|  |  |  |         db.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return True |