import os import platform import subprocess def get_providers(): """ Scans the 'src/rotator_library/providers' directory to find all provider modules. Returns a list of hidden import arguments for PyInstaller. """ hidden_imports = [] # Get the absolute path to the directory containing this script script_dir = os.path.dirname(os.path.abspath(__file__)) # Construct the path to the providers directory relative to this script's location providers_path = os.path.join(script_dir, "..", "rotator_library", "providers") if not os.path.isdir(providers_path): print(f"Error: Directory not found at '{os.path.abspath(providers_path)}'") return [] for filename in os.listdir(providers_path): if filename.endswith("_provider.py") and filename != "__init__.py": module_name = f"rotator_library.providers.{filename[:-3]}" hidden_imports.append(f"--hidden-import={module_name}") return hidden_imports def main(): """ Constructs and runs the PyInstaller command to build the executable. """ # Base PyInstaller command command = [ "python", "-m", "PyInstaller", "--onefile", "--name", "proxy_app", "--paths", "../", "--paths", ".", "--hidden-import=rotator_library", "--hidden-import=tiktoken_ext.openai_public", "--hidden-import=tiktoken_ext", "--collect-data", "litellm", ] # Add hidden imports for providers provider_imports = get_providers() if not provider_imports: print("Warning: No providers found. The build might not include any LLM providers.") command.extend(provider_imports) # Add the main script command.append("main.py") # Execute the command print(f"Running command: {' '.join(command)}") try: # Run PyInstaller from the script's directory to ensure relative paths are correct script_dir = os.path.dirname(os.path.abspath(__file__)) subprocess.run(command, check=True, cwd=script_dir) print("Build successful!") except subprocess.CalledProcessError as e: print(f"Build failed with error: {e}") except FileNotFoundError: print("Error: PyInstaller is not installed or not in the system's PATH.") if __name__ == "__main__": main()