Spaces:
Running
Running
| # SPDX-License-Identifier: BSD-3-Clause | |
| """CLI utilities for OpenEnv command-line interface.""" | |
| from pathlib import Path | |
| from typing import List | |
| from rich.console import Console | |
| # Create a console instance for CLI output | |
| console = Console() | |
| def _extract_hf_username(user_info: object) -> str | None: | |
| """Extract a username from the supported Hugging Face whoami shapes.""" | |
| if isinstance(user_info, dict): | |
| return ( | |
| user_info.get("name") | |
| or user_info.get("fullname") | |
| or user_info.get("username") | |
| ) | |
| return ( | |
| getattr(user_info, "name", None) | |
| or getattr(user_info, "fullname", None) | |
| or getattr(user_info, "username", None) | |
| ) | |
| def validate_env_structure(env_dir: Path, strict: bool = False) -> List[str]: | |
| """ | |
| Validate that the directory follows OpenEnv environment structure. | |
| Args: | |
| env_dir (`Path`): | |
| Path to the environment directory. | |
| strict (`bool`, *optional*, defaults to `False`): | |
| If `True`, enforce all optional requirements. | |
| Returns: | |
| `list` of validation warnings (empty if all checks pass). | |
| Raises: | |
| `FileNotFoundError`: If required files are missing. | |
| """ | |
| warnings = [] | |
| # Required files | |
| required_files = [ | |
| "openenv.yaml", | |
| "__init__.py", | |
| "client.py", | |
| "models.py", | |
| "README.md", | |
| ] | |
| for file in required_files: | |
| if not (env_dir / file).exists(): | |
| raise FileNotFoundError(f"Required file missing: {file}") | |
| # Dockerfile: must exist in server/ or at env root | |
| has_root_dockerfile = (env_dir / "Dockerfile").exists() | |
| has_server_dockerfile = (env_dir / "server" / "Dockerfile").exists() | |
| if not has_root_dockerfile and not has_server_dockerfile: | |
| raise FileNotFoundError( | |
| "Required file missing: server/Dockerfile or Dockerfile at env root" | |
| ) | |
| # When no root Dockerfile, require the traditional server/ layout | |
| if not has_root_dockerfile: | |
| server_dir = env_dir / "server" | |
| if not server_dir.exists() or not server_dir.is_dir(): | |
| raise FileNotFoundError("Required directory missing: server/") | |
| for file in ["server/__init__.py", "server/app.py"]: | |
| if not (env_dir / file).exists(): | |
| raise FileNotFoundError(f"Required file missing: {file}") | |
| # Check for dependency management (pyproject.toml required) | |
| has_pyproject = (env_dir / "pyproject.toml").exists() | |
| if not has_pyproject: | |
| raise FileNotFoundError( | |
| "No dependency specification found. 'pyproject.toml' is required." | |
| ) | |
| # Warnings for recommended structure | |
| if not (env_dir / "outputs").exists(): | |
| warnings.append("Recommended directory missing: outputs/") | |
| return warnings | |