#!/usr/bin/env python3 """ Interactive setup script for biomni environment configuration. This script helps users set up: 1. Conda environment with required dependencies 2. API keys for LLM providers 3. Data lake directory configuration 4. MCP server setup (optional) Usage: python setup_environment.py """ import os import sys import subprocess from pathlib import Path from typing import Dict, Optional def check_conda_installed() -> bool: """Check if conda is available in the system.""" try: subprocess.run( ['conda', '--version'], capture_output=True, check=True ) return True except (subprocess.CalledProcessError, FileNotFoundError): return False def setup_conda_environment(): """Guide user through conda environment setup.""" print("\n=== Conda Environment Setup ===") if not check_conda_installed(): print("❌ Conda not found. Please install Miniconda or Anaconda:") print(" https://docs.conda.io/en/latest/miniconda.html") return False print("✓ Conda is installed") # Check if biomni_e1 environment exists result = subprocess.run( ['conda', 'env', 'list'], capture_output=True, text=True ) if 'biomni_e1' in result.stdout: print("✓ biomni_e1 environment already exists") return True print("\nCreating biomni_e1 conda environment...") print("This will install Python 3.10 and required dependencies.") response = input("Proceed? [y/N]: ").strip().lower() if response != 'y': print("Skipping conda environment setup") return False try: # Create conda environment subprocess.run( ['conda', 'create', '-n', 'biomni_e1', 'python=3.10', '-y'], check=True ) print("\n✓ Conda environment created successfully") print("\nTo activate: conda activate biomni_e1") print("Then install biomni: pip install biomni --upgrade") return True except subprocess.CalledProcessError as e: print(f"❌ Failed to create conda environment: {e}") return False def setup_api_keys() -> Dict[str, str]: """Interactive API key configuration.""" print("\n=== API Key Configuration ===") print("Biomni supports multiple LLM providers.") print("At minimum, configure one provider.") api_keys = {} # Anthropic (recommended) print("\n1. Anthropic Claude (Recommended)") print(" Get your API key from: https://console.anthropic.com/") anthropic_key = input(" Enter ANTHROPIC_API_KEY (or press Enter to skip): ").strip() if anthropic_key: api_keys['ANTHROPIC_API_KEY'] = anthropic_key # OpenAI print("\n2. OpenAI") print(" Get your API key from: https://platform.openai.com/api-keys") openai_key = input(" Enter OPENAI_API_KEY (or press Enter to skip): ").strip() if openai_key: api_keys['OPENAI_API_KEY'] = openai_key # Google Gemini print("\n3. Google Gemini") print(" Get your API key from: https://makersuite.google.com/app/apikey") google_key = input(" Enter GOOGLE_API_KEY (or press Enter to skip): ").strip() if google_key: api_keys['GOOGLE_API_KEY'] = google_key # Groq print("\n4. Groq") print(" Get your API key from: https://console.groq.com/keys") groq_key = input(" Enter GROQ_API_KEY (or press Enter to skip): ").strip() if groq_key: api_keys['GROQ_API_KEY'] = groq_key if not api_keys: print("\n⚠️ No API keys configured. You'll need at least one to use biomni.") return {} return api_keys def save_api_keys(api_keys: Dict[str, str], method: str = 'env_file'): """Save API keys using specified method.""" if method == 'env_file': env_file = Path.cwd() / '.env' # Read existing .env if present existing_vars = {} if env_file.exists(): with open(env_file, 'r') as f: for line in f: line = line.strip() if line and not line.startswith('#'): if '=' in line: key, val = line.split('=', 1) existing_vars[key.strip()] = val.strip() # Update with new keys existing_vars.update(api_keys) # Write to .env with open(env_file, 'w') as f: f.write("# Biomni API Keys\n") f.write(f"# Generated by setup_environment.py\n\n") for key, value in existing_vars.items(): f.write(f"{key}={value}\n") print(f"\n✓ API keys saved to {env_file}") print(" Keys will be loaded automatically when biomni runs in this directory") elif method == 'shell_export': shell_file = Path.home() / '.bashrc' # or .zshrc for zsh users print("\n📋 Add these lines to your shell configuration:") for key, value in api_keys.items(): print(f" export {key}=\"{value}\"") print(f"\nThen run: source {shell_file}") def setup_data_directory() -> Optional[Path]: """Configure biomni data lake directory.""" print("\n=== Data Lake Configuration ===") print("Biomni requires ~11GB for integrated biomedical databases.") default_path = Path.cwd() / 'biomni_data' print(f"\nDefault location: {default_path}") response = input("Use default location? [Y/n]: ").strip().lower() if response == 'n': custom_path = input("Enter custom path: ").strip() data_path = Path(custom_path).expanduser().resolve() else: data_path = default_path # Create directory if it doesn't exist data_path.mkdir(parents=True, exist_ok=True) print(f"\n✓ Data directory configured: {data_path}") print(" Data will be downloaded automatically on first use") return data_path def test_installation(data_path: Path): """Test biomni installation with a simple query.""" print("\n=== Installation Test ===") print("Testing biomni installation with a simple query...") response = input("Run test? [Y/n]: ").strip().lower() if response == 'n': print("Skipping test") return test_code = f''' import os from biomni.agent import A1 # Use environment variables for API keys agent = A1(path='{data_path}', llm='claude-sonnet-4-20250514') # Simple test query result = agent.go("What is the primary function of the TP53 gene?") print("Test result:", result) ''' test_file = Path('test_biomni.py') with open(test_file, 'w') as f: f.write(test_code) print(f"\nTest script created: {test_file}") print("Running test...") try: subprocess.run([sys.executable, str(test_file)], check=True) print("\n✓ Test completed successfully!") test_file.unlink() # Clean up test file except subprocess.CalledProcessError: print("\n❌ Test failed. Check your configuration.") print(f" Test script saved as {test_file} for debugging") def generate_example_script(data_path: Path): """Generate example usage script.""" example_code = f'''#!/usr/bin/env python3 """ Example biomni usage script This demonstrates basic biomni usage patterns. Modify this script for your research tasks. """ from biomni.agent import A1 # Initialize agent agent = A1( path='{data_path}', llm='claude-sonnet-4-20250514' # or your preferred LLM ) # Example 1: Simple gene query print("Example 1: Gene function query") result = agent.go(""" What are the main functions of the BRCA1 gene? Include information about: - Molecular function - Associated diseases - Protein interactions """) print(result) print("-" * 80) # Example 2: Data analysis print("\\nExample 2: GWAS analysis") result = agent.go(""" Explain how to analyze GWAS summary statistics for: 1. Identifying genome-wide significant variants 2. Mapping variants to genes 3. Pathway enrichment analysis """) print(result) # Save conversation history agent.save_conversation_history("example_results.pdf") print("\\nResults saved to example_results.pdf") ''' example_file = Path('example_biomni_usage.py') with open(example_file, 'w') as f: f.write(example_code) print(f"\n✓ Example script created: {example_file}") def main(): """Main setup workflow.""" print("=" * 60) print("Biomni Environment Setup") print("=" * 60) # Step 1: Conda environment conda_success = setup_conda_environment() if conda_success: print("\n⚠️ Remember to activate the environment:") print(" conda activate biomni_e1") print(" pip install biomni --upgrade") # Step 2: API keys api_keys = setup_api_keys() if api_keys: print("\nHow would you like to store API keys?") print("1. .env file (recommended, local to this directory)") print("2. Shell export (add to .bashrc/.zshrc)") choice = input("Choose [1/2]: ").strip() if choice == '2': save_api_keys(api_keys, method='shell_export') else: save_api_keys(api_keys, method='env_file') # Step 3: Data directory data_path = setup_data_directory() # Step 4: Generate example script if data_path: generate_example_script(data_path) # Step 5: Test installation (optional) if api_keys and data_path: test_installation(data_path) # Summary print("\n" + "=" * 60) print("Setup Complete!") print("=" * 60) if conda_success: print("✓ Conda environment: biomni_e1") if api_keys: print(f"✓ API keys configured: {', '.join(api_keys.keys())}") if data_path: print(f"✓ Data directory: {data_path}") print("\nNext steps:") if conda_success: print("1. conda activate biomni_e1") print("2. pip install biomni --upgrade") print("3. Run example_biomni_usage.py to test") else: print("1. Install conda/miniconda") print("2. Run this script again") print("\nFor documentation, see:") print(" - GitHub: https://github.com/snap-stanford/biomni") print(" - Paper: https://www.biorxiv.org/content/10.1101/2025.05.30.656746v1") if __name__ == "__main__": try: main() except KeyboardInterrupt: print("\n\nSetup interrupted by user") sys.exit(1) except Exception as e: print(f"\n❌ Error during setup: {e}") sys.exit(1)