summaryrefslogtreecommitdiff
path: root/putnam-bench-anon/install.py
blob: 36812b92ddfd54b71d5e4d45e5ef4146ef16d958 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#!/usr/bin/env python3
"""
Quick installation and setup script for Putnam Problem Solver.

This script provides a one-command setup for the entire system.

Usage:
    python install.py                    # Full installation
    python install.py --quick           # Quick setup (minimal dependencies)
    python install.py --check-only      # Just check what would be installed
"""

import asyncio
import sys
import subprocess
import os
from pathlib import Path
import argparse


def print_banner():
    """Print installation banner."""
    print("šŸš€ Putnam Problem Solver - Quick Install")
    print("=" * 50)
    print("This script will set up everything you need to get started.")
    print()


def check_python():
    """Check Python version."""
    version = sys.version_info
    if version.major < 3 or (version.major == 3 and version.minor < 8):
        print("āŒ Python 3.8+ required")
        print(f"   Current version: {version.major}.{version.minor}.{version.micro}")
        return False
    
    print(f"āœ… Python {version.major}.{version.minor}.{version.micro}")
    return True


def install_packages(packages: list, check_only: bool = False):
    """Install required packages."""
    if not packages:
        print("āœ… All required packages are already installed!")
        return True
    
    print(f"šŸ“¦ {'Would install' if check_only else 'Installing'}: {', '.join(packages)}")
    
    if check_only:
        return True
    
    try:
        subprocess.run([
            sys.executable, '-m', 'pip', 'install', '--upgrade'
        ] + packages, check=True)
        print("āœ… Packages installed successfully!")
        return True
    except subprocess.CalledProcessError as e:
        print(f"āŒ Failed to install packages: {e}")
        return False


def check_package_installed(package: str) -> bool:
    """Check if a package is installed."""
    try:
        if package == 'google-generativeai':
            import google.generativeai
        else:
            __import__(package)
        return True
    except ImportError:
        return False


def get_missing_packages(include_optional: bool = True) -> list:
    """Get list of missing packages."""
    # Core packages (always required)
    core_packages = ['openai', 'anthropic', 'google-generativeai', 'psutil']
    
    # Optional packages (for local models)
    optional_packages = ['transformers', 'torch', 'vllm'] if include_optional else []
    
    missing = []
    
    print("šŸ” Checking required packages...")
    for package in core_packages:
        if check_package_installed(package):
            print(f"   āœ… {package}")
        else:
            print(f"   āŒ {package}")
            missing.append(package)
    
    if include_optional:
        print("\nšŸ” Checking optional packages (for local models)...")
        for package in optional_packages:
            if check_package_installed(package):
                print(f"   āœ… {package}")
            else:
                print(f"   āš ļø {package} (optional)")
                missing.append(package)
    
    return missing


def create_alias():
    """Create putnam command alias."""
    script_dir = Path(__file__).parent.absolute()
    putnam_cli = script_dir / "putnam_cli.py"
    
    # For Unix-like systems
    if os.name != 'nt':
        shell_profile = Path.home() / ".bashrc"
        if not shell_profile.exists():
            shell_profile = Path.home() / ".bash_profile"
        if not shell_profile.exists():
            shell_profile = Path.home() / ".zshrc"
        
        alias_line = f'alias putnam="python {putnam_cli}"'
        
        try:
            # Check if alias already exists
            if shell_profile.exists():
                with open(shell_profile, 'r') as f:
                    content = f.read()
                    if 'alias putnam=' in content:
                        print("āœ… 'putnam' alias already exists")
                        return True
            
            # Add alias
            with open(shell_profile, 'a') as f:
                f.write(f"\n# Putnam Problem Solver alias\n{alias_line}\n")
            
            print(f"āœ… Added 'putnam' alias to {shell_profile}")
            print(f"šŸ’” Restart your shell or run: source {shell_profile}")
            return True
            
        except Exception as e:
            print(f"āš ļø Could not create alias: {e}")
            print(f"šŸ’” You can manually add: {alias_line}")
    
    else:
        # Windows
        print("šŸ’” On Windows, use: python putnam_cli.py <command>")
    
    return False


async def run_setup():
    """Run the configuration setup."""
    print("\nšŸ› ļø Running configuration setup...")
    try:
        from setup_config import ConfigManager
        manager = ConfigManager()
        await manager.interactive_setup()
        return True
    except ImportError:
        print("āŒ Configuration setup not available")
        return False
    except Exception as e:
        print(f"āŒ Setup failed: {e}")
        return False


def print_next_steps():
    """Print next steps for the user."""
    print("\nšŸŽ‰ Installation completed!")
    print("\nšŸ“š Next Steps:")
    print("   1. Set up API keys: python setup_config.py")
    print("   2. Check health: python health_check.py")
    print("   3. Quick test: python putnam_cli.py test --provider openai")
    print("   4. Solve a problem: python putnam_cli.py solve dataset/1938-A-1.json")
    print("   5. Run benchmark: python benchmark.py --quick-test")
    print("\nšŸ’” Available Scripts:")
    print("   • putnam_cli.py - Main CLI interface")
    print("   • health_check.py - Check provider health")
    print("   • batch_evaluate.py - Batch evaluation")
    print("   • benchmark.py - Performance comparison")
    print("   • setup_config.py - Configuration management")
    print("   • local_models_example.py - Local model examples")
    print("\nšŸ“– Documentation: See README.md for detailed usage")


async def main():
    """Main installation function."""
    parser = argparse.ArgumentParser(description="Install Putnam Problem Solver")
    parser.add_argument("--quick", action="store_true", 
                       help="Quick install (core packages only)")
    parser.add_argument("--check-only", action="store_true",
                       help="Check what would be installed without installing")
    parser.add_argument("--no-setup", action="store_true",
                       help="Skip interactive configuration setup")
    parser.add_argument("--no-alias", action="store_true",
                       help="Skip creating command alias")
    
    args = parser.parse_args()
    
    print_banner()
    
    # Check Python version
    if not check_python():
        return 1
    
    # Check packages
    missing_packages = get_missing_packages(include_optional=not args.quick)
    
    if args.check_only:
        if missing_packages:
            print(f"\nšŸ“‹ Would install: {', '.join(missing_packages)}")
        else:
            print("\nāœ… All packages are already installed!")
        return 0
    
    # Install packages
    if missing_packages:
        print(f"\nšŸ“¦ Installing {len(missing_packages)} packages...")
        if not install_packages(missing_packages):
            return 1
    else:
        print("\nāœ… All packages are already installed!")
    
    # Create alias
    if not args.no_alias:
        print("\nšŸ”— Creating command alias...")
        create_alias()
    
    # Run configuration setup
    if not args.no_setup:
        if input("\nšŸ› ļø Run configuration setup now? (y/n): ").lower().startswith('y'):
            await run_setup()
        else:
            print("šŸ’” You can run setup later with: python setup_config.py")
    
    # Print next steps
    print_next_steps()
    
    return 0


if __name__ == "__main__":
    exit(asyncio.run(main()))