mirror of
				https://github.com/open-webui/open-webui
				synced 2025-06-26 18:26:48 +00:00 
			
		
		
		
	fix: install external requirements of admin functions and tools on startups
This commit is contained in:
		
							parent
							
								
									c9d3bb35c3
								
							
						
					
					
						commit
						e80ed32aeb
					
				@ -383,6 +383,7 @@ from open_webui.utils.auth import (
 | 
			
		||||
    get_admin_user,
 | 
			
		||||
    get_verified_user,
 | 
			
		||||
)
 | 
			
		||||
from open_webui.utils.plugin import install_admin_tool_and_function_dependencies
 | 
			
		||||
from open_webui.utils.oauth import OAuthManager
 | 
			
		||||
from open_webui.utils.security_headers import SecurityHeadersMiddleware
 | 
			
		||||
 | 
			
		||||
@ -451,6 +452,12 @@ async def lifespan(app: FastAPI):
 | 
			
		||||
        limiter.total_tokens = pool_size
 | 
			
		||||
 | 
			
		||||
    asyncio.create_task(periodic_usage_pool_cleanup())
 | 
			
		||||
 | 
			
		||||
    # This should be blocking (sync) so functions are not deactivated on first /get_models calls
 | 
			
		||||
    # when the first user lands on the / route.
 | 
			
		||||
    log.info("Installing external dependencies of functions and tools...")
 | 
			
		||||
    install_admin_tool_and_function_dependencies()
 | 
			
		||||
 | 
			
		||||
    yield
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -895,7 +902,8 @@ class RedirectMiddleware(BaseHTTPMiddleware):
 | 
			
		||||
 | 
			
		||||
            # Check for the specific watch path and the presence of 'v' parameter
 | 
			
		||||
            if path.endswith("/watch") and "v" in query_params:
 | 
			
		||||
                video_id = query_params["v"][0]  # Extract the first 'v' parameter
 | 
			
		||||
                # Extract the first 'v' parameter
 | 
			
		||||
                video_id = query_params["v"][0]
 | 
			
		||||
                encoded_video_id = urlencode({"youtube": video_id})
 | 
			
		||||
                redirect_url = f"/?{encoded_video_id}"
 | 
			
		||||
                return RedirectResponse(url=redirect_url)
 | 
			
		||||
 | 
			
		||||
@ -157,7 +157,8 @@ def load_function_module_by_id(function_id, content=None):
 | 
			
		||||
            raise Exception("No Function class found in the module")
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        log.error(f"Error loading module: {function_id}: {e}")
 | 
			
		||||
        del sys.modules[module_name]  # Cleanup by removing the module in case of error
 | 
			
		||||
        # Cleanup by removing the module in case of error
 | 
			
		||||
        del sys.modules[module_name]
 | 
			
		||||
 | 
			
		||||
        Functions.update_function_by_id(function_id, {"is_active": False})
 | 
			
		||||
        raise e
 | 
			
		||||
@ -182,3 +183,32 @@ def install_frontmatter_requirements(requirements: str):
 | 
			
		||||
 | 
			
		||||
    else:
 | 
			
		||||
        log.info("No requirements found in frontmatter.")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def install_admin_tool_and_function_dependencies():
 | 
			
		||||
    """
 | 
			
		||||
    Install all dependencies for all admin tools and active functions.
 | 
			
		||||
 | 
			
		||||
    By first collecting all dependencies from the frontmatter of each tool and function,
 | 
			
		||||
    and then installing them using pip. Duplicates or similar version specifications are
 | 
			
		||||
    handled by pip as much as possible.
 | 
			
		||||
    """
 | 
			
		||||
    function_list = Functions.get_functions(active_only=True)
 | 
			
		||||
    tool_list = Tools.get_tools()
 | 
			
		||||
 | 
			
		||||
    all_dependencies = ""
 | 
			
		||||
    try:
 | 
			
		||||
        for function in function_list:
 | 
			
		||||
            frontmatter = extract_frontmatter(replace_imports(function.content))
 | 
			
		||||
            if dependencies := frontmatter.get("requirements"):
 | 
			
		||||
                all_dependencies += f"{dependencies}, "
 | 
			
		||||
        for tool in tool_list:
 | 
			
		||||
            # Only install requirements for admin tools
 | 
			
		||||
            if tool.user.role == "admin":
 | 
			
		||||
                frontmatter = extract_frontmatter(replace_imports(tool.content))
 | 
			
		||||
                if dependencies := frontmatter.get("requirements"):
 | 
			
		||||
                    all_dependencies += f"{dependencies}, "
 | 
			
		||||
 | 
			
		||||
        install_frontmatter_requirements(all_dependencies.strip(", "))
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        log.error(f"Error installing requirements: {e}")
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user