Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .env.backup
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Development Environment Configuration

# API Keys (Development)
OPENAI_API_KEY=your_dev_openai_key
ANTHROPIC_API_KEY=your_dev_anthropic_key
GOOGLE_API_KEY=your_dev_google_key

# Database Configuration (Development)
DB_HOST=localhost
DB_PORT=5432
DB_NAME=mcp_dev
DB_USER=dev_user
DB_PASSWORD=dev_password

# Development Settings
DEBUG=true
LOG_LEVEL=DEBUG
ENVIRONMENT=development

# Development Tools Configuration
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=0
PYTEST_ADDOPTS="--color=yes"

# Development URLs
API_BASE_URL=http://localhost:8000
FRONTEND_URL=http://localhost:3000
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ celerybeat.pid

# Environments
.env
.env.dev
.venv
env/
venv/
Expand Down
Empty file added dev/scripts/__init__.py
Empty file.
Empty file added dev/tests/__init__.py
Empty file.
Empty file added dev/tests/mcp/__init__.py
Empty file.
Empty file added dev/tests/mcp/unit/__init__.py
Empty file.
62 changes: 62 additions & 0 deletions dev/tests/mcp/unit/test_dev_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import os
import sys
import pytest
from pathlib import Path

def test_dev_tools_structure():
"""Test that development tools are properly organized."""
# Test that dev directory exists
dev_dir = Path('dev')
assert dev_dir.exists()
assert dev_dir.is_dir()

# Test that tools directory exists
tools_dir = dev_dir / 'tools'
assert tools_dir.exists()
assert tools_dir.is_dir()

# Test that scripts directory exists
scripts_dir = dev_dir / 'scripts'
assert scripts_dir.exists()
assert scripts_dir.is_dir()

def test_dev_tools_imports():
"""Test that development tools can be imported."""
# Add dev directory to Python path
dev_tools_path = os.path.abspath('dev/tools')
if dev_tools_path not in sys.path:
sys.path.append(dev_tools_path)

try:
# Test importing tools
import llm_api
import web_scraper
import search_engine
import screenshot_utils

# Test basic attributes
assert hasattr(llm_api, 'query_llm')
assert hasattr(web_scraper, 'scrape_urls')
assert hasattr(search_engine, 'search')
assert hasattr(screenshot_utils, 'take_screenshot_sync')
except ImportError as e:
pytest.fail(f"Failed to import development tools: {e}")

def test_dev_requirements():
"""Test that development requirements are installed."""
import pkg_resources

with open('requirements-dev.txt') as f:
requirements = [
line.strip()
for line in f
if line.strip() and not line.startswith('#') and not line.startswith('-r')
]

for requirement in requirements:
try:
pkg_resources.require(requirement)
except pkg_resources.DistributionNotFound:
pytest.fail(f"Required package not found: {requirement}")
except pkg_resources.VersionConflict:
pytest.fail(f"Version conflict for package: {requirement}")
54 changes: 54 additions & 0 deletions dev/tests/mcp/unit/test_env_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import os
import pytest
from pathlib import Path
from dev.tools.env_manager import backup_env, switch_environment, list_environments

@pytest.fixture
def temp_env_files(tmp_path):
"""Create temporary environment files for testing."""
# Create test environment files
(tmp_path / '.env.dev').write_text('DEV=true')
(tmp_path / '.env.prod').write_text('PROD=true')
(tmp_path / '.env').write_text('CURRENT=true')

# Change to temp directory for tests
original_dir = os.getcwd()
os.chdir(tmp_path)

yield tmp_path

# Cleanup and restore original directory
os.chdir(original_dir)

def test_backup_env(temp_env_files):
"""Test environment file backup functionality."""
env_path = temp_env_files / '.env'
backup_path = backup_env(env_path)

assert backup_path.exists()
assert backup_path.name == '.env.backup'
assert backup_path.read_text() == 'CURRENT=true'

def test_switch_environment(temp_env_files):
"""Test switching between environments."""
# Switch to dev environment
switch_environment('dev')

env_path = temp_env_files / '.env'
assert env_path.exists()
if os.name != 'nt': # Skip symlink check on Windows
assert env_path.is_symlink()
assert env_path.resolve() == temp_env_files / '.env.dev'

def test_switch_to_nonexistent_environment(temp_env_files):
"""Test switching to a non-existent environment."""
with pytest.raises(FileNotFoundError):
switch_environment('nonexistent')

def test_list_environments(temp_env_files, capsys):
"""Test listing available environments."""
list_environments()
captured = capsys.readouterr()

assert 'dev' in captured.out
assert 'prod' in captured.out
53 changes: 53 additions & 0 deletions dev/tests/mcp/unit/test_environment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import os
import pytest
from pathlib import Path
from dotenv import load_dotenv
from dev.tools.env_manager import switch_environment

@pytest.fixture(scope='module')
def dev_environment():
"""Set up development environment for tests."""
# Store current environment
original_env = {}
env_vars = ['ENVIRONMENT', 'DEBUG', 'LOG_LEVEL', 'API_BASE_URL', 'FRONTEND_URL']
for var in env_vars:
original_env[var] = os.getenv(var)

# Switch to dev environment
switch_environment('dev')
load_dotenv()

