| |
| """ |
| Hugging Face Space Authentication Setup (GitHub Secrets) |
| |
| This script helps set up proper authentication for Hugging Face Spaces |
| using GitHub secrets to ensure training and model uploads work correctly. |
| |
| Features: |
| - Sets up authentication for Hugging Face Spaces using GitHub secrets |
| - Tests repository creation and upload capabilities |
| - Provides configuration for Space environments |
| - Validates authentication before training |
| |
| Usage: |
| python setup_hf_space_auth.py |
| |
| Author: Louis Chua Bean Chong |
| License: GPLv3 |
| """ |
|
|
| import os |
| import sys |
| import json |
| from pathlib import Path |
|
|
| try: |
| from huggingface_hub import HfApi, login, whoami, create_repo |
| from huggingface_hub.utils import HfHubHTTPError |
| HF_AVAILABLE = True |
| except ImportError: |
| HF_AVAILABLE = False |
| print("β huggingface_hub not installed") |
| sys.exit(1) |
|
|
|
|
| class HuggingFaceSpaceAuthSetup: |
| """ |
| Sets up authentication for Hugging Face Spaces training and upload using GitHub secrets. |
| """ |
| |
| def __init__(self): |
| """Initialize the Space authentication setup.""" |
| self.api = None |
| self.username = None |
| self.is_authenticated = False |
| self.space_config = {} |
| |
| def setup_space_authentication(self) -> bool: |
| """ |
| Set up authentication specifically for Hugging Face Spaces using GitHub secrets. |
| |
| Returns: |
| True if authentication successful, False otherwise |
| """ |
| print("π Hugging Face Space Authentication Setup (GitHub Secrets)") |
| print("=" * 65) |
| |
| |
| is_space = self._check_if_in_space() |
| |
| if is_space: |
| print("β
Running in Hugging Face Space environment") |
| return self._setup_space_env_auth() |
| else: |
| print("βΉοΈ Running in local environment") |
| return self._setup_local_auth() |
| |
| def _check_if_in_space(self) -> bool: |
| """Check if we're running in a Hugging Face Space.""" |
| space_env_vars = [ |
| "SPACE_ID", |
| "SPACE_HOST", |
| "SPACE_REPO_ID", |
| "HF_HUB_ENABLE_HF_TRANSFER" |
| ] |
| |
| for var in space_env_vars: |
| if os.getenv(var): |
| print(f" - Found Space environment variable: {var}") |
| return True |
| |
| return False |
| |
| def _setup_space_env_auth(self) -> bool: |
| """Set up authentication in Hugging Face Space environment using GitHub secrets.""" |
| print("\nπ Setting up Space Environment Authentication (GitHub Secrets)") |
| print("-" * 60) |
| |
| |
| token = os.getenv("HF_TOKEN") |
| if not token: |
| print("β HF_TOKEN not found in Space environment") |
| print(" - This should be set in your GitHub repository secrets") |
| print(" - Go to your GitHub repository β Settings β Secrets and variables β Actions") |
| print(" - Add HF_TOKEN with your Hugging Face token") |
| print(" - The Space will automatically have access to this secret") |
| return False |
| |
| try: |
| |
| login(token=token) |
| |
| |
| self.api = HfApi() |
| user_info = whoami() |
| |
| self.username = user_info["name"] |
| self.is_authenticated = True |
| |
| print(f"β
Space authentication successful!") |
| print(f" - Username: {self.username}") |
| print(f" - Token: {token[:8]}...{token[-4:]}") |
| print(f" - Source: GitHub secrets") |
| |
| |
| self.space_config = { |
| "is_space": True, |
| "username": self.username, |
| "space_id": os.getenv("SPACE_ID"), |
| "space_host": os.getenv("SPACE_HOST"), |
| "space_repo_id": os.getenv("SPACE_REPO_ID"), |
| "auth_source": "github_secrets" |
| } |
| |
| return True |
| |
| except Exception as e: |
| print(f"β Space authentication failed: {e}") |
| return False |
| |
| def _setup_local_auth(self) -> bool: |
| """Set up authentication in local environment.""" |
| print("\nπ Setting up Local Environment Authentication") |
| print("-" * 45) |
| |
| try: |
| |
| user_info = whoami() |
| self.username = user_info["name"] |
| self.api = HfApi() |
| self.is_authenticated = True |
| |
| print(f"β
Already authenticated as: {self.username}") |
| return True |
| |
| except Exception as e: |
| print(f"β Not authenticated: {e}") |
| print("π Attempting to authenticate...") |
| |
| |
| token = os.getenv("HUGGING_FACE_HUB_TOKEN") or os.getenv("HF_TOKEN") |
| if token: |
| try: |
| login(token=token) |
| user_info = whoami() |
| self.username = user_info["name"] |
| self.api = HfApi() |
| self.is_authenticated = True |
| |
| print(f"β
Authenticated with token as: {self.username}") |
| return True |
| |
| except Exception as token_error: |
| print(f"β Token authentication failed: {token_error}") |
| |
| print("β Authentication failed") |
| return False |
| |
| def test_repository_creation(self) -> bool: |
| """ |
| Test repository creation capabilities. |
| |
| Returns: |
| True if successful, False otherwise |
| """ |
| if not self.is_authenticated: |
| print("β Not authenticated") |
| return False |
| |
| print(f"\nπ§ͺ Testing Repository Creation") |
| print("-" * 35) |
| |
| try: |
| |
| repo_name = "test-openllm-space-auth" |
| repo_id = f"{self.username}/{repo_name}" |
| |
| print(f"π Creating test repository: {repo_id}") |
| create_repo( |
| repo_id=repo_id, |
| repo_type="model", |
| exist_ok=True, |
| private=True |
| ) |
| |
| print(f"β
Test repository created successfully") |
| |
| |
| from huggingface_hub import delete_repo |
| print(f"π Cleaning up test repository...") |
| delete_repo(repo_id=repo_id, repo_type="model") |
| print(f"β
Test repository deleted") |
| |
| return True |
| |
| except Exception as e: |
| print(f"β Repository creation test failed: {e}") |
| return False |
| |
| def test_model_upload(self) -> bool: |
| """ |
| Test model upload capabilities. |
| |
| Returns: |
| True if successful, False otherwise |
| """ |
| if not self.is_authenticated: |
| print("β Not authenticated") |
| return False |
| |
| print(f"\nπ€ Testing Model Upload") |
| print("-" * 25) |
| |
| try: |
| |
| test_file = "test_upload.txt" |
| with open(test_file, "w") as f: |
| f.write("This is a test file for Hugging Face Space upload verification.\n") |
| f.write("Generated by setup_hf_space_auth.py (GitHub Secrets)\n") |
| |
| |
| repo_name = "test-upload-openllm-space" |
| repo_id = f"{self.username}/{repo_name}" |
| |
| from huggingface_hub import create_repo, delete_repo |
| |
| create_repo( |
| repo_id=repo_id, |
| repo_type="model", |
| exist_ok=True, |
| private=True |
| ) |
| |
| |
| print(f"π Uploading test file to {repo_id}...") |
| self.api.upload_file( |
| path_or_fileobj=test_file, |
| path_in_repo="test_file.txt", |
| repo_id=repo_id, |
| repo_type="model", |
| commit_message="Test upload from OpenLLM Space auth setup (GitHub Secrets)" |
| ) |
| |
| print(f"β
Test upload successful!") |
| |
| |
| print(f"π Cleaning up...") |
| delete_repo(repo_id=repo_id, repo_type="model") |
| os.remove(test_file) |
| print(f"β
Cleanup completed") |
| |
| return True |
| |
| except Exception as e: |
| print(f"β Upload test failed: {e}") |
| |
| if os.path.exists("test_upload.txt"): |
| os.remove("test_upload.txt") |
| return False |
| |
| def create_space_config(self) -> bool: |
| """ |
| Create configuration file for Hugging Face Space. |
| |
| Returns: |
| True if successful, False otherwise |
| """ |
| if not self.is_authenticated: |
| print("β Not authenticated") |
| return False |
| |
| print(f"\nπ Creating Space Configuration") |
| print("-" * 30) |
| |
| config = { |
| "authentication": { |
| "username": self.username, |
| "authenticated": self.is_authenticated, |
| "method": "github_secrets" if self.space_config.get("auth_source") == "github_secrets" else "local_token" |
| }, |
| "space_config": self.space_config, |
| "model_upload": { |
| "default_repo_prefix": f"{self.username}/openllm", |
| "supported_sizes": ["small", "medium", "large"], |
| "upload_enabled": True |
| }, |
| "training": { |
| "checkpoint_upload": True, |
| "final_model_upload": True, |
| "create_model_card": True |
| } |
| } |
| |
| |
| config_path = ".hf_space_config.json" |
| with open(config_path, "w") as f: |
| json.dump(config, f, indent=2) |
| |
| print(f"β
Space configuration saved to: {config_path}") |
| return True |
| |
| def generate_space_instructions(self) -> str: |
| """Generate instructions for setting up Hugging Face Space with GitHub secrets.""" |
| instructions = f""" |
| π― Hugging Face Space Setup Instructions (GitHub Secrets) |
| |
| 1. **Set up GitHub Repository Secrets:** |
| - Go to your GitHub repository: https://github.com/your-username/your-repo |
| - Click on "Settings" tab |
| - Click on "Secrets and variables" β "Actions" |
| - Click "New repository secret" |
| - Add a new secret: |
| - Name: HF_TOKEN |
| - Value: Your Hugging Face token (get from https://huggingface.co/settings/tokens) |
| |
| 2. **Verify Authentication:** |
| - Run this script in your Space to verify authentication works |
| - The script will test repository creation and upload capabilities |
| - GitHub secrets are automatically available in Hugging Face Spaces |
| |
| 3. **Training Configuration:** |
| - Your training script should use the authentication setup |
| - Model uploads will go to: https://huggingface.co/{self.username}/openllm-* |
| - Checkpoints will be saved during training |
| |
| 4. **Expected Results:** |
| - Training will complete successfully |
| - Model will be uploaded to Hugging Face Hub |
| - Repository will be created with proper model files |
| - Model card and configuration will be generated |
| |
| 5. **Troubleshooting:** |
| - If upload fails, check HF_TOKEN is set correctly in GitHub secrets |
| - Verify token has "Write" permissions |
| - Check Space logs for detailed error messages |
| - Ensure your Space is connected to the GitHub repository |
| """ |
| return instructions |
|
|
|
|
| def main(): |
| """Main function to run the Space authentication setup.""" |
| print("π OpenLLM - Hugging Face Space Authentication Setup (GitHub Secrets)") |
| print("=" * 70) |
| |
| |
| auth_setup = HuggingFaceSpaceAuthSetup() |
| |
| |
| if not auth_setup.setup_space_authentication(): |
| print("\nβ Authentication setup failed") |
| print("\nπ§ Troubleshooting:") |
| print("1. Get a Hugging Face token from https://huggingface.co/settings/tokens") |
| print("2. In GitHub: Set HF_TOKEN in Repository secrets (Settings β Secrets and variables β Actions)") |
| print("3. Locally: Set HUGGING_FACE_HUB_TOKEN environment variable") |
| sys.exit(1) |
| |
| print(f"\nβ
Authentication successful!") |
| print(f" - Username: {auth_setup.username}") |
| |
| |
| repo_success = auth_setup.test_repository_creation() |
| |
| |
| upload_success = auth_setup.test_model_upload() |
| |
| |
| config_success = auth_setup.create_space_config() |
| |
| |
| print(f"\nπ Setup Results") |
| print("-" * 20) |
| print(f"β
Authentication: PASSED") |
| print(f"{'β
' if repo_success else 'β'} Repository Creation: {'PASSED' if repo_success else 'FAILED'}") |
| print(f"{'β
' if upload_success else 'β'} Model Upload: {'PASSED' if upload_success else 'FAILED'}") |
| print(f"{'β
' if config_success else 'β'} Configuration: {'PASSED' if config_success else 'FAILED'}") |
| |
| if repo_success and upload_success: |
| print(f"\nπ Space authentication setup completed successfully!") |
| print(f" - You can now run training in Hugging Face Spaces") |
| print(f" - Model uploads will work correctly") |
| print(f" - Your models will be uploaded to: https://huggingface.co/{auth_setup.username}") |
| |
| |
| print(auth_setup.generate_space_instructions()) |
| else: |
| print(f"\nβ οΈ Some tests failed. Check the error messages above.") |
| sys.exit(1) |
| |
| return True |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|