Spaces:
Running
Running
adds correct huggingface spaces api deployment
Browse files- docs/LATEST_DEPLOYMENT_APPROACH.md +267 -0
- docs/TRACKIO_SPACE_DEPLOYMENT_FIXES.md +262 -0
- TRAINING_FIXES_SUMMARY.md β docs/TRAINING_FIXES_SUMMARY.md +0 -0
- requirements/requirements_core.txt +6 -7
- scripts/trackio_tonic/deploy_trackio_space.py +149 -99
- templates/spaces/README.md +94 -11
- templates/spaces/requirements.txt +14 -12
- tests/test_latest_deployment.py +253 -0
- tests/test_trackio_deployment.py +244 -0
docs/LATEST_DEPLOYMENT_APPROACH.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Latest Trackio Space Deployment Approach
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
Based on the [Hugging Face Hub repository code](https://github.com/huggingface/huggingface_hub/blob/9e0493cfdb4de5a27b45c53c3342c83ab1a138fb/src/huggingface_hub/commands/repo.py#L30), I've updated the Trackio Space deployment to use the latest Hugging Face Hub Python API instead of CLI commands.
|
| 6 |
+
|
| 7 |
+
## Key Improvements
|
| 8 |
+
|
| 9 |
+
### 1. **Latest HF Hub API Integration**
|
| 10 |
+
|
| 11 |
+
**Before**: Using CLI commands
|
| 12 |
+
```python
|
| 13 |
+
cmd = ["huggingface-cli", "repo", "create", f"{username}/{space_name}", "--type", "space"]
|
| 14 |
+
```
|
| 15 |
+
|
| 16 |
+
**After**: Using Python API
|
| 17 |
+
```python
|
| 18 |
+
from huggingface_hub import create_repo
|
| 19 |
+
|
| 20 |
+
create_repo(
|
| 21 |
+
repo_id=f"{username}/{space_name}",
|
| 22 |
+
token=token,
|
| 23 |
+
repo_type="space",
|
| 24 |
+
exist_ok=True,
|
| 25 |
+
private=False,
|
| 26 |
+
space_sdk="gradio",
|
| 27 |
+
space_hardware="cpu-basic"
|
| 28 |
+
)
|
| 29 |
+
```
|
| 30 |
+
|
| 31 |
+
### 2. **Robust Fallback Mechanism**
|
| 32 |
+
|
| 33 |
+
The deployment script now includes both API and CLI approaches:
|
| 34 |
+
|
| 35 |
+
```python
|
| 36 |
+
def create_space(self) -> bool:
|
| 37 |
+
"""Create a new Hugging Face Space using the latest API"""
|
| 38 |
+
try:
|
| 39 |
+
if not HF_HUB_AVAILABLE:
|
| 40 |
+
return self._create_space_cli()
|
| 41 |
+
|
| 42 |
+
# Use latest API
|
| 43 |
+
create_repo(...)
|
| 44 |
+
|
| 45 |
+
except Exception as api_error:
|
| 46 |
+
# Fallback to CLI
|
| 47 |
+
return self._create_space_cli()
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
### 3. **Enhanced Dependencies**
|
| 51 |
+
|
| 52 |
+
Updated `requirements/requirements_core.txt`:
|
| 53 |
+
```txt
|
| 54 |
+
# Hugging Face Hub for model and space management
|
| 55 |
+
huggingface_hub>=0.19.0
|
| 56 |
+
```
|
| 57 |
+
|
| 58 |
+
## API Parameters
|
| 59 |
+
|
| 60 |
+
### **Required Parameters**
|
| 61 |
+
- `repo_id`: Repository identifier (username/space-name)
|
| 62 |
+
- `token`: Hugging Face token with write permissions
|
| 63 |
+
|
| 64 |
+
### **Optional Parameters**
|
| 65 |
+
- `repo_type`: Set to "space" for Spaces
|
| 66 |
+
- `exist_ok`: Allow existing repositories (default: True)
|
| 67 |
+
- `private`: Make repository private (default: False)
|
| 68 |
+
- `space_sdk`: SDK type (default: "gradio")
|
| 69 |
+
- `space_hardware`: Hardware specification (default: "cpu-basic")
|
| 70 |
+
|
| 71 |
+
## Deployment Process
|
| 72 |
+
|
| 73 |
+
### **Step 1: API Creation**
|
| 74 |
+
```python
|
| 75 |
+
# Create space using latest API
|
| 76 |
+
create_repo(
|
| 77 |
+
repo_id=f"{username}/{space_name}",
|
| 78 |
+
token=token,
|
| 79 |
+
repo_type="space",
|
| 80 |
+
exist_ok=True,
|
| 81 |
+
private=False,
|
| 82 |
+
space_sdk="gradio",
|
| 83 |
+
space_hardware="cpu-basic"
|
| 84 |
+
)
|
| 85 |
+
```
|
| 86 |
+
|
| 87 |
+
### **Step 2: File Preparation**
|
| 88 |
+
```python
|
| 89 |
+
# Prepare files in temporary directory
|
| 90 |
+
temp_dir = tempfile.mkdtemp()
|
| 91 |
+
# Copy template files
|
| 92 |
+
shutil.copy2(source_path, dest_path)
|
| 93 |
+
# Update README with actual space URL
|
| 94 |
+
readme_content.replace("{SPACE_URL}", self.space_url)
|
| 95 |
+
```
|
| 96 |
+
|
| 97 |
+
### **Step 3: Git Upload**
|
| 98 |
+
```python
|
| 99 |
+
# Initialize git in temp directory
|
| 100 |
+
os.chdir(temp_dir)
|
| 101 |
+
subprocess.run(["git", "init"], check=True)
|
| 102 |
+
subprocess.run(["git", "remote", "add", "origin", space_url], check=True)
|
| 103 |
+
subprocess.run(["git", "add", "."], check=True)
|
| 104 |
+
subprocess.run(["git", "commit", "-m", "Initial Trackio Space setup"], check=True)
|
| 105 |
+
subprocess.run(["git", "push", "origin", "main"], check=True)
|
| 106 |
+
```
|
| 107 |
+
|
| 108 |
+
## Testing the Latest Deployment
|
| 109 |
+
|
| 110 |
+
### **Run Latest Deployment Tests**
|
| 111 |
+
```bash
|
| 112 |
+
python tests/test_latest_deployment.py
|
| 113 |
+
```
|
| 114 |
+
|
| 115 |
+
Expected output:
|
| 116 |
+
```
|
| 117 |
+
π Testing Latest Trackio Space Deployment
|
| 118 |
+
=======================================================
|
| 119 |
+
π Testing huggingface_hub import...
|
| 120 |
+
β
huggingface_hub imported successfully
|
| 121 |
+
|
| 122 |
+
π Testing deployment script import...
|
| 123 |
+
β
TrackioSpaceDeployer class imported successfully
|
| 124 |
+
β
HF API initialized
|
| 125 |
+
|
| 126 |
+
π Testing API methods...
|
| 127 |
+
β
Method exists: create_space
|
| 128 |
+
β
Method exists: _create_space_cli
|
| 129 |
+
β
Method exists: prepare_space_files
|
| 130 |
+
β
Method exists: upload_files_to_space
|
| 131 |
+
β
Method exists: test_space
|
| 132 |
+
β
Method exists: deploy
|
| 133 |
+
|
| 134 |
+
π Testing create_repo API...
|
| 135 |
+
β
Required parameter: repo_id
|
| 136 |
+
β
Required parameter: token
|
| 137 |
+
β
Optional parameter: repo_type
|
| 138 |
+
β
Optional parameter: space_sdk
|
| 139 |
+
β
Optional parameter: space_hardware
|
| 140 |
+
β
create_repo API signature looks correct
|
| 141 |
+
|
| 142 |
+
π Testing space creation logic...
|
| 143 |
+
β
Space URL formatted correctly
|
| 144 |
+
β
Repo ID formatted correctly
|
| 145 |
+
|
| 146 |
+
π Testing template files...
|
| 147 |
+
β
app.py exists
|
| 148 |
+
β
requirements.txt exists
|
| 149 |
+
β
README.md exists
|
| 150 |
+
|
| 151 |
+
π Testing temporary directory handling...
|
| 152 |
+
β
Created temp directory: /tmp/tmp_xxxxx
|
| 153 |
+
β
File copying works
|
| 154 |
+
β
Cleanup successful
|
| 155 |
+
|
| 156 |
+
π Test Results: 7/7 tests passed
|
| 157 |
+
β
All deployment tests passed! The latest deployment should work correctly.
|
| 158 |
+
```
|
| 159 |
+
|
| 160 |
+
## Files Updated
|
| 161 |
+
|
| 162 |
+
### **Core Deployment Files**
|
| 163 |
+
1. **`scripts/trackio_tonic/deploy_trackio_space.py`**
|
| 164 |
+
- Added HF Hub API integration
|
| 165 |
+
- Implemented fallback mechanism
|
| 166 |
+
- Enhanced error handling
|
| 167 |
+
- Better logging and debugging
|
| 168 |
+
|
| 169 |
+
### **Dependencies**
|
| 170 |
+
2. **`requirements/requirements_core.txt`**
|
| 171 |
+
- Updated huggingface_hub to >=0.19.0
|
| 172 |
+
- Organized dependencies by category
|
| 173 |
+
- Added missing dependencies
|
| 174 |
+
|
| 175 |
+
### **Testing**
|
| 176 |
+
3. **`tests/test_latest_deployment.py`**
|
| 177 |
+
- Comprehensive API testing
|
| 178 |
+
- Import validation
|
| 179 |
+
- Method verification
|
| 180 |
+
- Template file checking
|
| 181 |
+
|
| 182 |
+
## Benefits of Latest Approach
|
| 183 |
+
|
| 184 |
+
### **1. Better Error Handling**
|
| 185 |
+
- API-first approach with CLI fallback
|
| 186 |
+
- Detailed error messages
|
| 187 |
+
- Graceful degradation
|
| 188 |
+
|
| 189 |
+
### **2. More Reliable**
|
| 190 |
+
- Uses official HF Hub API
|
| 191 |
+
- Better parameter validation
|
| 192 |
+
- Consistent behavior
|
| 193 |
+
|
| 194 |
+
### **3. Future-Proof**
|
| 195 |
+
- Follows latest HF Hub patterns
|
| 196 |
+
- Easy to update with new API features
|
| 197 |
+
- Maintains backward compatibility
|
| 198 |
+
|
| 199 |
+
### **4. Enhanced Logging**
|
| 200 |
+
- Detailed progress reporting
|
| 201 |
+
- Better debugging information
|
| 202 |
+
- Clear success/failure indicators
|
| 203 |
+
|
| 204 |
+
## Usage Instructions
|
| 205 |
+
|
| 206 |
+
### **1. Install Latest Dependencies**
|
| 207 |
+
```bash
|
| 208 |
+
pip install huggingface_hub>=0.19.0
|
| 209 |
+
```
|
| 210 |
+
|
| 211 |
+
### **2. Test the Deployment**
|
| 212 |
+
```bash
|
| 213 |
+
python tests/test_latest_deployment.py
|
| 214 |
+
```
|
| 215 |
+
|
| 216 |
+
### **3. Deploy Trackio Space**
|
| 217 |
+
```bash
|
| 218 |
+
python scripts/trackio_tonic/deploy_trackio_space.py
|
| 219 |
+
```
|
| 220 |
+
|
| 221 |
+
### **4. Verify Deployment**
|
| 222 |
+
- Check the Space URL
|
| 223 |
+
- Test the interface
|
| 224 |
+
- Verify API endpoints
|
| 225 |
+
|
| 226 |
+
## Troubleshooting
|
| 227 |
+
|
| 228 |
+
### **Common Issues**
|
| 229 |
+
|
| 230 |
+
#### **1. Import Errors**
|
| 231 |
+
```
|
| 232 |
+
β Failed to import huggingface_hub
|
| 233 |
+
```
|
| 234 |
+
**Solution**: Install latest version
|
| 235 |
+
```bash
|
| 236 |
+
pip install huggingface_hub>=0.19.0
|
| 237 |
+
```
|
| 238 |
+
|
| 239 |
+
#### **2. API Errors**
|
| 240 |
+
```
|
| 241 |
+
API creation failed: 401 Client Error
|
| 242 |
+
```
|
| 243 |
+
**Solution**: Check token permissions and validity
|
| 244 |
+
|
| 245 |
+
#### **3. Git Push Errors**
|
| 246 |
+
```
|
| 247 |
+
β Error uploading files: git push failed
|
| 248 |
+
```
|
| 249 |
+
**Solution**: Verify git configuration and token access
|
| 250 |
+
|
| 251 |
+
### **Fallback Behavior**
|
| 252 |
+
|
| 253 |
+
The deployment script automatically falls back to CLI if:
|
| 254 |
+
- `huggingface_hub` is not available
|
| 255 |
+
- API creation fails
|
| 256 |
+
- Network issues occur
|
| 257 |
+
|
| 258 |
+
## Reference Implementation
|
| 259 |
+
|
| 260 |
+
Based on the [Hugging Face Hub repository](https://github.com/huggingface/huggingface_hub/blob/9e0493cfdb4de5a27b45c53c3342c83ab1a138fb/src/huggingface_hub/commands/repo.py#L30), this implementation:
|
| 261 |
+
|
| 262 |
+
1. **Uses the latest API patterns**
|
| 263 |
+
2. **Follows HF Hub best practices**
|
| 264 |
+
3. **Maintains backward compatibility**
|
| 265 |
+
4. **Provides robust error handling**
|
| 266 |
+
|
| 267 |
+
The Trackio Space deployment should now work reliably with the latest Hugging Face Hub infrastructure! π
|
docs/TRACKIO_SPACE_DEPLOYMENT_FIXES.md
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Trackio Space Deployment Fixes
|
| 2 |
+
|
| 3 |
+
## Issues Identified
|
| 4 |
+
|
| 5 |
+
Based on the reference Hugging Face Space structure at [yourbench/advanced](https://huggingface.co/spaces/yourbench/advanced/tree/main), the original Trackio Space deployment had several issues:
|
| 6 |
+
|
| 7 |
+
1. **Incorrect File Structure**: Not following the proper Hugging Face Spaces format
|
| 8 |
+
2. **Poor Git Integration**: Trying to use git commands incorrectly
|
| 9 |
+
3. **Missing Required Files**: Incomplete template structure
|
| 10 |
+
4. **Incorrect README Format**: Not following HF Spaces metadata format
|
| 11 |
+
5. **Dependency Issues**: Requirements file not properly structured
|
| 12 |
+
|
| 13 |
+
## Fixes Applied
|
| 14 |
+
|
| 15 |
+
### 1. Proper Hugging Face Spaces Structure
|
| 16 |
+
|
| 17 |
+
**Before**: Files were copied to current directory and pushed via git
|
| 18 |
+
**After**: Files are prepared in temporary directory with proper structure
|
| 19 |
+
|
| 20 |
+
```python
|
| 21 |
+
# New approach - proper temp directory handling
|
| 22 |
+
temp_dir = tempfile.mkdtemp()
|
| 23 |
+
# Copy files to temp directory
|
| 24 |
+
shutil.copy2(source_path, dest_path)
|
| 25 |
+
# Initialize git in temp directory
|
| 26 |
+
os.chdir(temp_dir)
|
| 27 |
+
subprocess.run(["git", "init"], check=True)
|
| 28 |
+
subprocess.run(["git", "remote", "add", "origin", space_url], check=True)
|
| 29 |
+
```
|
| 30 |
+
|
| 31 |
+
### 2. Correct README.md Format
|
| 32 |
+
|
| 33 |
+
**Before**: Basic README without proper HF Spaces metadata
|
| 34 |
+
**After**: Proper HF Spaces metadata format
|
| 35 |
+
|
| 36 |
+
```markdown
|
| 37 |
+
---
|
| 38 |
+
title: Trackio Experiment Tracking
|
| 39 |
+
emoji: π
|
| 40 |
+
colorFrom: indigo
|
| 41 |
+
colorTo: yellow
|
| 42 |
+
sdk: gradio
|
| 43 |
+
sdk_version: 4.44.0
|
| 44 |
+
app_file: app.py
|
| 45 |
+
pinned: true
|
| 46 |
+
license: mit
|
| 47 |
+
short_description: Trackio experiment tracking and monitoring interface
|
| 48 |
+
---
|
| 49 |
+
```
|
| 50 |
+
|
| 51 |
+
### 3. Updated Requirements.txt
|
| 52 |
+
|
| 53 |
+
**Before**: Duplicate dependencies and incorrect versions
|
| 54 |
+
**After**: Clean, organized dependencies
|
| 55 |
+
|
| 56 |
+
```txt
|
| 57 |
+
# Core Gradio dependencies
|
| 58 |
+
gradio>=4.0.0
|
| 59 |
+
gradio-client>=0.10.0
|
| 60 |
+
|
| 61 |
+
# Data processing and visualization
|
| 62 |
+
pandas>=2.0.0
|
| 63 |
+
numpy>=1.24.0
|
| 64 |
+
plotly>=5.15.0
|
| 65 |
+
|
| 66 |
+
# HTTP requests and API
|
| 67 |
+
requests>=2.31.0
|
| 68 |
+
|
| 69 |
+
# JSON handling
|
| 70 |
+
jsonschema>=4.17.0
|
| 71 |
+
|
| 72 |
+
# Hugging Face integration
|
| 73 |
+
datasets>=2.14.0
|
| 74 |
+
huggingface-hub>=0.16.0
|
| 75 |
+
|
| 76 |
+
# Environment and configuration
|
| 77 |
+
python-dotenv>=1.0.0
|
| 78 |
+
|
| 79 |
+
# Optional: for better performance
|
| 80 |
+
matplotlib>=3.7.0
|
| 81 |
+
```
|
| 82 |
+
|
| 83 |
+
### 4. Improved Deployment Script
|
| 84 |
+
|
| 85 |
+
**Key Improvements**:
|
| 86 |
+
- Proper temporary directory handling
|
| 87 |
+
- Better error handling and logging
|
| 88 |
+
- Correct git workflow
|
| 89 |
+
- Environment variable setup
|
| 90 |
+
- Comprehensive testing
|
| 91 |
+
|
| 92 |
+
```python
|
| 93 |
+
class TrackioSpaceDeployer:
|
| 94 |
+
def __init__(self, space_name: str, username: str, token: str):
|
| 95 |
+
self.space_name = space_name
|
| 96 |
+
self.username = username
|
| 97 |
+
self.token = token
|
| 98 |
+
self.space_url = f"https://huggingface.co/spaces/{username}/{space_name}"
|
| 99 |
+
|
| 100 |
+
def create_space(self) -> bool:
|
| 101 |
+
# Set HF token for CLI
|
| 102 |
+
os.environ['HF_TOKEN'] = self.token
|
| 103 |
+
# Create space with proper error handling
|
| 104 |
+
|
| 105 |
+
def prepare_space_files(self) -> str:
|
| 106 |
+
# Create temp directory and copy files
|
| 107 |
+
# Update README with actual space URL
|
| 108 |
+
|
| 109 |
+
def upload_files_to_space(self, temp_dir: str) -> bool:
|
| 110 |
+
# Proper git workflow in temp directory
|
| 111 |
+
# Push to main/master branch
|
| 112 |
+
```
|
| 113 |
+
|
| 114 |
+
## Files Modified
|
| 115 |
+
|
| 116 |
+
### Core Deployment Files
|
| 117 |
+
1. **`scripts/trackio_tonic/deploy_trackio_space.py`**
|
| 118 |
+
- Complete rewrite following HF Spaces best practices
|
| 119 |
+
- Proper temporary directory handling
|
| 120 |
+
- Better error handling and logging
|
| 121 |
+
- Correct git workflow
|
| 122 |
+
|
| 123 |
+
### Template Files
|
| 124 |
+
2. **`templates/spaces/README.md`**
|
| 125 |
+
- Updated to proper HF Spaces metadata format
|
| 126 |
+
- Comprehensive documentation
|
| 127 |
+
- API endpoint documentation
|
| 128 |
+
- Troubleshooting guide
|
| 129 |
+
|
| 130 |
+
3. **`templates/spaces/requirements.txt`**
|
| 131 |
+
- Clean, organized dependencies
|
| 132 |
+
- Proper version specifications
|
| 133 |
+
- All required packages included
|
| 134 |
+
|
| 135 |
+
### Test Files
|
| 136 |
+
4. **`tests/test_trackio_deployment.py`**
|
| 137 |
+
- Comprehensive deployment testing
|
| 138 |
+
- Template structure validation
|
| 139 |
+
- File content verification
|
| 140 |
+
- Deployment script testing
|
| 141 |
+
|
| 142 |
+
## Testing the Deployment
|
| 143 |
+
|
| 144 |
+
### Run Deployment Tests
|
| 145 |
+
```bash
|
| 146 |
+
python tests/test_trackio_deployment.py
|
| 147 |
+
```
|
| 148 |
+
|
| 149 |
+
Expected output:
|
| 150 |
+
```
|
| 151 |
+
π Testing Trackio Space Deployment
|
| 152 |
+
==================================================
|
| 153 |
+
π Testing templates structure...
|
| 154 |
+
β
app.py exists
|
| 155 |
+
β
requirements.txt exists
|
| 156 |
+
β
README.md exists
|
| 157 |
+
|
| 158 |
+
π Testing app.py content...
|
| 159 |
+
β
Found: import gradio as gr
|
| 160 |
+
β
Found: class TrackioSpace
|
| 161 |
+
β
Found: def create_experiment_interface
|
| 162 |
+
β
Found: def log_metrics_interface
|
| 163 |
+
β
Found: def log_parameters_interface
|
| 164 |
+
β
Found: demo.launch()
|
| 165 |
+
|
| 166 |
+
π Testing requirements.txt content...
|
| 167 |
+
β
Found: gradio>=
|
| 168 |
+
β
Found: pandas>=
|
| 169 |
+
β
Found: numpy>=
|
| 170 |
+
β
Found: plotly>=
|
| 171 |
+
β
Found: requests>=
|
| 172 |
+
β
Found: datasets>=
|
| 173 |
+
β
Found: huggingface-hub>=
|
| 174 |
+
|
| 175 |
+
π Testing README.md structure...
|
| 176 |
+
β
Found: ---
|
| 177 |
+
β
Found: title: Trackio Experiment Tracking
|
| 178 |
+
β
Found: sdk: gradio
|
| 179 |
+
β
Found: app_file: app.py
|
| 180 |
+
β
Found: # Trackio Experiment Tracking
|
| 181 |
+
β
Found: ## Features
|
| 182 |
+
β
Found: ## Usage
|
| 183 |
+
β
Found: Visit: {SPACE_URL}
|
| 184 |
+
|
| 185 |
+
π Testing deployment script...
|
| 186 |
+
β
TrackioSpaceDeployer class imported successfully
|
| 187 |
+
β
Method exists: create_space
|
| 188 |
+
β
Method exists: prepare_space_files
|
| 189 |
+
β
Method exists: upload_files_to_space
|
| 190 |
+
β
Method exists: test_space
|
| 191 |
+
β
Method exists: deploy
|
| 192 |
+
|
| 193 |
+
π Testing temporary directory creation...
|
| 194 |
+
β
Created temp directory: /tmp/tmp_xxxxx
|
| 195 |
+
β
File copying works
|
| 196 |
+
β
Cleanup successful
|
| 197 |
+
|
| 198 |
+
π Test Results: 6/6 tests passed
|
| 199 |
+
β
All deployment tests passed! The Trackio Space should deploy correctly.
|
| 200 |
+
```
|
| 201 |
+
|
| 202 |
+
### Deploy Trackio Space
|
| 203 |
+
```bash
|
| 204 |
+
python scripts/trackio_tonic/deploy_trackio_space.py
|
| 205 |
+
```
|
| 206 |
+
|
| 207 |
+
## Key Improvements
|
| 208 |
+
|
| 209 |
+
### 1. **Proper HF Spaces Structure**
|
| 210 |
+
- Follows the exact format from reference spaces
|
| 211 |
+
- Correct metadata in README.md
|
| 212 |
+
- Proper file organization
|
| 213 |
+
|
| 214 |
+
### 2. **Robust Deployment Process**
|
| 215 |
+
- Temporary directory handling
|
| 216 |
+
- Proper git workflow
|
| 217 |
+
- Better error handling
|
| 218 |
+
- Comprehensive logging
|
| 219 |
+
|
| 220 |
+
### 3. **Better Error Handling**
|
| 221 |
+
- Graceful failure handling
|
| 222 |
+
- Detailed error messages
|
| 223 |
+
- Fallback mechanisms
|
| 224 |
+
- Cleanup procedures
|
| 225 |
+
|
| 226 |
+
### 4. **Comprehensive Testing**
|
| 227 |
+
- Template structure validation
|
| 228 |
+
- File content verification
|
| 229 |
+
- Deployment script testing
|
| 230 |
+
- Integration testing
|
| 231 |
+
|
| 232 |
+
## Reference Structure
|
| 233 |
+
|
| 234 |
+
The fixes are based on the Hugging Face Space structure from [yourbench/advanced](https://huggingface.co/spaces/yourbench/advanced/tree/main), which includes:
|
| 235 |
+
|
| 236 |
+
- **Proper README.md** with HF Spaces metadata
|
| 237 |
+
- **Clean requirements.txt** with organized dependencies
|
| 238 |
+
- **Correct app.py** structure for Gradio
|
| 239 |
+
- **Proper git workflow** for deployment
|
| 240 |
+
|
| 241 |
+
## Next Steps
|
| 242 |
+
|
| 243 |
+
1. **Test the deployment**:
|
| 244 |
+
```bash
|
| 245 |
+
python tests/test_trackio_deployment.py
|
| 246 |
+
```
|
| 247 |
+
|
| 248 |
+
2. **Deploy the Space**:
|
| 249 |
+
```bash
|
| 250 |
+
python scripts/trackio_tonic/deploy_trackio_space.py
|
| 251 |
+
```
|
| 252 |
+
|
| 253 |
+
3. **Verify deployment**:
|
| 254 |
+
- Check the Space URL
|
| 255 |
+
- Test the interface
|
| 256 |
+
- Verify API endpoints
|
| 257 |
+
|
| 258 |
+
4. **Use in training**:
|
| 259 |
+
- Update your training scripts with the new Space URL
|
| 260 |
+
- Test the monitoring integration
|
| 261 |
+
|
| 262 |
+
The Trackio Space should now deploy correctly and provide reliable experiment tracking for your SmolLM3 fine-tuning pipeline! π
|
TRAINING_FIXES_SUMMARY.md β docs/TRAINING_FIXES_SUMMARY.md
RENAMED
|
File without changes
|
requirements/requirements_core.txt
CHANGED
|
@@ -1,18 +1,17 @@
|
|
| 1 |
-
# Core
|
| 2 |
torch>=2.0.0
|
| 3 |
transformers>=4.53.0
|
| 4 |
datasets>=2.14.0
|
| 5 |
accelerate>=0.20.0
|
|
|
|
| 6 |
trl>=0.7.0
|
| 7 |
-
huggingface-hub>=0.16.0
|
| 8 |
-
tokenizers>=0.13.0
|
| 9 |
-
bitsandbytes>=0.41.0
|
| 10 |
-
numpy>=1.24.0
|
| 11 |
-
tqdm>=4.65.0
|
| 12 |
|
|
|
|
|
|
|
| 13 |
|
| 14 |
-
# Monitoring
|
| 15 |
requests>=2.31.0
|
|
|
|
| 16 |
pandas>=2.0.0
|
| 17 |
plotly>=5.0.0
|
| 18 |
trackio>=0.1.0
|
|
|
|
| 1 |
+
# Core dependencies for SmolLM3 fine-tuning
|
| 2 |
torch>=2.0.0
|
| 3 |
transformers>=4.53.0
|
| 4 |
datasets>=2.14.0
|
| 5 |
accelerate>=0.20.0
|
| 6 |
+
peft>=0.4.0
|
| 7 |
trl>=0.7.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
+
# Hugging Face Hub for model and space management
|
| 10 |
+
huggingface_hub>=0.19.0
|
| 11 |
|
| 12 |
+
# Monitoring and tracking
|
| 13 |
requests>=2.31.0
|
| 14 |
+
numpy>=1.24.0
|
| 15 |
pandas>=2.0.0
|
| 16 |
plotly>=5.0.0
|
| 17 |
trackio>=0.1.0
|
scripts/trackio_tonic/deploy_trackio_space.py
CHANGED
|
@@ -9,9 +9,19 @@ import json
|
|
| 9 |
import requests
|
| 10 |
import subprocess
|
| 11 |
import sys
|
|
|
|
|
|
|
| 12 |
from pathlib import Path
|
| 13 |
from typing import Dict, Any, Optional
|
| 14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
class TrackioSpaceDeployer:
|
| 16 |
"""Deployer for Trackio on Hugging Face Spaces"""
|
| 17 |
|
|
@@ -21,11 +31,56 @@ class TrackioSpaceDeployer:
|
|
| 21 |
self.token = token
|
| 22 |
self.space_url = f"https://huggingface.co/spaces/{username}/{space_name}"
|
| 23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
def create_space(self) -> bool:
|
| 25 |
-
"""Create a new Hugging Face Space"""
|
| 26 |
try:
|
| 27 |
print(f"Creating Space: {self.space_name}")
|
| 28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
# Create space using Hugging Face CLI
|
| 30 |
cmd = [
|
| 31 |
"huggingface-cli", "repo", "create",
|
|
@@ -33,10 +88,11 @@ class TrackioSpaceDeployer:
|
|
| 33 |
"--type", "space"
|
| 34 |
]
|
| 35 |
|
| 36 |
-
|
| 37 |
result = subprocess.run(cmd, capture_output=True, text=True)
|
| 38 |
|
| 39 |
if result.returncode != 0:
|
|
|
|
| 40 |
# Try alternative approach without space-specific flags
|
| 41 |
print("Retrying with basic space creation...")
|
| 42 |
cmd = [
|
|
@@ -53,123 +109,98 @@ class TrackioSpaceDeployer:
|
|
| 53 |
return False
|
| 54 |
|
| 55 |
except Exception as e:
|
| 56 |
-
print(f"β Error creating space: {e}")
|
| 57 |
return False
|
| 58 |
|
| 59 |
-
def
|
| 60 |
-
"""
|
| 61 |
try:
|
| 62 |
-
print("
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
# Get the project root directory (3 levels up from this script)
|
| 65 |
project_root = Path(__file__).parent.parent.parent
|
| 66 |
templates_dir = project_root / "templates" / "spaces"
|
| 67 |
|
| 68 |
-
# Files to
|
| 69 |
-
|
| 70 |
"app.py",
|
| 71 |
-
"requirements.txt"
|
|
|
|
| 72 |
]
|
| 73 |
|
| 74 |
-
#
|
| 75 |
-
|
| 76 |
-
# Copy files from templates/spaces to current directory
|
| 77 |
copied_files = []
|
| 78 |
-
for file_name in
|
| 79 |
source_path = templates_dir / file_name
|
|
|
|
|
|
|
| 80 |
if source_path.exists():
|
| 81 |
-
|
| 82 |
-
shutil.copy2(source_path, file_name)
|
| 83 |
copied_files.append(file_name)
|
| 84 |
-
print(f"β
Copied {file_name}
|
| 85 |
else:
|
| 86 |
print(f"β οΈ File not found: {source_path}")
|
| 87 |
|
| 88 |
-
#
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
subprocess.run(["git", "init"], check=True)
|
| 94 |
-
subprocess.run(["git", "remote", "add", "origin", f"https://huggingface.co/spaces/{self.username}/{self.space_name}"], check=True)
|
| 95 |
-
|
| 96 |
-
# Add all files at once
|
| 97 |
-
existing_files = [f for f in files_to_upload if os.path.exists(f)]
|
| 98 |
-
if existing_files:
|
| 99 |
-
subprocess.run(["git", "add"] + existing_files, check=True)
|
| 100 |
-
subprocess.run(["git", "add", "README.md"], check=True) # Add README.md that was created in configure_space
|
| 101 |
-
subprocess.run(["git", "commit", "-m", "Initial Space setup"], check=True)
|
| 102 |
|
| 103 |
-
#
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
print(f"β
Uploaded {len(existing_files)} files")
|
| 111 |
-
else:
|
| 112 |
-
print("β οΈ No files found to upload")
|
| 113 |
|
| 114 |
-
|
|
|
|
| 115 |
|
| 116 |
except Exception as e:
|
| 117 |
-
print(f"β Error
|
| 118 |
-
return
|
| 119 |
|
| 120 |
-
def
|
| 121 |
-
"""
|
| 122 |
try:
|
| 123 |
-
print("
|
| 124 |
|
| 125 |
-
#
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
readme_template_path = templates_dir / "README.md"
|
| 129 |
|
| 130 |
-
#
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
colorFrom: indigo
|
| 150 |
-
colorTo: yellow
|
| 151 |
-
sdk: gradio
|
| 152 |
-
sdk_version: 5.38.0
|
| 153 |
-
app_file: app.py
|
| 154 |
-
pinned: true
|
| 155 |
-
license: mit
|
| 156 |
-
short_description: trackio for training monitoring
|
| 157 |
-
---
|
| 158 |
-
|
| 159 |
-
# Trackio Experiment Tracking
|
| 160 |
-
|
| 161 |
-
A Gradio interface for experiment tracking and monitoring.
|
| 162 |
-
|
| 163 |
-
Visit: {self.space_url}
|
| 164 |
-
"""
|
| 165 |
-
with open("README.md", "w", encoding='utf-8') as f:
|
| 166 |
-
f.write(basic_readme)
|
| 167 |
-
print(f"β
Created basic README.md")
|
| 168 |
|
| 169 |
return True
|
| 170 |
|
| 171 |
except Exception as e:
|
| 172 |
-
print(f"β Error
|
|
|
|
|
|
|
| 173 |
return False
|
| 174 |
|
| 175 |
def test_space(self) -> bool:
|
|
@@ -179,16 +210,18 @@ Visit: {self.space_url}
|
|
| 179 |
|
| 180 |
# Wait a bit for the space to build
|
| 181 |
import time
|
| 182 |
-
|
|
|
|
| 183 |
|
| 184 |
# Try to access the space
|
| 185 |
-
response = requests.get(self.space_url, timeout=
|
| 186 |
|
| 187 |
if response.status_code == 200:
|
| 188 |
print(f"β
Space is accessible: {self.space_url}")
|
| 189 |
return True
|
| 190 |
else:
|
| 191 |
print(f"β οΈ Space returned status code: {response.status_code}")
|
|
|
|
| 192 |
return False
|
| 193 |
|
| 194 |
except Exception as e:
|
|
@@ -203,17 +236,26 @@ Visit: {self.space_url}
|
|
| 203 |
if not self.create_space():
|
| 204 |
return False
|
| 205 |
|
| 206 |
-
# Step 2:
|
| 207 |
-
|
|
|
|
| 208 |
return False
|
| 209 |
|
| 210 |
# Step 3: Upload files
|
| 211 |
-
if not self.
|
| 212 |
return False
|
| 213 |
|
| 214 |
-
# Step 4:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
if not self.test_space():
|
| 216 |
-
print("β οΈ Space created but may need time to build")
|
|
|
|
| 217 |
|
| 218 |
print(f"π Deployment completed!")
|
| 219 |
print(f"π Trackio Space URL: {self.space_url}")
|
|
@@ -229,10 +271,10 @@ def main():
|
|
| 229 |
# Get user input
|
| 230 |
username = input("Enter your Hugging Face username: ").strip()
|
| 231 |
space_name = input("Enter Space name (e.g., trackio-monitoring): ").strip()
|
| 232 |
-
token = input("Enter your Hugging Face token
|
| 233 |
|
| 234 |
-
if not username or not space_name:
|
| 235 |
-
print("β Username
|
| 236 |
sys.exit(1)
|
| 237 |
|
| 238 |
# Create deployer
|
|
@@ -248,9 +290,17 @@ def main():
|
|
| 248 |
print("1. Wait for the Space to build (usually 2-5 minutes)")
|
| 249 |
print("2. Test the interface by visiting the Space URL")
|
| 250 |
print("3. Use the Space URL in your training scripts")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 251 |
else:
|
| 252 |
print("\nβ Deployment failed!")
|
| 253 |
print("Check the error messages above and try again.")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
|
| 255 |
if __name__ == "__main__":
|
| 256 |
main()
|
|
|
|
| 9 |
import requests
|
| 10 |
import subprocess
|
| 11 |
import sys
|
| 12 |
+
import tempfile
|
| 13 |
+
import shutil
|
| 14 |
from pathlib import Path
|
| 15 |
from typing import Dict, Any, Optional
|
| 16 |
|
| 17 |
+
# Import Hugging Face Hub API
|
| 18 |
+
try:
|
| 19 |
+
from huggingface_hub import HfApi, create_repo
|
| 20 |
+
HF_HUB_AVAILABLE = True
|
| 21 |
+
except ImportError:
|
| 22 |
+
HF_HUB_AVAILABLE = False
|
| 23 |
+
print("Warning: huggingface_hub not available. Install with: pip install huggingface_hub")
|
| 24 |
+
|
| 25 |
class TrackioSpaceDeployer:
|
| 26 |
"""Deployer for Trackio on Hugging Face Spaces"""
|
| 27 |
|
|
|
|
| 31 |
self.token = token
|
| 32 |
self.space_url = f"https://huggingface.co/spaces/{username}/{space_name}"
|
| 33 |
|
| 34 |
+
# Initialize HF API
|
| 35 |
+
if HF_HUB_AVAILABLE:
|
| 36 |
+
self.api = HfApi(token=self.token)
|
| 37 |
+
else:
|
| 38 |
+
self.api = None
|
| 39 |
+
|
| 40 |
def create_space(self) -> bool:
|
| 41 |
+
"""Create a new Hugging Face Space using the latest API"""
|
| 42 |
try:
|
| 43 |
print(f"Creating Space: {self.space_name}")
|
| 44 |
|
| 45 |
+
if not HF_HUB_AVAILABLE:
|
| 46 |
+
print("β huggingface_hub not available, falling back to CLI")
|
| 47 |
+
return self._create_space_cli()
|
| 48 |
+
|
| 49 |
+
# Use the latest HF Hub API to create space
|
| 50 |
+
repo_id = f"{self.username}/{self.space_name}"
|
| 51 |
+
|
| 52 |
+
try:
|
| 53 |
+
# Create the space using the API
|
| 54 |
+
create_repo(
|
| 55 |
+
repo_id=repo_id,
|
| 56 |
+
token=self.token,
|
| 57 |
+
repo_type="space",
|
| 58 |
+
exist_ok=True,
|
| 59 |
+
private=False, # Spaces are typically public
|
| 60 |
+
space_sdk="gradio", # Specify Gradio SDK
|
| 61 |
+
space_hardware="cpu-basic" # Use basic CPU
|
| 62 |
+
)
|
| 63 |
+
|
| 64 |
+
print(f"β
Space created successfully: {self.space_url}")
|
| 65 |
+
return True
|
| 66 |
+
|
| 67 |
+
except Exception as api_error:
|
| 68 |
+
print(f"API creation failed: {api_error}")
|
| 69 |
+
print("Falling back to CLI method...")
|
| 70 |
+
return self._create_space_cli()
|
| 71 |
+
|
| 72 |
+
except Exception as e:
|
| 73 |
+
print(f"β Error creating space: {e}")
|
| 74 |
+
return False
|
| 75 |
+
|
| 76 |
+
def _create_space_cli(self) -> bool:
|
| 77 |
+
"""Fallback method using CLI commands"""
|
| 78 |
+
try:
|
| 79 |
+
print("Using CLI fallback method...")
|
| 80 |
+
|
| 81 |
+
# Set HF token for CLI
|
| 82 |
+
os.environ['HF_TOKEN'] = self.token
|
| 83 |
+
|
| 84 |
# Create space using Hugging Face CLI
|
| 85 |
cmd = [
|
| 86 |
"huggingface-cli", "repo", "create",
|
|
|
|
| 88 |
"--type", "space"
|
| 89 |
]
|
| 90 |
|
| 91 |
+
print(f"Running command: {' '.join(cmd)}")
|
| 92 |
result = subprocess.run(cmd, capture_output=True, text=True)
|
| 93 |
|
| 94 |
if result.returncode != 0:
|
| 95 |
+
print(f"First attempt failed: {result.stderr}")
|
| 96 |
# Try alternative approach without space-specific flags
|
| 97 |
print("Retrying with basic space creation...")
|
| 98 |
cmd = [
|
|
|
|
| 109 |
return False
|
| 110 |
|
| 111 |
except Exception as e:
|
| 112 |
+
print(f"β Error creating space with CLI: {e}")
|
| 113 |
return False
|
| 114 |
|
| 115 |
+
def prepare_space_files(self) -> str:
|
| 116 |
+
"""Prepare all necessary files for the Space in a temporary directory"""
|
| 117 |
try:
|
| 118 |
+
print("Preparing Space files...")
|
| 119 |
+
|
| 120 |
+
# Create temporary directory
|
| 121 |
+
temp_dir = tempfile.mkdtemp()
|
| 122 |
+
print(f"Created temporary directory: {temp_dir}")
|
| 123 |
|
| 124 |
# Get the project root directory (3 levels up from this script)
|
| 125 |
project_root = Path(__file__).parent.parent.parent
|
| 126 |
templates_dir = project_root / "templates" / "spaces"
|
| 127 |
|
| 128 |
+
# Files to copy from templates/spaces
|
| 129 |
+
files_to_copy = [
|
| 130 |
"app.py",
|
| 131 |
+
"requirements.txt",
|
| 132 |
+
"README.md"
|
| 133 |
]
|
| 134 |
|
| 135 |
+
# Copy files from templates/spaces to temp directory
|
|
|
|
|
|
|
| 136 |
copied_files = []
|
| 137 |
+
for file_name in files_to_copy:
|
| 138 |
source_path = templates_dir / file_name
|
| 139 |
+
dest_path = Path(temp_dir) / file_name
|
| 140 |
+
|
| 141 |
if source_path.exists():
|
| 142 |
+
shutil.copy2(source_path, dest_path)
|
|
|
|
| 143 |
copied_files.append(file_name)
|
| 144 |
+
print(f"β
Copied {file_name} to temp directory")
|
| 145 |
else:
|
| 146 |
print(f"β οΈ File not found: {source_path}")
|
| 147 |
|
| 148 |
+
# Update README.md with actual space URL
|
| 149 |
+
readme_path = Path(temp_dir) / "README.md"
|
| 150 |
+
if readme_path.exists():
|
| 151 |
+
with open(readme_path, 'r', encoding='utf-8') as f:
|
| 152 |
+
readme_content = f.read()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
|
| 154 |
+
# Replace placeholder with actual space URL
|
| 155 |
+
readme_content = readme_content.replace("{SPACE_URL}", self.space_url)
|
| 156 |
+
|
| 157 |
+
with open(readme_path, 'w', encoding='utf-8') as f:
|
| 158 |
+
f.write(readme_content)
|
| 159 |
+
|
| 160 |
+
print(f"β
Updated README.md with space URL")
|
|
|
|
|
|
|
|
|
|
| 161 |
|
| 162 |
+
print(f"β
Prepared {len(copied_files)} files in temporary directory")
|
| 163 |
+
return temp_dir
|
| 164 |
|
| 165 |
except Exception as e:
|
| 166 |
+
print(f"β Error preparing files: {e}")
|
| 167 |
+
return None
|
| 168 |
|
| 169 |
+
def upload_files_to_space(self, temp_dir: str) -> bool:
|
| 170 |
+
"""Upload files to the Space using git"""
|
| 171 |
try:
|
| 172 |
+
print("Uploading files to Space...")
|
| 173 |
|
| 174 |
+
# Change to temp directory
|
| 175 |
+
original_dir = os.getcwd()
|
| 176 |
+
os.chdir(temp_dir)
|
|
|
|
| 177 |
|
| 178 |
+
# Initialize git repository
|
| 179 |
+
subprocess.run(["git", "init"], check=True, capture_output=True)
|
| 180 |
+
subprocess.run(["git", "remote", "add", "origin", f"https://huggingface.co/spaces/{self.username}/{self.space_name}"], check=True, capture_output=True)
|
| 181 |
+
|
| 182 |
+
# Add all files
|
| 183 |
+
subprocess.run(["git", "add", "."], check=True, capture_output=True)
|
| 184 |
+
subprocess.run(["git", "commit", "-m", "Initial Trackio Space setup"], check=True, capture_output=True)
|
| 185 |
+
|
| 186 |
+
# Push to the space
|
| 187 |
+
try:
|
| 188 |
+
subprocess.run(["git", "push", "origin", "main"], check=True, capture_output=True)
|
| 189 |
+
print("β
Pushed to main branch")
|
| 190 |
+
except subprocess.CalledProcessError:
|
| 191 |
+
# Try pushing to master branch if main doesn't exist
|
| 192 |
+
subprocess.run(["git", "push", "origin", "master"], check=True, capture_output=True)
|
| 193 |
+
print("β
Pushed to master branch")
|
| 194 |
+
|
| 195 |
+
# Return to original directory
|
| 196 |
+
os.chdir(original_dir)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
|
| 198 |
return True
|
| 199 |
|
| 200 |
except Exception as e:
|
| 201 |
+
print(f"β Error uploading files: {e}")
|
| 202 |
+
# Return to original directory
|
| 203 |
+
os.chdir(original_dir)
|
| 204 |
return False
|
| 205 |
|
| 206 |
def test_space(self) -> bool:
|
|
|
|
| 210 |
|
| 211 |
# Wait a bit for the space to build
|
| 212 |
import time
|
| 213 |
+
print("Waiting 180 seconds for Space to build...")
|
| 214 |
+
time.sleep(180)
|
| 215 |
|
| 216 |
# Try to access the space
|
| 217 |
+
response = requests.get(self.space_url, timeout=30)
|
| 218 |
|
| 219 |
if response.status_code == 200:
|
| 220 |
print(f"β
Space is accessible: {self.space_url}")
|
| 221 |
return True
|
| 222 |
else:
|
| 223 |
print(f"β οΈ Space returned status code: {response.status_code}")
|
| 224 |
+
print(f"Response: {response.text[:500]}...")
|
| 225 |
return False
|
| 226 |
|
| 227 |
except Exception as e:
|
|
|
|
| 236 |
if not self.create_space():
|
| 237 |
return False
|
| 238 |
|
| 239 |
+
# Step 2: Prepare files
|
| 240 |
+
temp_dir = self.prepare_space_files()
|
| 241 |
+
if not temp_dir:
|
| 242 |
return False
|
| 243 |
|
| 244 |
# Step 3: Upload files
|
| 245 |
+
if not self.upload_files_to_space(temp_dir):
|
| 246 |
return False
|
| 247 |
|
| 248 |
+
# Step 4: Clean up temp directory
|
| 249 |
+
try:
|
| 250 |
+
shutil.rmtree(temp_dir)
|
| 251 |
+
print("β
Cleaned up temporary directory")
|
| 252 |
+
except Exception as e:
|
| 253 |
+
print(f"β οΈ Warning: Could not clean up temp directory: {e}")
|
| 254 |
+
|
| 255 |
+
# Step 5: Test space
|
| 256 |
if not self.test_space():
|
| 257 |
+
print("β οΈ Space created but may need more time to build")
|
| 258 |
+
print("Please check the Space manually in a few minutes")
|
| 259 |
|
| 260 |
print(f"π Deployment completed!")
|
| 261 |
print(f"π Trackio Space URL: {self.space_url}")
|
|
|
|
| 271 |
# Get user input
|
| 272 |
username = input("Enter your Hugging Face username: ").strip()
|
| 273 |
space_name = input("Enter Space name (e.g., trackio-monitoring): ").strip()
|
| 274 |
+
token = input("Enter your Hugging Face token: ").strip()
|
| 275 |
|
| 276 |
+
if not username or not space_name or not token:
|
| 277 |
+
print("β Username, Space name, and token are required")
|
| 278 |
sys.exit(1)
|
| 279 |
|
| 280 |
# Create deployer
|
|
|
|
| 290 |
print("1. Wait for the Space to build (usually 2-5 minutes)")
|
| 291 |
print("2. Test the interface by visiting the Space URL")
|
| 292 |
print("3. Use the Space URL in your training scripts")
|
| 293 |
+
print("\nIf the Space doesn't work immediately, check:")
|
| 294 |
+
print("- The Space logs at the Space URL")
|
| 295 |
+
print("- That all files were uploaded correctly")
|
| 296 |
+
print("- That the HF token has write permissions")
|
| 297 |
else:
|
| 298 |
print("\nβ Deployment failed!")
|
| 299 |
print("Check the error messages above and try again.")
|
| 300 |
+
print("\nTroubleshooting:")
|
| 301 |
+
print("1. Verify your HF token has write permissions")
|
| 302 |
+
print("2. Check that the space name is available")
|
| 303 |
+
print("3. Try creating the space manually on HF first")
|
| 304 |
|
| 305 |
if __name__ == "__main__":
|
| 306 |
main()
|
templates/spaces/README.md
CHANGED
|
@@ -13,25 +13,29 @@ short_description: trackio for training monitoring
|
|
| 13 |
|
| 14 |
# Trackio Experiment Tracking
|
| 15 |
|
| 16 |
-
A Gradio interface for experiment tracking and monitoring.
|
| 17 |
|
| 18 |
## Features
|
| 19 |
|
| 20 |
-
- Create
|
| 21 |
-
- Log training metrics and parameters
|
| 22 |
-
-
|
| 23 |
-
- Update experiment status
|
|
|
|
|
|
|
| 24 |
|
| 25 |
## Usage
|
| 26 |
|
| 27 |
-
|
| 28 |
-
2. Log metrics during training using the "Log Metrics" tab
|
| 29 |
-
3. View experiment details using the "View Experiments" tab
|
| 30 |
-
4. Update experiment status using the "Update Status" tab
|
| 31 |
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
| 33 |
|
| 34 |
-
|
|
|
|
|
|
|
| 35 |
|
| 36 |
```python
|
| 37 |
from monitoring import SmolLM3Monitor
|
|
@@ -41,6 +45,85 @@ monitor = SmolLM3Monitor(
|
|
| 41 |
trackio_url="{SPACE_URL}",
|
| 42 |
enable_tracking=True
|
| 43 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
```
|
| 45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
Visit: {SPACE_URL}
|
|
|
|
| 13 |
|
| 14 |
# Trackio Experiment Tracking
|
| 15 |
|
| 16 |
+
A comprehensive Gradio interface for experiment tracking and monitoring, designed for ML training workflows.
|
| 17 |
|
| 18 |
## Features
|
| 19 |
|
| 20 |
+
- **Create Experiments**: Start new experiments with custom names and descriptions
|
| 21 |
+
- **Log Metrics**: Real-time logging of training metrics and parameters
|
| 22 |
+
- **Visualize Results**: Interactive plots and charts for experiment analysis
|
| 23 |
+
- **Manage Status**: Update experiment status (running, completed, failed, paused)
|
| 24 |
+
- **HF Datasets Integration**: Persistent storage using Hugging Face Datasets
|
| 25 |
+
- **API Access**: Programmatic access for automated training scripts
|
| 26 |
|
| 27 |
## Usage
|
| 28 |
|
| 29 |
+
### Web Interface
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
+
1. **Create Experiment**: Use the "Create Experiment" tab to start new experiments
|
| 32 |
+
2. **Log Metrics**: Use the "Log Metrics" tab to track training progress
|
| 33 |
+
3. **View Results**: Use the "View Experiments" tab to see experiment details
|
| 34 |
+
4. **Update Status**: Use the "Update Status" tab to mark experiments as completed
|
| 35 |
|
| 36 |
+
### API Integration
|
| 37 |
+
|
| 38 |
+
Connect your training script to this Trackio Space:
|
| 39 |
|
| 40 |
```python
|
| 41 |
from monitoring import SmolLM3Monitor
|
|
|
|
| 45 |
trackio_url="{SPACE_URL}",
|
| 46 |
enable_tracking=True
|
| 47 |
)
|
| 48 |
+
|
| 49 |
+
# Log configuration
|
| 50 |
+
monitor.log_config(config_dict)
|
| 51 |
+
|
| 52 |
+
# Log metrics during training
|
| 53 |
+
monitor.log_metrics({"loss": 0.5, "accuracy": 0.85}, step=100)
|
| 54 |
+
|
| 55 |
+
# Log final results
|
| 56 |
+
monitor.log_training_summary(final_results)
|
| 57 |
+
```
|
| 58 |
+
|
| 59 |
+
## Configuration
|
| 60 |
+
|
| 61 |
+
### Environment Variables
|
| 62 |
+
|
| 63 |
+
Set these environment variables for full functionality:
|
| 64 |
+
|
| 65 |
+
```bash
|
| 66 |
+
export HF_TOKEN="your_huggingface_token"
|
| 67 |
+
export TRACKIO_DATASET_REPO="your-username/your-dataset"
|
| 68 |
```
|
| 69 |
|
| 70 |
+
### Dataset Repository
|
| 71 |
+
|
| 72 |
+
The Space uses Hugging Face Datasets for persistent storage. Create a dataset repository to store your experiments:
|
| 73 |
+
|
| 74 |
+
1. Go to https://huggingface.co/datasets
|
| 75 |
+
2. Create a new dataset repository
|
| 76 |
+
3. Set the `TRACKIO_DATASET_REPO` environment variable
|
| 77 |
+
|
| 78 |
+
## API Endpoints
|
| 79 |
+
|
| 80 |
+
The Space provides these API endpoints:
|
| 81 |
+
|
| 82 |
+
- `create_experiment_interface`: Create new experiments
|
| 83 |
+
- `log_metrics_interface`: Log training metrics
|
| 84 |
+
- `log_parameters_interface`: Log experiment parameters
|
| 85 |
+
- `get_experiment_details`: Retrieve experiment details
|
| 86 |
+
- `list_experiments_interface`: List all experiments
|
| 87 |
+
- `update_experiment_status_interface`: Update experiment status
|
| 88 |
+
|
| 89 |
+
## Examples
|
| 90 |
+
|
| 91 |
+
### Creating an Experiment
|
| 92 |
+
|
| 93 |
+
```python
|
| 94 |
+
import requests
|
| 95 |
+
|
| 96 |
+
response = requests.post(
|
| 97 |
+
"https://your-space.hf.space/gradio_api/call/create_experiment_interface",
|
| 98 |
+
json={"data": ["my_experiment", "Training experiment description"]}
|
| 99 |
+
)
|
| 100 |
+
```
|
| 101 |
+
|
| 102 |
+
### Logging Metrics
|
| 103 |
+
|
| 104 |
+
```python
|
| 105 |
+
import requests
|
| 106 |
+
import json
|
| 107 |
+
|
| 108 |
+
metrics = {"loss": 0.5, "accuracy": 0.85, "learning_rate": 2e-5}
|
| 109 |
+
response = requests.post(
|
| 110 |
+
"https://your-space.hf.space/gradio_api/call/log_metrics_interface",
|
| 111 |
+
json={"data": ["exp_20231201_143022", json.dumps(metrics), "100"]}
|
| 112 |
+
)
|
| 113 |
+
```
|
| 114 |
+
|
| 115 |
+
## Troubleshooting
|
| 116 |
+
|
| 117 |
+
### Common Issues
|
| 118 |
+
|
| 119 |
+
1. **Space Not Building**: Check that all required files are uploaded and the app.py is correct
|
| 120 |
+
2. **API Connection Errors**: Verify the Space URL and ensure the Space is running
|
| 121 |
+
3. **Missing Metrics**: Check that the experiment ID is correct and the Space is accessible
|
| 122 |
+
|
| 123 |
+
### Getting Help
|
| 124 |
+
|
| 125 |
+
- Check the Space logs at the Space URL
|
| 126 |
+
- Verify your HF token has the necessary permissions
|
| 127 |
+
- Ensure the dataset repository exists and is accessible
|
| 128 |
+
|
| 129 |
Visit: {SPACE_URL}
|
templates/spaces/requirements.txt
CHANGED
|
@@ -1,22 +1,24 @@
|
|
| 1 |
-
# Gradio
|
| 2 |
gradio>=4.0.0
|
| 3 |
gradio-client>=0.10.0
|
| 4 |
|
| 5 |
-
#
|
| 6 |
-
requests>=2.31.0
|
| 7 |
-
numpy>=1.24.0
|
| 8 |
pandas>=2.0.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
-
# JSON
|
| 11 |
jsonschema>=4.17.0
|
| 12 |
|
| 13 |
-
#
|
| 14 |
-
plotly>=5.0.0
|
| 15 |
-
pandas>=2.0.0
|
| 16 |
-
numpy>=1.24.0
|
| 17 |
datasets>=2.14.0
|
| 18 |
huggingface-hub>=0.16.0
|
| 19 |
-
requests>=2.31.0
|
| 20 |
|
| 21 |
-
#
|
| 22 |
-
python-dotenv>=1.0.0
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Core Gradio dependencies
|
| 2 |
gradio>=4.0.0
|
| 3 |
gradio-client>=0.10.0
|
| 4 |
|
| 5 |
+
# Data processing and visualization
|
|
|
|
|
|
|
| 6 |
pandas>=2.0.0
|
| 7 |
+
numpy>=1.24.0
|
| 8 |
+
plotly>=5.15.0
|
| 9 |
+
|
| 10 |
+
# HTTP requests and API
|
| 11 |
+
requests>=2.31.0
|
| 12 |
|
| 13 |
+
# JSON handling
|
| 14 |
jsonschema>=4.17.0
|
| 15 |
|
| 16 |
+
# Hugging Face integration
|
|
|
|
|
|
|
|
|
|
| 17 |
datasets>=2.14.0
|
| 18 |
huggingface-hub>=0.16.0
|
|
|
|
| 19 |
|
| 20 |
+
# Environment and configuration
|
| 21 |
+
python-dotenv>=1.0.0
|
| 22 |
+
|
| 23 |
+
# Optional: for better performance
|
| 24 |
+
matplotlib>=3.7.0
|
tests/test_latest_deployment.py
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Test script to verify the latest Trackio Space deployment using HF Hub API
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import os
|
| 7 |
+
import sys
|
| 8 |
+
import tempfile
|
| 9 |
+
import shutil
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
|
| 12 |
+
# Add project root to path
|
| 13 |
+
project_root = Path(__file__).parent.parent
|
| 14 |
+
sys.path.insert(0, str(project_root))
|
| 15 |
+
|
| 16 |
+
def test_hf_hub_import():
|
| 17 |
+
"""Test that huggingface_hub can be imported"""
|
| 18 |
+
print("π Testing huggingface_hub import...")
|
| 19 |
+
|
| 20 |
+
try:
|
| 21 |
+
from huggingface_hub import HfApi, create_repo
|
| 22 |
+
print("β
huggingface_hub imported successfully")
|
| 23 |
+
return True
|
| 24 |
+
except ImportError as e:
|
| 25 |
+
print(f"β Failed to import huggingface_hub: {e}")
|
| 26 |
+
print("π‘ Install with: pip install huggingface_hub>=0.19.0")
|
| 27 |
+
return False
|
| 28 |
+
|
| 29 |
+
def test_deployment_script_import():
|
| 30 |
+
"""Test that the deployment script can be imported"""
|
| 31 |
+
print("\nπ Testing deployment script import...")
|
| 32 |
+
|
| 33 |
+
try:
|
| 34 |
+
sys.path.insert(0, str(project_root / "scripts" / "trackio_tonic"))
|
| 35 |
+
from deploy_trackio_space import TrackioSpaceDeployer
|
| 36 |
+
|
| 37 |
+
# Test class instantiation
|
| 38 |
+
deployer = TrackioSpaceDeployer("test-space", "test-user", "test-token")
|
| 39 |
+
print("β
TrackioSpaceDeployer class imported successfully")
|
| 40 |
+
|
| 41 |
+
# Test API availability
|
| 42 |
+
if hasattr(deployer, 'api'):
|
| 43 |
+
print("β
HF API initialized")
|
| 44 |
+
else:
|
| 45 |
+
print("β οΈ HF API not available (fallback to CLI)")
|
| 46 |
+
|
| 47 |
+
return True
|
| 48 |
+
|
| 49 |
+
except Exception as e:
|
| 50 |
+
print(f"β Error testing deployment script: {e}")
|
| 51 |
+
return False
|
| 52 |
+
|
| 53 |
+
def test_api_methods():
|
| 54 |
+
"""Test that the deployment script has the new API methods"""
|
| 55 |
+
print("\nπ Testing API methods...")
|
| 56 |
+
|
| 57 |
+
try:
|
| 58 |
+
sys.path.insert(0, str(project_root / "scripts" / "trackio_tonic"))
|
| 59 |
+
from deploy_trackio_space import TrackioSpaceDeployer
|
| 60 |
+
|
| 61 |
+
deployer = TrackioSpaceDeployer("test-space", "test-user", "test-token")
|
| 62 |
+
|
| 63 |
+
# Test required methods exist
|
| 64 |
+
required_methods = [
|
| 65 |
+
"create_space",
|
| 66 |
+
"_create_space_cli",
|
| 67 |
+
"prepare_space_files",
|
| 68 |
+
"upload_files_to_space",
|
| 69 |
+
"test_space",
|
| 70 |
+
"deploy"
|
| 71 |
+
]
|
| 72 |
+
|
| 73 |
+
for method in required_methods:
|
| 74 |
+
if hasattr(deployer, method):
|
| 75 |
+
print(f"β
Method exists: {method}")
|
| 76 |
+
else:
|
| 77 |
+
print(f"β Missing method: {method}")
|
| 78 |
+
return False
|
| 79 |
+
|
| 80 |
+
return True
|
| 81 |
+
|
| 82 |
+
except Exception as e:
|
| 83 |
+
print(f"β Error testing API methods: {e}")
|
| 84 |
+
return False
|
| 85 |
+
|
| 86 |
+
def test_create_repo_api():
|
| 87 |
+
"""Test the create_repo API function"""
|
| 88 |
+
print("\nπ Testing create_repo API...")
|
| 89 |
+
|
| 90 |
+
try:
|
| 91 |
+
from huggingface_hub import create_repo
|
| 92 |
+
|
| 93 |
+
# Test that the function exists and has the right parameters
|
| 94 |
+
import inspect
|
| 95 |
+
sig = inspect.signature(create_repo)
|
| 96 |
+
|
| 97 |
+
# Check for required parameters
|
| 98 |
+
required_params = ['repo_id', 'token']
|
| 99 |
+
optional_params = ['repo_type', 'space_sdk', 'space_hardware']
|
| 100 |
+
|
| 101 |
+
param_names = list(sig.parameters.keys())
|
| 102 |
+
|
| 103 |
+
for param in required_params:
|
| 104 |
+
if param in param_names:
|
| 105 |
+
print(f"β
Required parameter: {param}")
|
| 106 |
+
else:
|
| 107 |
+
print(f"β Missing required parameter: {param}")
|
| 108 |
+
return False
|
| 109 |
+
|
| 110 |
+
for param in optional_params:
|
| 111 |
+
if param in param_names:
|
| 112 |
+
print(f"β
Optional parameter: {param}")
|
| 113 |
+
else:
|
| 114 |
+
print(f"β οΈ Optional parameter not found: {param}")
|
| 115 |
+
|
| 116 |
+
print("β
create_repo API signature looks correct")
|
| 117 |
+
return True
|
| 118 |
+
|
| 119 |
+
except Exception as e:
|
| 120 |
+
print(f"β Error testing create_repo API: {e}")
|
| 121 |
+
return False
|
| 122 |
+
|
| 123 |
+
def test_space_creation_logic():
|
| 124 |
+
"""Test the space creation logic"""
|
| 125 |
+
print("\nπ Testing space creation logic...")
|
| 126 |
+
|
| 127 |
+
try:
|
| 128 |
+
sys.path.insert(0, str(project_root / "scripts" / "trackio_tonic"))
|
| 129 |
+
from deploy_trackio_space import TrackioSpaceDeployer
|
| 130 |
+
|
| 131 |
+
# Test with mock data
|
| 132 |
+
deployer = TrackioSpaceDeployer("test-space", "test-user", "test-token")
|
| 133 |
+
|
| 134 |
+
# Test that the space URL is correctly formatted
|
| 135 |
+
expected_url = "https://huggingface.co/spaces/test-user/test-space"
|
| 136 |
+
if deployer.space_url == expected_url:
|
| 137 |
+
print("β
Space URL formatted correctly")
|
| 138 |
+
else:
|
| 139 |
+
print(f"β Space URL incorrect: {deployer.space_url}")
|
| 140 |
+
return False
|
| 141 |
+
|
| 142 |
+
# Test that the repo_id is correctly formatted
|
| 143 |
+
repo_id = f"{deployer.username}/{deployer.space_name}"
|
| 144 |
+
expected_repo_id = "test-user/test-space"
|
| 145 |
+
if repo_id == expected_repo_id:
|
| 146 |
+
print("β
Repo ID formatted correctly")
|
| 147 |
+
else:
|
| 148 |
+
print(f"β Repo ID incorrect: {repo_id}")
|
| 149 |
+
return False
|
| 150 |
+
|
| 151 |
+
return True
|
| 152 |
+
|
| 153 |
+
except Exception as e:
|
| 154 |
+
print(f"β Error testing space creation logic: {e}")
|
| 155 |
+
return False
|
| 156 |
+
|
| 157 |
+
def test_template_files():
|
| 158 |
+
"""Test that all required template files exist"""
|
| 159 |
+
print("\nπ Testing template files...")
|
| 160 |
+
|
| 161 |
+
templates_dir = project_root / "templates" / "spaces"
|
| 162 |
+
required_files = ["app.py", "requirements.txt", "README.md"]
|
| 163 |
+
|
| 164 |
+
for file_name in required_files:
|
| 165 |
+
file_path = templates_dir / file_name
|
| 166 |
+
if file_path.exists():
|
| 167 |
+
print(f"β
{file_name} exists")
|
| 168 |
+
else:
|
| 169 |
+
print(f"β {file_name} missing")
|
| 170 |
+
return False
|
| 171 |
+
|
| 172 |
+
return True
|
| 173 |
+
|
| 174 |
+
def test_temp_directory_handling():
|
| 175 |
+
"""Test temporary directory handling"""
|
| 176 |
+
print("\nπ Testing temporary directory handling...")
|
| 177 |
+
|
| 178 |
+
try:
|
| 179 |
+
import tempfile
|
| 180 |
+
|
| 181 |
+
# Test temp directory creation
|
| 182 |
+
temp_dir = tempfile.mkdtemp()
|
| 183 |
+
print(f"β
Created temp directory: {temp_dir}")
|
| 184 |
+
|
| 185 |
+
# Test file copying
|
| 186 |
+
templates_dir = project_root / "templates" / "spaces"
|
| 187 |
+
test_file = templates_dir / "app.py"
|
| 188 |
+
|
| 189 |
+
if test_file.exists():
|
| 190 |
+
dest_file = Path(temp_dir) / "app.py"
|
| 191 |
+
shutil.copy2(test_file, dest_file)
|
| 192 |
+
print("β
File copying works")
|
| 193 |
+
else:
|
| 194 |
+
print("β Source file not found")
|
| 195 |
+
return False
|
| 196 |
+
|
| 197 |
+
# Clean up
|
| 198 |
+
shutil.rmtree(temp_dir)
|
| 199 |
+
print("β
Cleanup successful")
|
| 200 |
+
|
| 201 |
+
return True
|
| 202 |
+
|
| 203 |
+
except Exception as e:
|
| 204 |
+
print(f"β Error testing temp directory handling: {e}")
|
| 205 |
+
return False
|
| 206 |
+
|
| 207 |
+
def main():
|
| 208 |
+
"""Run all deployment tests"""
|
| 209 |
+
print("π Testing Latest Trackio Space Deployment")
|
| 210 |
+
print("=" * 55)
|
| 211 |
+
|
| 212 |
+
tests = [
|
| 213 |
+
test_hf_hub_import,
|
| 214 |
+
test_deployment_script_import,
|
| 215 |
+
test_api_methods,
|
| 216 |
+
test_create_repo_api,
|
| 217 |
+
test_space_creation_logic,
|
| 218 |
+
test_template_files,
|
| 219 |
+
test_temp_directory_handling
|
| 220 |
+
]
|
| 221 |
+
|
| 222 |
+
passed = 0
|
| 223 |
+
total = len(tests)
|
| 224 |
+
|
| 225 |
+
for test in tests:
|
| 226 |
+
try:
|
| 227 |
+
if test():
|
| 228 |
+
passed += 1
|
| 229 |
+
except Exception as e:
|
| 230 |
+
print(f"β Test {test.__name__} crashed: {e}")
|
| 231 |
+
|
| 232 |
+
print(f"\nπ Test Results: {passed}/{total} tests passed")
|
| 233 |
+
|
| 234 |
+
if passed == total:
|
| 235 |
+
print("β
All deployment tests passed! The latest deployment should work correctly.")
|
| 236 |
+
print("\nπ― Next steps:")
|
| 237 |
+
print("1. Install latest huggingface_hub: pip install huggingface_hub>=0.19.0")
|
| 238 |
+
print("2. Run the deployment script: python scripts/trackio_tonic/deploy_trackio_space.py")
|
| 239 |
+
print("3. Provide your HF username, space name, and token")
|
| 240 |
+
print("4. Wait for the Space to build (2-5 minutes)")
|
| 241 |
+
print("5. Test the Space URL")
|
| 242 |
+
return True
|
| 243 |
+
else:
|
| 244 |
+
print("β Some deployment tests failed. Please check the errors above.")
|
| 245 |
+
print("\nπ‘ Troubleshooting:")
|
| 246 |
+
print("1. Install huggingface_hub: pip install huggingface_hub>=0.19.0")
|
| 247 |
+
print("2. Check that all template files exist")
|
| 248 |
+
print("3. Verify the deployment script structure")
|
| 249 |
+
return False
|
| 250 |
+
|
| 251 |
+
if __name__ == "__main__":
|
| 252 |
+
success = main()
|
| 253 |
+
sys.exit(0 if success else 1)
|
tests/test_trackio_deployment.py
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Test script to verify Trackio Space deployment
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import os
|
| 7 |
+
import sys
|
| 8 |
+
import tempfile
|
| 9 |
+
import shutil
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
|
| 12 |
+
# Add project root to path
|
| 13 |
+
project_root = Path(__file__).parent.parent
|
| 14 |
+
sys.path.insert(0, str(project_root))
|
| 15 |
+
|
| 16 |
+
def test_templates_structure():
|
| 17 |
+
"""Test that the templates structure is correct"""
|
| 18 |
+
print("π Testing templates structure...")
|
| 19 |
+
|
| 20 |
+
templates_dir = project_root / "templates" / "spaces"
|
| 21 |
+
|
| 22 |
+
required_files = ["app.py", "requirements.txt", "README.md"]
|
| 23 |
+
|
| 24 |
+
for file_name in required_files:
|
| 25 |
+
file_path = templates_dir / file_name
|
| 26 |
+
if file_path.exists():
|
| 27 |
+
print(f"β
{file_name} exists")
|
| 28 |
+
else:
|
| 29 |
+
print(f"β {file_name} missing")
|
| 30 |
+
return False
|
| 31 |
+
|
| 32 |
+
return True
|
| 33 |
+
|
| 34 |
+
def test_app_py_content():
|
| 35 |
+
"""Test that app.py has the required structure"""
|
| 36 |
+
print("\nπ Testing app.py content...")
|
| 37 |
+
|
| 38 |
+
app_path = project_root / "templates" / "spaces" / "app.py"
|
| 39 |
+
|
| 40 |
+
try:
|
| 41 |
+
with open(app_path, 'r', encoding='utf-8') as f:
|
| 42 |
+
content = f.read()
|
| 43 |
+
|
| 44 |
+
# Check for required components
|
| 45 |
+
required_components = [
|
| 46 |
+
"import gradio as gr",
|
| 47 |
+
"class TrackioSpace",
|
| 48 |
+
"def create_experiment_interface",
|
| 49 |
+
"def log_metrics_interface",
|
| 50 |
+
"def log_parameters_interface",
|
| 51 |
+
"demo.launch()"
|
| 52 |
+
]
|
| 53 |
+
|
| 54 |
+
for component in required_components:
|
| 55 |
+
if component in content:
|
| 56 |
+
print(f"β
Found: {component}")
|
| 57 |
+
else:
|
| 58 |
+
print(f"β Missing: {component}")
|
| 59 |
+
return False
|
| 60 |
+
|
| 61 |
+
return True
|
| 62 |
+
|
| 63 |
+
except Exception as e:
|
| 64 |
+
print(f"β Error reading app.py: {e}")
|
| 65 |
+
return False
|
| 66 |
+
|
| 67 |
+
def test_requirements_content():
|
| 68 |
+
"""Test that requirements.txt has the required dependencies"""
|
| 69 |
+
print("\nπ Testing requirements.txt content...")
|
| 70 |
+
|
| 71 |
+
req_path = project_root / "templates" / "spaces" / "requirements.txt"
|
| 72 |
+
|
| 73 |
+
try:
|
| 74 |
+
with open(req_path, 'r', encoding='utf-8') as f:
|
| 75 |
+
content = f.read()
|
| 76 |
+
|
| 77 |
+
# Check for required dependencies
|
| 78 |
+
required_deps = [
|
| 79 |
+
"gradio>=",
|
| 80 |
+
"pandas>=",
|
| 81 |
+
"numpy>=",
|
| 82 |
+
"plotly>=",
|
| 83 |
+
"requests>=",
|
| 84 |
+
"datasets>=",
|
| 85 |
+
"huggingface-hub>="
|
| 86 |
+
]
|
| 87 |
+
|
| 88 |
+
for dep in required_deps:
|
| 89 |
+
if dep in content:
|
| 90 |
+
print(f"β
Found: {dep}")
|
| 91 |
+
else:
|
| 92 |
+
print(f"β Missing: {dep}")
|
| 93 |
+
return False
|
| 94 |
+
|
| 95 |
+
return True
|
| 96 |
+
|
| 97 |
+
except Exception as e:
|
| 98 |
+
print(f"β Error reading requirements.txt: {e}")
|
| 99 |
+
return False
|
| 100 |
+
|
| 101 |
+
def test_readme_structure():
|
| 102 |
+
"""Test that README.md has the correct structure"""
|
| 103 |
+
print("\nπ Testing README.md structure...")
|
| 104 |
+
|
| 105 |
+
readme_path = project_root / "templates" / "spaces" / "README.md"
|
| 106 |
+
|
| 107 |
+
try:
|
| 108 |
+
with open(readme_path, 'r', encoding='utf-8') as f:
|
| 109 |
+
content = f.read()
|
| 110 |
+
|
| 111 |
+
# Check for required sections
|
| 112 |
+
required_sections = [
|
| 113 |
+
"---",
|
| 114 |
+
"title: Trackio Experiment Tracking",
|
| 115 |
+
"sdk: gradio",
|
| 116 |
+
"app_file: app.py",
|
| 117 |
+
"# Trackio Experiment Tracking",
|
| 118 |
+
"## Features",
|
| 119 |
+
"## Usage",
|
| 120 |
+
"Visit: {SPACE_URL}"
|
| 121 |
+
]
|
| 122 |
+
|
| 123 |
+
for section in required_sections:
|
| 124 |
+
if section in content:
|
| 125 |
+
print(f"β
Found: {section}")
|
| 126 |
+
else:
|
| 127 |
+
print(f"β Missing: {section}")
|
| 128 |
+
return False
|
| 129 |
+
|
| 130 |
+
return True
|
| 131 |
+
|
| 132 |
+
except Exception as e:
|
| 133 |
+
print(f"β Error reading README.md: {e}")
|
| 134 |
+
return False
|
| 135 |
+
|
| 136 |
+
def test_deployment_script():
|
| 137 |
+
"""Test that the deployment script can be imported and has required methods"""
|
| 138 |
+
print("\nπ Testing deployment script...")
|
| 139 |
+
|
| 140 |
+
try:
|
| 141 |
+
sys.path.insert(0, str(project_root / "scripts" / "trackio_tonic"))
|
| 142 |
+
from deploy_trackio_space import TrackioSpaceDeployer
|
| 143 |
+
|
| 144 |
+
# Test class instantiation
|
| 145 |
+
deployer = TrackioSpaceDeployer("test-space", "test-user", "test-token")
|
| 146 |
+
print("β
TrackioSpaceDeployer class imported successfully")
|
| 147 |
+
|
| 148 |
+
# Test required methods exist
|
| 149 |
+
required_methods = [
|
| 150 |
+
"create_space",
|
| 151 |
+
"prepare_space_files",
|
| 152 |
+
"upload_files_to_space",
|
| 153 |
+
"test_space",
|
| 154 |
+
"deploy"
|
| 155 |
+
]
|
| 156 |
+
|
| 157 |
+
for method in required_methods:
|
| 158 |
+
if hasattr(deployer, method):
|
| 159 |
+
print(f"β
Method exists: {method}")
|
| 160 |
+
else:
|
| 161 |
+
print(f"β Missing method: {method}")
|
| 162 |
+
return False
|
| 163 |
+
|
| 164 |
+
return True
|
| 165 |
+
|
| 166 |
+
except Exception as e:
|
| 167 |
+
print(f"β Error testing deployment script: {e}")
|
| 168 |
+
return False
|
| 169 |
+
|
| 170 |
+
def test_temp_directory_creation():
|
| 171 |
+
"""Test that the deployment script can create temporary directories"""
|
| 172 |
+
print("\nπ Testing temporary directory creation...")
|
| 173 |
+
|
| 174 |
+
try:
|
| 175 |
+
import tempfile
|
| 176 |
+
import shutil
|
| 177 |
+
|
| 178 |
+
# Test temp directory creation
|
| 179 |
+
temp_dir = tempfile.mkdtemp()
|
| 180 |
+
print(f"β
Created temp directory: {temp_dir}")
|
| 181 |
+
|
| 182 |
+
# Test file copying
|
| 183 |
+
templates_dir = project_root / "templates" / "spaces"
|
| 184 |
+
test_file = templates_dir / "app.py"
|
| 185 |
+
|
| 186 |
+
if test_file.exists():
|
| 187 |
+
dest_file = Path(temp_dir) / "app.py"
|
| 188 |
+
shutil.copy2(test_file, dest_file)
|
| 189 |
+
print("β
File copying works")
|
| 190 |
+
else:
|
| 191 |
+
print("β Source file not found")
|
| 192 |
+
return False
|
| 193 |
+
|
| 194 |
+
# Clean up
|
| 195 |
+
shutil.rmtree(temp_dir)
|
| 196 |
+
print("β
Cleanup successful")
|
| 197 |
+
|
| 198 |
+
return True
|
| 199 |
+
|
| 200 |
+
except Exception as e:
|
| 201 |
+
print(f"β Error testing temp directory creation: {e}")
|
| 202 |
+
return False
|
| 203 |
+
|
| 204 |
+
def main():
|
| 205 |
+
"""Run all deployment tests"""
|
| 206 |
+
print("π Testing Trackio Space Deployment")
|
| 207 |
+
print("=" * 50)
|
| 208 |
+
|
| 209 |
+
tests = [
|
| 210 |
+
test_templates_structure,
|
| 211 |
+
test_app_py_content,
|
| 212 |
+
test_requirements_content,
|
| 213 |
+
test_readme_structure,
|
| 214 |
+
test_deployment_script,
|
| 215 |
+
test_temp_directory_creation
|
| 216 |
+
]
|
| 217 |
+
|
| 218 |
+
passed = 0
|
| 219 |
+
total = len(tests)
|
| 220 |
+
|
| 221 |
+
for test in tests:
|
| 222 |
+
try:
|
| 223 |
+
if test():
|
| 224 |
+
passed += 1
|
| 225 |
+
except Exception as e:
|
| 226 |
+
print(f"β Test {test.__name__} crashed: {e}")
|
| 227 |
+
|
| 228 |
+
print(f"\nπ Test Results: {passed}/{total} tests passed")
|
| 229 |
+
|
| 230 |
+
if passed == total:
|
| 231 |
+
print("β
All deployment tests passed! The Trackio Space should deploy correctly.")
|
| 232 |
+
print("\nπ― Next steps:")
|
| 233 |
+
print("1. Run the deployment script: python scripts/trackio_tonic/deploy_trackio_space.py")
|
| 234 |
+
print("2. Provide your HF username, space name, and token")
|
| 235 |
+
print("3. Wait for the Space to build (2-5 minutes)")
|
| 236 |
+
print("4. Test the Space URL")
|
| 237 |
+
return True
|
| 238 |
+
else:
|
| 239 |
+
print("β Some deployment tests failed. Please check the errors above.")
|
| 240 |
+
return False
|
| 241 |
+
|
| 242 |
+
if __name__ == "__main__":
|
| 243 |
+
success = main()
|
| 244 |
+
sys.exit(0 if success else 1)
|