yield

# Restore original environment variables
for var, value in original_env.items():
if value is None:
os.unsetenv(var)
else:
os.environ[var] = value

def test_environment_variables(dev_environment):
"""Test that required environment variables are set."""
# Test environment type
assert os.getenv('ENVIRONMENT') == 'development'

# Test debug mode
assert os.getenv('DEBUG') == 'true'

# Test log level
assert os.getenv('LOG_LEVEL') == 'DEBUG'

def test_python_environment(dev_environment):
"""Test Python environment setup."""
# Test that we're running in a virtual environment
assert os.getenv('VIRTUAL_ENV') is not None

# Test that pytest is installed
import pytest
assert pytest.__version__ >= '8.3.4'

def test_api_configuration(dev_environment):
"""Test API configuration."""
# Test API URLs are set
assert os.getenv('API_BASE_URL') == 'http://localhost:8000'
assert os.getenv('FRONTEND_URL') == 'http://localhost:3000'
56 changes: 56 additions & 0 deletions dev/tests/mcp/unit/test_llm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import os
import pytest
from pathlib import Path
from dotenv import load_dotenv
from dev.tools.env_manager import switch_environment

@pytest.fixture(scope='module')
def dev_environment():
"""Set up development environment for tests."""
# Store current environment
original_env = {}
env_vars = ['OPENAI_API_KEY', 'ANTHROPIC_API_KEY', 'GOOGLE_API_KEY']
for var in env_vars:
original_env[var] = os.getenv(var)

# Switch to dev environment
switch_environment('dev')
load_dotenv()

yield

# Restore original environment variables
for var, value in original_env.items():
if value is None:
os.unsetenv(var)
else:
os.environ[var] = value

def test_llm_api_keys_exist(dev_environment):
"""Test that LLM API keys are set."""
# Test OpenAI API key
openai_key = os.getenv('OPENAI_API_KEY')
assert openai_key is not None, "OpenAI API key not found"

# Test Anthropic API key
anthropic_key = os.getenv('ANTHROPIC_API_KEY')
assert anthropic_key is not None, "Anthropic API key not found"

# Test Google API key
google_key = os.getenv('GOOGLE_API_KEY')
assert google_key is not None, "Google API key not found"

@pytest.mark.asyncio
async def test_llm_imports(dev_environment):
"""Test that LLM libraries are properly installed."""
# Test OpenAI
import openai
assert openai.__version__ >= '1.63.2'

# Test Anthropic
import anthropic
assert anthropic.__version__ >= '0.46.0'

# Test Google Generative AI
import google.generativeai as genai
assert genai.__package__ == 'google.generativeai'
Empty file added dev/tools/__init__.py
Empty file.
85 changes: 85 additions & 0 deletions dev/tools/env_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import os
import shutil
import argparse
from pathlib import Path
from typing import Optional

def backup_env(env_path: Path, backup_suffix: str = 'backup') -> Optional[Path]:
"""Backup existing .env file if it exists."""
if env_path.exists():
backup_path = env_path.with_suffix(f'.{backup_suffix}')
shutil.copy2(env_path, backup_path)
return backup_path
return None

def switch_environment(env_type: str) -> None:
"""Switch to a different environment configuration."""
root_dir = Path.cwd()
env_path = root_dir / '.env'
target_env = root_dir / f'.env.{env_type}'

if not target_env.exists():
raise FileNotFoundError(f"Environment file .env.{env_type} not found")

# Create backup of current .env if it exists
if env_path.exists():
backup_path = backup_env(env_path)
print(f"Backed up current .env to {backup_path}")

# Create symlink to target environment
if os.name == 'nt': # Windows
import ctypes
if not ctypes.windll.shell32.IsUserAnAdmin():
print("Warning: On Windows, you may need admin privileges to create symlinks")
os.system(f'mklink {env_path} {target_env}')
else: # Unix-like
if env_path.exists():
env_path.unlink()
env_path.symlink_to(target_env)

print(f"Switched to {env_type} environment")

def list_environments() -> None:
"""List all available environment configurations."""
root_dir = Path.cwd()
env_files = list(root_dir.glob('.env.*'))

if not env_files:
print("No environment configurations found")
return

print("\nAvailable environments:")
for env_file in env_files:
env_type = env_file.suffix[1:] # Remove the leading dot
if env_type != 'backup':
print(f"- {env_type}")

current_env = root_dir / '.env'
if current_env.exists() and current_env.is_symlink():
current = current_env.resolve().name.replace('.env.', '')
print(f"\nCurrent environment: {current}")
else:
print("\nCurrent environment: not linked to any environment file")

def main():
parser = argparse.ArgumentParser(description='Manage environment configurations')
parser.add_argument('action', choices=['switch', 'list'], help='Action to perform')
parser.add_argument('--env', help='Environment to switch to (e.g., dev, prod)')

args = parser.parse_args()

try:
if args.action == 'list':
list_environments()
elif args.action == 'switch':
if not args.env:
parser.error("--env is required when using 'switch'")
switch_environment(args.env)
except Exception as e:
print(f"Error: {e}")
return 1

return 0

if __name__ == '__main__':
exit(main())
Loading
Loading