Spaces:
Sleeping
Sleeping
| """Application configuration using pydantic-settings.""" | |
| from __future__ import annotations | |
| import os | |
| from enum import Enum | |
| from pathlib import Path | |
| from typing import Optional | |
| from pydantic import Field, field_validator | |
| from pydantic_settings import BaseSettings | |
| class EnvType(str, Enum): | |
| CONDA = "conda" | |
| VENV = "venv" | |
| VENV_UV = "venv-uv" | |
| class Settings(BaseSettings): | |
| """Application settings loaded from environment variables.""" | |
| # Server settings | |
| app_name: str = "MCP Code Executor" | |
| debug: bool = False | |
| host: str = "0.0.0.0" | |
| port: int = 7860 | |
| # Code storage | |
| code_storage_dir: str = Field( | |
| default="/app/code_storage", | |
| description="Directory where generated code files are stored", | |
| ) | |
| # Environment configuration | |
| env_type: EnvType = Field(default=EnvType.VENV_UV, description="Python environment type") | |
| conda_env_name: Optional[str] = Field(default=None, description="Conda environment name") | |
| venv_path: Optional[str] = Field(default=None, description="Path to virtualenv") | |
| uv_venv_path: Optional[str] = Field( | |
| default="/app/executor_venv", description="Path to UV virtualenv" | |
| ) | |
| # Execution settings | |
| execution_timeout: int = Field( | |
| default=120, description="Maximum execution time in seconds", ge=5, le=600 | |
| ) | |
| max_concurrent_executions: int = Field( | |
| default=20, description="Maximum concurrent code executions", ge=1, le=100 | |
| ) | |
| max_output_size: int = Field( | |
| default=1_048_576, description="Maximum output size in bytes (1MB)", ge=1024 | |
| ) | |
| max_file_size: int = Field( | |
| default=10_485_760, description="Maximum file size in bytes (10MB)", ge=1024 | |
| ) | |
| # HF Space | |
| hf_space: bool = Field(default=False, description="Running on HuggingFace Space") | |
| def ensure_storage_dir_exists(cls, v: str) -> str: | |
| path = Path(v) | |
| path.mkdir(parents=True, exist_ok=True) | |
| return str(path.resolve()) | |
| def get_python_executable(self) -> str: | |
| """Get the Python executable path for the configured environment.""" | |
| if self.env_type == EnvType.CONDA: | |
| if not self.conda_env_name: | |
| raise ValueError("CONDA_ENV_NAME must be set when ENV_TYPE is conda") | |
| return f"conda run -n {self.conda_env_name} python" | |
| elif self.env_type == EnvType.VENV: | |
| if not self.venv_path: | |
| raise ValueError("VENV_PATH must be set when ENV_TYPE is venv") | |
| return str(Path(self.venv_path) / "bin" / "python") | |
| elif self.env_type == EnvType.VENV_UV: | |
| if not self.uv_venv_path: | |
| raise ValueError("UV_VENV_PATH must be set when ENV_TYPE is venv-uv") | |
| return str(Path(self.uv_venv_path) / "bin" / "python") | |
| raise ValueError(f"Unknown environment type: {self.env_type}") | |
| def get_pip_command(self) -> list[str]: | |
| """Get the pip install command for the configured environment.""" | |
| if self.env_type == EnvType.CONDA: | |
| return ["conda", "install", "-n", self.conda_env_name, "-y"] | |
| elif self.env_type == EnvType.VENV: | |
| pip_path = str(Path(self.venv_path) / "bin" / "pip") | |
| return [pip_path, "install"] | |
| elif self.env_type == EnvType.VENV_UV: | |
| return ["uv", "pip", "install", "--python", str(Path(self.uv_venv_path) / "bin" / "python")] | |
| raise ValueError(f"Unknown environment type: {self.env_type}") | |
| model_config = { | |
| "env_prefix": "", | |
| "case_sensitive": False, | |
| "env_file": ".env", | |
| "env_file_encoding": "utf-8", | |
| } | |
| # Singleton settings instance | |
| _settings: Optional[Settings] = None | |
| def get_settings() -> Settings: | |
| """Get or create the settings singleton.""" | |
| global _settings | |
| if _settings is None: | |
| _settings = Settings() | |
| return _settings | |
| def update_settings(**kwargs) -> Settings: | |
| """Update settings with new values (for dynamic configuration).""" | |
| global _settings | |
| current = get_settings() | |
| new_data = current.model_dump() | |
| new_data.update(kwargs) | |
| _settings = Settings(**new_data) | |
| return _settings |