Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files- .gitattributes +3 -0
- .gitignore +15 -1
- HUGGINGFACE_DEPLOYMENT_FIX.md +133 -0
- README_HF.md +18 -0
- hf_app.py +183 -0
- hf_deploy/.gitattributes +35 -0
- hf_deploy/.gitignore +25 -0
- hf_deploy/Assets/Ghibli.jpg +3 -0
- hf_deploy/Assets/Picasso.jpg +3 -0
- hf_deploy/Assets/Pixar.jpg +0 -0
- hf_deploy/Assets/README.md +3 -0
- hf_deploy/Assets/VanGogh.jpg +3 -0
- hf_deploy/Generated/README.md +3 -0
- hf_deploy/README.md +40 -0
- hf_deploy/hf_app.py +183 -0
- hf_deploy/requirements.txt +7 -0
- hf_deploy/static/README.md +3 -0
- hf_deploy/view_session/README.md +3 -0
- hf_spaces_startup.py +65 -0
- prepare_hf_deployment.py +164 -0
.gitattributes
CHANGED
|
@@ -36,3 +36,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 36 |
Assets/Ghibli.jpg filter=lfs diff=lfs merge=lfs -text
|
| 37 |
Assets/Picasso.jpg filter=lfs diff=lfs merge=lfs -text
|
| 38 |
Assets/VanGogh.jpg filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
Assets/Ghibli.jpg filter=lfs diff=lfs merge=lfs -text
|
| 37 |
Assets/Picasso.jpg filter=lfs diff=lfs merge=lfs -text
|
| 38 |
Assets/VanGogh.jpg filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
hf_deploy/Assets/Ghibli.jpg filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
hf_deploy/Assets/Picasso.jpg filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
hf_deploy/Assets/VanGogh.jpg filter=lfs diff=lfs merge=lfs -text
|
.gitignore
CHANGED
|
@@ -3,4 +3,18 @@
|
|
| 3 |
.cache/*
|
| 4 |
!.cache/Assets/
|
| 5 |
|
| 6 |
-
cache/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
.cache/*
|
| 4 |
!.cache/Assets/
|
| 5 |
|
| 6 |
+
cache/
|
| 7 |
+
|
| 8 |
+
# Keep essential directories for HuggingFace deployment
|
| 9 |
+
# These directories need to exist for the app to work properly
|
| 10 |
+
!Generated/
|
| 11 |
+
!static/
|
| 12 |
+
!view_session/
|
| 13 |
+
|
| 14 |
+
# But ignore their contents during development (they're created at runtime)
|
| 15 |
+
Generated/*
|
| 16 |
+
!Generated/README.md
|
| 17 |
+
static/*
|
| 18 |
+
!static/README.md
|
| 19 |
+
view_session/*
|
| 20 |
+
!view_session/README.md
|
HUGGINGFACE_DEPLOYMENT_FIX.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# HuggingFace Spaces Deployment Fix
|
| 2 |
+
|
| 3 |
+
## β **The Problem**
|
| 4 |
+
|
| 5 |
+
When deploying the BytePlus Image Generation Studio to HuggingFace Spaces, the `Generated`, `static`, and `view_session` folders are **NOT created** or **NOT accessible**, causing:
|
| 6 |
+
|
| 7 |
+
1. View session links show **nothing** (blank page)
|
| 8 |
+
2. Generated images are **not stored persistently**
|
| 9 |
+
3. ZIP downloads **don't work**
|
| 10 |
+
4. Session viewer **returns 404 errors**
|
| 11 |
+
|
| 12 |
+
## β
**The Solution**
|
| 13 |
+
|
| 14 |
+
The issue occurs because HuggingFace Spaces needs these directories to be **explicitly created** and **properly configured** for the deployment. Here's the complete fix:
|
| 15 |
+
|
| 16 |
+
### **Step 1: Use the Pre-built Deployment Package**
|
| 17 |
+
|
| 18 |
+
I've created a deployment-ready package in the `hf_deploy/` directory that includes:
|
| 19 |
+
|
| 20 |
+
- β
**Essential directories** with proper structure
|
| 21 |
+
- β
**HuggingFace-optimized app.py**
|
| 22 |
+
- β
**Correct .gitignore** settings
|
| 23 |
+
- β
**README.md** for HuggingFace Spaces
|
| 24 |
+
- β
**Directory creation** on startup
|
| 25 |
+
|
| 26 |
+
### **Step 2: Deploy to HuggingFace Spaces**
|
| 27 |
+
|
| 28 |
+
1. **Create a new HuggingFace Space**:
|
| 29 |
+
```
|
| 30 |
+
https://huggingface.co/new-space
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
2. **Upload all files** from the `hf_deploy/` directory:
|
| 34 |
+
```
|
| 35 |
+
hf_deploy/
|
| 36 |
+
βββ hf_app.py # Main app file (optimized for HF Spaces)
|
| 37 |
+
βββ app.py # BytePlus application code
|
| 38 |
+
βββ requirements.txt # Python dependencies
|
| 39 |
+
βββ README.md # HuggingFace Space description
|
| 40 |
+
βββ .gitignore # Proper ignore rules
|
| 41 |
+
βββ Generated/ # Directory for generated images
|
| 42 |
+
β βββ README.md
|
| 43 |
+
βββ static/ # Directory for static files
|
| 44 |
+
β βββ README.md
|
| 45 |
+
βββ view_session/ # Directory for session viewer
|
| 46 |
+
β βββ README.md
|
| 47 |
+
βββ Assets/ # Sample images and resources
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
3. **Set the app_file** in your Space settings:
|
| 51 |
+
```yaml
|
| 52 |
+
app_file: hf_app.py
|
| 53 |
+
```
|
| 54 |
+
|
| 55 |
+
### **Step 3: The Fix Explained**
|
| 56 |
+
|
| 57 |
+
#### **π§ Directory Creation on Startup**
|
| 58 |
+
The `hf_app.py` automatically creates the required directories:
|
| 59 |
+
|
| 60 |
+
```python
|
| 61 |
+
def setup_huggingface_environment():
|
| 62 |
+
essential_dirs = ["Generated", "static", "view_session"]
|
| 63 |
+
|
| 64 |
+
for dir_name in essential_dirs:
|
| 65 |
+
dir_path = Path(dir_name)
|
| 66 |
+
if not dir_path.exists():
|
| 67 |
+
dir_path.mkdir(exist_ok=True, mode=0o755)
|
| 68 |
+
print(f"β
Created directory: {dir_name}")
|
| 69 |
+
```
|
| 70 |
+
|
| 71 |
+
#### **π§ Proper Permissions**
|
| 72 |
+
All directories are created with `755` permissions (readable/accessible).
|
| 73 |
+
|
| 74 |
+
#### **π§ HuggingFace Spaces Detection**
|
| 75 |
+
The app detects when it's running on HuggingFace Spaces and adjusts behavior:
|
| 76 |
+
|
| 77 |
+
```python
|
| 78 |
+
is_hf_space = bool(os.environ.get("SPACE_ID"))
|
| 79 |
+
```
|
| 80 |
+
|
| 81 |
+
### **Step 4: Verify the Fix**
|
| 82 |
+
|
| 83 |
+
After deployment, your HuggingFace Space will have:
|
| 84 |
+
|
| 85 |
+
1. β
**Working view_session URLs**: `https://your-space.hf.space/view_session/TIMESTAMP`
|
| 86 |
+
2. β
**Generated images storage**: Images saved to `Generated/session_*/`
|
| 87 |
+
3. β
**ZIP downloads**: Available at `/Generated/filename.zip`
|
| 88 |
+
4. β
**Static file serving**: Proper file access via `/files/`
|
| 89 |
+
|
| 90 |
+
### **Step 5: Test the Deployment**
|
| 91 |
+
|
| 92 |
+
1. **Generate some images** using your deployed Space
|
| 93 |
+
2. **Check the history gallery** - you should see sessions with "ποΈ View" buttons
|
| 94 |
+
3. **Click "ποΈ View"** - should open a beautiful gallery in new tab
|
| 95 |
+
4. **Verify URLs** - should be `https://your-space.hf.space/view_session/...`
|
| 96 |
+
|
| 97 |
+
## π **Alternative Quick Fix**
|
| 98 |
+
|
| 99 |
+
If you want to fix your existing HuggingFace Space without redeploying:
|
| 100 |
+
|
| 101 |
+
### **Option A: Add directories manually**
|
| 102 |
+
1. In your HuggingFace Space, create these directories:
|
| 103 |
+
- `Generated/`
|
| 104 |
+
- `static/`
|
| 105 |
+
- `view_session/`
|
| 106 |
+
|
| 107 |
+
### **Option B: Modify your existing app.py**
|
| 108 |
+
Add this code to the beginning of your app.py on HuggingFace:
|
| 109 |
+
|
| 110 |
+
```python
|
| 111 |
+
import os
|
| 112 |
+
from pathlib import Path
|
| 113 |
+
|
| 114 |
+
# Ensure directories exist for HuggingFace Spaces
|
| 115 |
+
for dir_name in ["Generated", "static", "view_session"]:
|
| 116 |
+
Path(dir_name).mkdir(exist_ok=True, mode=0o755)
|
| 117 |
+
print(f"β
Ensured directory exists: {dir_name}")
|
| 118 |
+
```
|
| 119 |
+
|
| 120 |
+
## π **Summary**
|
| 121 |
+
|
| 122 |
+
The root cause was that HuggingFace Spaces doesn't automatically create runtime directories. The solution:
|
| 123 |
+
|
| 124 |
+
1. **Pre-create directories** in the repository
|
| 125 |
+
2. **Ensure proper permissions** (755)
|
| 126 |
+
3. **Add startup code** to verify directories exist
|
| 127 |
+
4. **Use HuggingFace-optimized** deployment structure
|
| 128 |
+
|
| 129 |
+
After applying this fix, your `view_session` links will work perfectly on HuggingFace Spaces! π
|
| 130 |
+
|
| 131 |
+
## π **Files Ready for Deployment**
|
| 132 |
+
|
| 133 |
+
All necessary files are prepared in `/Users/data/SGS-1/hf_deploy/` - just upload them to your HuggingFace Space and the directories will be created automatically!
|
README_HF.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
title: BytePlus Image Generation Studio
|
| 2 |
+
emoji: π¨
|
| 3 |
+
colorFrom: blue
|
| 4 |
+
colorTo: purple
|
| 5 |
+
sdk: gradio
|
| 6 |
+
sdk_version: 5.44.1
|
| 7 |
+
app_file: hf_app.py
|
| 8 |
+
pinned: false
|
| 9 |
+
license: apache-2.0
|
| 10 |
+
short_description: Secure BytePlus Image Generation Studio with session management
|
| 11 |
+
tags:
|
| 12 |
+
- image-generation
|
| 13 |
+
- byteplus
|
| 14 |
+
- ai
|
| 15 |
+
- gradio
|
| 16 |
+
models:
|
| 17 |
+
- byteplus/image-generation
|
| 18 |
+
datasets: []
|
hf_app.py
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
HuggingFace Spaces version of BytePlus Image Generation Studio
|
| 4 |
+
This version is optimized for deployment on Hugging Face Spaces
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import sys
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
from huggingface_hub import snapshot_download
|
| 11 |
+
import importlib.util
|
| 12 |
+
|
| 13 |
+
from dotenv import load_dotenv
|
| 14 |
+
load_dotenv()
|
| 15 |
+
|
| 16 |
+
def setup_huggingface_environment():
|
| 17 |
+
"""Setup environment for HuggingFace Spaces deployment"""
|
| 18 |
+
|
| 19 |
+
# Detect if we're running on HuggingFace Spaces
|
| 20 |
+
is_hf_space = bool(os.environ.get("SPACE_ID"))
|
| 21 |
+
|
| 22 |
+
if is_hf_space:
|
| 23 |
+
print("π Detected HuggingFace Space environment")
|
| 24 |
+
|
| 25 |
+
# Create essential directories that must exist for the app to work
|
| 26 |
+
essential_dirs = ["Generated", "static", "view_session"]
|
| 27 |
+
|
| 28 |
+
for dir_name in essential_dirs:
|
| 29 |
+
dir_path = Path(dir_name)
|
| 30 |
+
if not dir_path.exists():
|
| 31 |
+
dir_path.mkdir(exist_ok=True, mode=0o755)
|
| 32 |
+
print(f"β
Created directory: {dir_name}")
|
| 33 |
+
else:
|
| 34 |
+
# Ensure correct permissions
|
| 35 |
+
try:
|
| 36 |
+
dir_path.chmod(0o755)
|
| 37 |
+
except Exception:
|
| 38 |
+
pass # Ignore permission errors on some filesystems
|
| 39 |
+
|
| 40 |
+
# For HuggingFace Spaces, we need to work with the current directory
|
| 41 |
+
# since we can't download to a hidden cache directory
|
| 42 |
+
return Path(".")
|
| 43 |
+
else:
|
| 44 |
+
# Local development - use the cache system
|
| 45 |
+
return setup_cache_directory()
|
| 46 |
+
|
| 47 |
+
def setup_cache_directory():
|
| 48 |
+
"""Create a hidden cache directory '.cache' for local development"""
|
| 49 |
+
hidden_cache = Path(".cache")
|
| 50 |
+
public_cache = Path("cache")
|
| 51 |
+
|
| 52 |
+
try:
|
| 53 |
+
if not hidden_cache.exists():
|
| 54 |
+
if public_cache.exists():
|
| 55 |
+
public_cache.rename(hidden_cache)
|
| 56 |
+
else:
|
| 57 |
+
hidden_cache.mkdir(exist_ok=True)
|
| 58 |
+
else:
|
| 59 |
+
hidden_cache.mkdir(exist_ok=True)
|
| 60 |
+
|
| 61 |
+
try:
|
| 62 |
+
hidden_cache.chmod(0o700)
|
| 63 |
+
except Exception:
|
| 64 |
+
pass
|
| 65 |
+
|
| 66 |
+
if sys.platform == "darwin":
|
| 67 |
+
hide_flag = os.environ.get("HIDE_CACHE", "1")
|
| 68 |
+
if hide_flag != "0":
|
| 69 |
+
try:
|
| 70 |
+
os.system(f"/usr/bin/chflags hidden {hidden_cache}")
|
| 71 |
+
except Exception:
|
| 72 |
+
pass
|
| 73 |
+
|
| 74 |
+
return hidden_cache
|
| 75 |
+
except Exception:
|
| 76 |
+
public_cache.mkdir(exist_ok=True)
|
| 77 |
+
return public_cache
|
| 78 |
+
|
| 79 |
+
def download_space(cache_dir):
|
| 80 |
+
"""Download the HuggingFace Space if needed"""
|
| 81 |
+
token = os.environ.get("HF_TOKEN")
|
| 82 |
+
repo_id = os.environ.get("REPO_ID")
|
| 83 |
+
|
| 84 |
+
is_hf_space = bool(os.environ.get("SPACE_ID"))
|
| 85 |
+
|
| 86 |
+
if is_hf_space:
|
| 87 |
+
# On HuggingFace Spaces, the code is already available
|
| 88 |
+
# We just need to ensure the main app file exists
|
| 89 |
+
app_path = cache_dir / "app.py"
|
| 90 |
+
if app_path.exists():
|
| 91 |
+
print("β
App code is already available in HuggingFace Space")
|
| 92 |
+
return True
|
| 93 |
+
else:
|
| 94 |
+
print("β App code not found in HuggingFace Space")
|
| 95 |
+
return False
|
| 96 |
+
|
| 97 |
+
# Local development - download from HuggingFace
|
| 98 |
+
if not token or not repo_id:
|
| 99 |
+
print("β οΈ HF_TOKEN or REPO_ID not set")
|
| 100 |
+
return False
|
| 101 |
+
|
| 102 |
+
try:
|
| 103 |
+
snapshot_download(
|
| 104 |
+
repo_id=repo_id,
|
| 105 |
+
repo_type="space",
|
| 106 |
+
local_dir=cache_dir,
|
| 107 |
+
token=token
|
| 108 |
+
)
|
| 109 |
+
return True
|
| 110 |
+
except Exception as e:
|
| 111 |
+
print(f"β Failed to download space: {e}")
|
| 112 |
+
return False
|
| 113 |
+
|
| 114 |
+
def load_app(cache_dir):
|
| 115 |
+
"""Load the BytePlus app"""
|
| 116 |
+
sys.path.insert(0, str(cache_dir))
|
| 117 |
+
|
| 118 |
+
# Look for the main app file
|
| 119 |
+
app_files = ["app.py", "main.py", "byteplus_app.py"]
|
| 120 |
+
|
| 121 |
+
for app_file in app_files:
|
| 122 |
+
app_path = cache_dir / app_file
|
| 123 |
+
if app_path.exists():
|
| 124 |
+
try:
|
| 125 |
+
spec = importlib.util.spec_from_file_location("app", app_path)
|
| 126 |
+
app = importlib.util.module_from_spec(spec)
|
| 127 |
+
spec.loader.exec_module(app)
|
| 128 |
+
|
| 129 |
+
# Try different ways to get the demo
|
| 130 |
+
if hasattr(app, "demo"):
|
| 131 |
+
return app.demo
|
| 132 |
+
elif hasattr(app, "create_secure_interface"):
|
| 133 |
+
return app.create_secure_interface()
|
| 134 |
+
elif hasattr(app, "main"):
|
| 135 |
+
return app.main()
|
| 136 |
+
|
| 137 |
+
except Exception as e:
|
| 138 |
+
print(f"β οΈ Failed to load {app_file}: {e}")
|
| 139 |
+
continue
|
| 140 |
+
|
| 141 |
+
raise AttributeError("Could not find or load the main app")
|
| 142 |
+
|
| 143 |
+
if __name__ == "__main__":
|
| 144 |
+
print("π Starting BytePlus Image Generation Studio")
|
| 145 |
+
print("π HuggingFace Spaces optimized version")
|
| 146 |
+
|
| 147 |
+
# Setup environment
|
| 148 |
+
cache_dir = setup_huggingface_environment()
|
| 149 |
+
|
| 150 |
+
# Download space if needed (for local development)
|
| 151 |
+
if download_space(cache_dir):
|
| 152 |
+
print("β
App loaded successfully")
|
| 153 |
+
|
| 154 |
+
# For HuggingFace Spaces, run the app directly
|
| 155 |
+
is_hf_space = bool(os.environ.get("SPACE_ID"))
|
| 156 |
+
|
| 157 |
+
if is_hf_space:
|
| 158 |
+
print("π Running in HuggingFace Space mode")
|
| 159 |
+
# Import and run the app directly
|
| 160 |
+
try:
|
| 161 |
+
sys.path.insert(0, str(cache_dir))
|
| 162 |
+
|
| 163 |
+
# Since we're in HF Spaces, the app code should be here
|
| 164 |
+
# Check if there's a main app file in the current directory
|
| 165 |
+
if Path("app.py").exists():
|
| 166 |
+
import app as main_app
|
| 167 |
+
if hasattr(main_app, "demo"):
|
| 168 |
+
main_app.demo.launch()
|
| 169 |
+
elif hasattr(main_app, "launch"):
|
| 170 |
+
main_app.launch()
|
| 171 |
+
else:
|
| 172 |
+
print("β Could not find launch method in app")
|
| 173 |
+
else:
|
| 174 |
+
print("β app.py not found in HuggingFace Space")
|
| 175 |
+
|
| 176 |
+
except Exception as e:
|
| 177 |
+
print(f"β Error running in HuggingFace Space: {e}")
|
| 178 |
+
else:
|
| 179 |
+
# Local development
|
| 180 |
+
demo = load_app(cache_dir)
|
| 181 |
+
demo.launch()
|
| 182 |
+
else:
|
| 183 |
+
print("β Failed to setup app environment")
|
hf_deploy/.gitattributes
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
hf_deploy/.gitignore
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Environment files
|
| 2 |
+
.env
|
| 3 |
+
|
| 4 |
+
# Python cache
|
| 5 |
+
__pycache__/
|
| 6 |
+
*.pyc
|
| 7 |
+
*.pyo
|
| 8 |
+
*.pyd
|
| 9 |
+
.Python
|
| 10 |
+
*.so
|
| 11 |
+
|
| 12 |
+
# Generated content (but keep directories)
|
| 13 |
+
Generated/*.jpg
|
| 14 |
+
Generated/*.png
|
| 15 |
+
Generated/*.zip
|
| 16 |
+
static/*.zip
|
| 17 |
+
static/*.jpg
|
| 18 |
+
static/*.png
|
| 19 |
+
|
| 20 |
+
# Logs
|
| 21 |
+
*.log
|
| 22 |
+
|
| 23 |
+
# OS files
|
| 24 |
+
.DS_Store
|
| 25 |
+
Thumbs.db
|
hf_deploy/Assets/Ghibli.jpg
ADDED
|
Git LFS Details
|
hf_deploy/Assets/Picasso.jpg
ADDED
|
Git LFS Details
|
hf_deploy/Assets/Pixar.jpg
ADDED
|
hf_deploy/Assets/README.md
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Assets
|
| 2 |
+
|
| 3 |
+
This directory is required for the BytePlus Image Generation Studio.
|
hf_deploy/Assets/VanGogh.jpg
ADDED
|
Git LFS Details
|
hf_deploy/Generated/README.md
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Generated
|
| 2 |
+
|
| 3 |
+
This directory is required for the BytePlus Image Generation Studio.
|
hf_deploy/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# BytePlus Image Generation Studio
|
| 2 |
+
|
| 3 |
+
A secure and feature-rich image generation studio powered by BytePlus API.
|
| 4 |
+
|
| 5 |
+
## Features
|
| 6 |
+
|
| 7 |
+
- π¨ Multiple art styles and generation modes
|
| 8 |
+
- π Secure API key management with encryption
|
| 9 |
+
- π Session-based image organization
|
| 10 |
+
- π₯ ZIP download functionality
|
| 11 |
+
- ποΈ Interactive session viewer
|
| 12 |
+
- π‘οΈ Rate limiting and abuse prevention
|
| 13 |
+
- π± Responsive web interface
|
| 14 |
+
|
| 15 |
+
## Usage
|
| 16 |
+
|
| 17 |
+
1. Enter your BytePlus API key in the interface
|
| 18 |
+
2. Choose your preferred settings (style, size, etc.)
|
| 19 |
+
3. Enter a prompt or upload an image
|
| 20 |
+
4. Generate images and view them in the gallery
|
| 21 |
+
5. Use the session viewer to see all images from a generation session
|
| 22 |
+
|
| 23 |
+
## Session Viewer
|
| 24 |
+
|
| 25 |
+
Click the "ποΈ View" button next to any session in the history to open a dedicated gallery view showing all images from that session.
|
| 26 |
+
|
| 27 |
+
## Security Features
|
| 28 |
+
|
| 29 |
+
- Encrypted API key storage
|
| 30 |
+
- Input validation and sanitization
|
| 31 |
+
- Rate limiting (20 requests/minute)
|
| 32 |
+
- Secure error handling
|
| 33 |
+
- Image validation and size limits
|
| 34 |
+
|
| 35 |
+
## Directories
|
| 36 |
+
|
| 37 |
+
- `Generated/`: Stores generated images organized by session
|
| 38 |
+
- `static/`: Serves static files and ZIP downloads
|
| 39 |
+
- `view_session/`: Supports the session viewing functionality
|
| 40 |
+
- `Assets/`: Contains sample images and resources
|
hf_deploy/hf_app.py
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
HuggingFace Spaces version of BytePlus Image Generation Studio
|
| 4 |
+
This version is optimized for deployment on Hugging Face Spaces
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import sys
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
from huggingface_hub import snapshot_download
|
| 11 |
+
import importlib.util
|
| 12 |
+
|
| 13 |
+
from dotenv import load_dotenv
|
| 14 |
+
load_dotenv()
|
| 15 |
+
|
| 16 |
+
def setup_huggingface_environment():
|
| 17 |
+
"""Setup environment for HuggingFace Spaces deployment"""
|
| 18 |
+
|
| 19 |
+
# Detect if we're running on HuggingFace Spaces
|
| 20 |
+
is_hf_space = bool(os.environ.get("SPACE_ID"))
|
| 21 |
+
|
| 22 |
+
if is_hf_space:
|
| 23 |
+
print("π Detected HuggingFace Space environment")
|
| 24 |
+
|
| 25 |
+
# Create essential directories that must exist for the app to work
|
| 26 |
+
essential_dirs = ["Generated", "static", "view_session"]
|
| 27 |
+
|
| 28 |
+
for dir_name in essential_dirs:
|
| 29 |
+
dir_path = Path(dir_name)
|
| 30 |
+
if not dir_path.exists():
|
| 31 |
+
dir_path.mkdir(exist_ok=True, mode=0o755)
|
| 32 |
+
print(f"β
Created directory: {dir_name}")
|
| 33 |
+
else:
|
| 34 |
+
# Ensure correct permissions
|
| 35 |
+
try:
|
| 36 |
+
dir_path.chmod(0o755)
|
| 37 |
+
except Exception:
|
| 38 |
+
pass # Ignore permission errors on some filesystems
|
| 39 |
+
|
| 40 |
+
# For HuggingFace Spaces, we need to work with the current directory
|
| 41 |
+
# since we can't download to a hidden cache directory
|
| 42 |
+
return Path(".")
|
| 43 |
+
else:
|
| 44 |
+
# Local development - use the cache system
|
| 45 |
+
return setup_cache_directory()
|
| 46 |
+
|
| 47 |
+
def setup_cache_directory():
|
| 48 |
+
"""Create a hidden cache directory '.cache' for local development"""
|
| 49 |
+
hidden_cache = Path(".cache")
|
| 50 |
+
public_cache = Path("cache")
|
| 51 |
+
|
| 52 |
+
try:
|
| 53 |
+
if not hidden_cache.exists():
|
| 54 |
+
if public_cache.exists():
|
| 55 |
+
public_cache.rename(hidden_cache)
|
| 56 |
+
else:
|
| 57 |
+
hidden_cache.mkdir(exist_ok=True)
|
| 58 |
+
else:
|
| 59 |
+
hidden_cache.mkdir(exist_ok=True)
|
| 60 |
+
|
| 61 |
+
try:
|
| 62 |
+
hidden_cache.chmod(0o700)
|
| 63 |
+
except Exception:
|
| 64 |
+
pass
|
| 65 |
+
|
| 66 |
+
if sys.platform == "darwin":
|
| 67 |
+
hide_flag = os.environ.get("HIDE_CACHE", "1")
|
| 68 |
+
if hide_flag != "0":
|
| 69 |
+
try:
|
| 70 |
+
os.system(f"/usr/bin/chflags hidden {hidden_cache}")
|
| 71 |
+
except Exception:
|
| 72 |
+
pass
|
| 73 |
+
|
| 74 |
+
return hidden_cache
|
| 75 |
+
except Exception:
|
| 76 |
+
public_cache.mkdir(exist_ok=True)
|
| 77 |
+
return public_cache
|
| 78 |
+
|
| 79 |
+
def download_space(cache_dir):
|
| 80 |
+
"""Download the HuggingFace Space if needed"""
|
| 81 |
+
token = os.environ.get("HF_TOKEN")
|
| 82 |
+
repo_id = os.environ.get("REPO_ID")
|
| 83 |
+
|
| 84 |
+
is_hf_space = bool(os.environ.get("SPACE_ID"))
|
| 85 |
+
|
| 86 |
+
if is_hf_space:
|
| 87 |
+
# On HuggingFace Spaces, the code is already available
|
| 88 |
+
# We just need to ensure the main app file exists
|
| 89 |
+
app_path = cache_dir / "app.py"
|
| 90 |
+
if app_path.exists():
|
| 91 |
+
print("β
App code is already available in HuggingFace Space")
|
| 92 |
+
return True
|
| 93 |
+
else:
|
| 94 |
+
print("β App code not found in HuggingFace Space")
|
| 95 |
+
return False
|
| 96 |
+
|
| 97 |
+
# Local development - download from HuggingFace
|
| 98 |
+
if not token or not repo_id:
|
| 99 |
+
print("β οΈ HF_TOKEN or REPO_ID not set")
|
| 100 |
+
return False
|
| 101 |
+
|
| 102 |
+
try:
|
| 103 |
+
snapshot_download(
|
| 104 |
+
repo_id=repo_id,
|
| 105 |
+
repo_type="space",
|
| 106 |
+
local_dir=cache_dir,
|
| 107 |
+
token=token
|
| 108 |
+
)
|
| 109 |
+
return True
|
| 110 |
+
except Exception as e:
|
| 111 |
+
print(f"β Failed to download space: {e}")
|
| 112 |
+
return False
|
| 113 |
+
|
| 114 |
+
def load_app(cache_dir):
|
| 115 |
+
"""Load the BytePlus app"""
|
| 116 |
+
sys.path.insert(0, str(cache_dir))
|
| 117 |
+
|
| 118 |
+
# Look for the main app file
|
| 119 |
+
app_files = ["app.py", "main.py", "byteplus_app.py"]
|
| 120 |
+
|
| 121 |
+
for app_file in app_files:
|
| 122 |
+
app_path = cache_dir / app_file
|
| 123 |
+
if app_path.exists():
|
| 124 |
+
try:
|
| 125 |
+
spec = importlib.util.spec_from_file_location("app", app_path)
|
| 126 |
+
app = importlib.util.module_from_spec(spec)
|
| 127 |
+
spec.loader.exec_module(app)
|
| 128 |
+
|
| 129 |
+
# Try different ways to get the demo
|
| 130 |
+
if hasattr(app, "demo"):
|
| 131 |
+
return app.demo
|
| 132 |
+
elif hasattr(app, "create_secure_interface"):
|
| 133 |
+
return app.create_secure_interface()
|
| 134 |
+
elif hasattr(app, "main"):
|
| 135 |
+
return app.main()
|
| 136 |
+
|
| 137 |
+
except Exception as e:
|
| 138 |
+
print(f"β οΈ Failed to load {app_file}: {e}")
|
| 139 |
+
continue
|
| 140 |
+
|
| 141 |
+
raise AttributeError("Could not find or load the main app")
|
| 142 |
+
|
| 143 |
+
if __name__ == "__main__":
|
| 144 |
+
print("π Starting BytePlus Image Generation Studio")
|
| 145 |
+
print("π HuggingFace Spaces optimized version")
|
| 146 |
+
|
| 147 |
+
# Setup environment
|
| 148 |
+
cache_dir = setup_huggingface_environment()
|
| 149 |
+
|
| 150 |
+
# Download space if needed (for local development)
|
| 151 |
+
if download_space(cache_dir):
|
| 152 |
+
print("β
App loaded successfully")
|
| 153 |
+
|
| 154 |
+
# For HuggingFace Spaces, run the app directly
|
| 155 |
+
is_hf_space = bool(os.environ.get("SPACE_ID"))
|
| 156 |
+
|
| 157 |
+
if is_hf_space:
|
| 158 |
+
print("π Running in HuggingFace Space mode")
|
| 159 |
+
# Import and run the app directly
|
| 160 |
+
try:
|
| 161 |
+
sys.path.insert(0, str(cache_dir))
|
| 162 |
+
|
| 163 |
+
# Since we're in HF Spaces, the app code should be here
|
| 164 |
+
# Check if there's a main app file in the current directory
|
| 165 |
+
if Path("app.py").exists():
|
| 166 |
+
import app as main_app
|
| 167 |
+
if hasattr(main_app, "demo"):
|
| 168 |
+
main_app.demo.launch()
|
| 169 |
+
elif hasattr(main_app, "launch"):
|
| 170 |
+
main_app.launch()
|
| 171 |
+
else:
|
| 172 |
+
print("β Could not find launch method in app")
|
| 173 |
+
else:
|
| 174 |
+
print("β app.py not found in HuggingFace Space")
|
| 175 |
+
|
| 176 |
+
except Exception as e:
|
| 177 |
+
print(f"β Error running in HuggingFace Space: {e}")
|
| 178 |
+
else:
|
| 179 |
+
# Local development
|
| 180 |
+
demo = load_app(cache_dir)
|
| 181 |
+
demo.launch()
|
| 182 |
+
else:
|
| 183 |
+
print("β Failed to setup app environment")
|
hf_deploy/requirements.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio==5.44.1
|
| 2 |
+
google-genai
|
| 3 |
+
pillow
|
| 4 |
+
websockets
|
| 5 |
+
boto3
|
| 6 |
+
requests
|
| 7 |
+
pydantic==2.10.6
|
hf_deploy/static/README.md
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# static
|
| 2 |
+
|
| 3 |
+
This directory is required for the BytePlus Image Generation Studio.
|
hf_deploy/view_session/README.md
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# view_session
|
| 2 |
+
|
| 3 |
+
This directory is required for the BytePlus Image Generation Studio.
|
hf_spaces_startup.py
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
HuggingFace Spaces startup script
|
| 4 |
+
This ensures all necessary directories exist when deployed to HF Spaces
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import sys
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
|
| 11 |
+
def ensure_hf_directories():
|
| 12 |
+
"""Ensure all necessary directories exist for HuggingFace Spaces"""
|
| 13 |
+
|
| 14 |
+
print("π HuggingFace Spaces - Setting up directories...")
|
| 15 |
+
|
| 16 |
+
# Essential directories that must exist
|
| 17 |
+
essential_dirs = [
|
| 18 |
+
"Generated",
|
| 19 |
+
"static",
|
| 20 |
+
"view_session"
|
| 21 |
+
]
|
| 22 |
+
|
| 23 |
+
for dir_name in essential_dirs:
|
| 24 |
+
dir_path = Path(dir_name)
|
| 25 |
+
if not dir_path.exists():
|
| 26 |
+
dir_path.mkdir(exist_ok=True, mode=0o755)
|
| 27 |
+
print(f"β
Created: {dir_name}/")
|
| 28 |
+
else:
|
| 29 |
+
# Ensure correct permissions
|
| 30 |
+
try:
|
| 31 |
+
dir_path.chmod(0o755)
|
| 32 |
+
print(f"β
Verified: {dir_name}/")
|
| 33 |
+
except Exception:
|
| 34 |
+
pass
|
| 35 |
+
|
| 36 |
+
print("β
All essential directories ready for HuggingFace Spaces")
|
| 37 |
+
|
| 38 |
+
# Run directory setup immediately when this module is imported
|
| 39 |
+
ensure_hf_directories()
|
| 40 |
+
|
| 41 |
+
# Import the main app
|
| 42 |
+
if __name__ == "__main__":
|
| 43 |
+
# This will be the main entry point for HuggingFace Spaces
|
| 44 |
+
print("π Starting BytePlus Image Generation Studio on HuggingFace Spaces")
|
| 45 |
+
|
| 46 |
+
# Import and run the main app
|
| 47 |
+
try:
|
| 48 |
+
# The main app code should be in app.py in the HF Space
|
| 49 |
+
import app as main_app
|
| 50 |
+
|
| 51 |
+
# The app should have a demo object that can be launched
|
| 52 |
+
if hasattr(main_app, "demo"):
|
| 53 |
+
print("β
Found demo object, launching...")
|
| 54 |
+
main_app.demo.launch()
|
| 55 |
+
elif hasattr(main_app, "create_interface"):
|
| 56 |
+
print("β
Found create_interface function, launching...")
|
| 57 |
+
demo = main_app.create_interface()
|
| 58 |
+
demo.launch()
|
| 59 |
+
else:
|
| 60 |
+
print("β Could not find demo or create_interface in app.py")
|
| 61 |
+
|
| 62 |
+
except ImportError as e:
|
| 63 |
+
print(f"β Could not import app.py: {e}")
|
| 64 |
+
except Exception as e:
|
| 65 |
+
print(f"β Error launching app: {e}")
|
prepare_hf_deployment.py
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Deploy BytePlus Image Generation Studio to HuggingFace Spaces
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import os
|
| 7 |
+
import shutil
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
|
| 10 |
+
def prepare_hf_deployment():
|
| 11 |
+
"""Prepare the app for HuggingFace Spaces deployment"""
|
| 12 |
+
|
| 13 |
+
print("π Preparing BytePlus Image Generation Studio for HuggingFace Spaces")
|
| 14 |
+
print("=" * 60)
|
| 15 |
+
|
| 16 |
+
# Create deployment directory
|
| 17 |
+
deploy_dir = Path("hf_deploy")
|
| 18 |
+
if deploy_dir.exists():
|
| 19 |
+
shutil.rmtree(deploy_dir)
|
| 20 |
+
deploy_dir.mkdir()
|
| 21 |
+
|
| 22 |
+
print(f"π Created deployment directory: {deploy_dir}")
|
| 23 |
+
|
| 24 |
+
# Files to copy to HuggingFace
|
| 25 |
+
files_to_copy = [
|
| 26 |
+
"hf_app.py", # This will be the main app file
|
| 27 |
+
"requirements.txt",
|
| 28 |
+
".gitattributes"
|
| 29 |
+
]
|
| 30 |
+
|
| 31 |
+
# Copy essential files
|
| 32 |
+
for file in files_to_copy:
|
| 33 |
+
if Path(file).exists():
|
| 34 |
+
shutil.copy2(file, deploy_dir / file)
|
| 35 |
+
print(f"β
Copied: {file}")
|
| 36 |
+
else:
|
| 37 |
+
print(f"β οΈ Missing: {file}")
|
| 38 |
+
|
| 39 |
+
# Copy the actual app.py from cache if it exists
|
| 40 |
+
cache_app = Path(".cache/app.py")
|
| 41 |
+
if cache_app.exists():
|
| 42 |
+
shutil.copy2(cache_app, deploy_dir / "app.py")
|
| 43 |
+
print("β
Copied: BytePlus app.py from cache")
|
| 44 |
+
else:
|
| 45 |
+
print("β οΈ BytePlus app.py not found in cache")
|
| 46 |
+
|
| 47 |
+
# Create essential directories with README files
|
| 48 |
+
dirs_to_create = ["Generated", "static", "view_session", "Assets"]
|
| 49 |
+
|
| 50 |
+
for dir_name in dirs_to_create:
|
| 51 |
+
target_dir = deploy_dir / dir_name
|
| 52 |
+
target_dir.mkdir(exist_ok=True)
|
| 53 |
+
|
| 54 |
+
# Copy README if it exists
|
| 55 |
+
readme_file = Path(dir_name) / "README.md"
|
| 56 |
+
if readme_file.exists():
|
| 57 |
+
shutil.copy2(readme_file, target_dir / "README.md")
|
| 58 |
+
print(f"β
Created directory with README: {dir_name}")
|
| 59 |
+
else:
|
| 60 |
+
# Create a basic README
|
| 61 |
+
with open(target_dir / "README.md", "w") as f:
|
| 62 |
+
f.write(f"# {dir_name}\n\nThis directory is required for the BytePlus Image Generation Studio.\n")
|
| 63 |
+
print(f"β
Created directory: {dir_name}")
|
| 64 |
+
|
| 65 |
+
# Copy Assets if they exist
|
| 66 |
+
assets_dir = Path("Assets")
|
| 67 |
+
if assets_dir.exists():
|
| 68 |
+
shutil.copytree(assets_dir, deploy_dir / "Assets", dirs_exist_ok=True)
|
| 69 |
+
print("β
Copied Assets directory")
|
| 70 |
+
|
| 71 |
+
# Create HuggingFace specific README.md
|
| 72 |
+
hf_readme_content = """# BytePlus Image Generation Studio
|
| 73 |
+
|
| 74 |
+
A secure and feature-rich image generation studio powered by BytePlus API.
|
| 75 |
+
|
| 76 |
+
## Features
|
| 77 |
+
|
| 78 |
+
- π¨ Multiple art styles and generation modes
|
| 79 |
+
- π Secure API key management with encryption
|
| 80 |
+
- π Session-based image organization
|
| 81 |
+
- π₯ ZIP download functionality
|
| 82 |
+
- ποΈ Interactive session viewer
|
| 83 |
+
- π‘οΈ Rate limiting and abuse prevention
|
| 84 |
+
- π± Responsive web interface
|
| 85 |
+
|
| 86 |
+
## Usage
|
| 87 |
+
|
| 88 |
+
1. Enter your BytePlus API key in the interface
|
| 89 |
+
2. Choose your preferred settings (style, size, etc.)
|
| 90 |
+
3. Enter a prompt or upload an image
|
| 91 |
+
4. Generate images and view them in the gallery
|
| 92 |
+
5. Use the session viewer to see all images from a generation session
|
| 93 |
+
|
| 94 |
+
## Session Viewer
|
| 95 |
+
|
| 96 |
+
Click the "ποΈ View" button next to any session in the history to open a dedicated gallery view showing all images from that session.
|
| 97 |
+
|
| 98 |
+
## Security Features
|
| 99 |
+
|
| 100 |
+
- Encrypted API key storage
|
| 101 |
+
- Input validation and sanitization
|
| 102 |
+
- Rate limiting (20 requests/minute)
|
| 103 |
+
- Secure error handling
|
| 104 |
+
- Image validation and size limits
|
| 105 |
+
|
| 106 |
+
## Directories
|
| 107 |
+
|
| 108 |
+
- `Generated/`: Stores generated images organized by session
|
| 109 |
+
- `static/`: Serves static files and ZIP downloads
|
| 110 |
+
- `view_session/`: Supports the session viewing functionality
|
| 111 |
+
- `Assets/`: Contains sample images and resources
|
| 112 |
+
"""
|
| 113 |
+
|
| 114 |
+
with open(deploy_dir / "README.md", "w") as f:
|
| 115 |
+
f.write(hf_readme_content)
|
| 116 |
+
print("β
Created HuggingFace README.md")
|
| 117 |
+
|
| 118 |
+
# Create .gitignore for HuggingFace
|
| 119 |
+
hf_gitignore = """# Environment files
|
| 120 |
+
.env
|
| 121 |
+
|
| 122 |
+
# Python cache
|
| 123 |
+
__pycache__/
|
| 124 |
+
*.pyc
|
| 125 |
+
*.pyo
|
| 126 |
+
*.pyd
|
| 127 |
+
.Python
|
| 128 |
+
*.so
|
| 129 |
+
|
| 130 |
+
# Generated content (but keep directories)
|
| 131 |
+
Generated/*.jpg
|
| 132 |
+
Generated/*.png
|
| 133 |
+
Generated/*.zip
|
| 134 |
+
static/*.zip
|
| 135 |
+
static/*.jpg
|
| 136 |
+
static/*.png
|
| 137 |
+
|
| 138 |
+
# Logs
|
| 139 |
+
*.log
|
| 140 |
+
|
| 141 |
+
# OS files
|
| 142 |
+
.DS_Store
|
| 143 |
+
Thumbs.db
|
| 144 |
+
"""
|
| 145 |
+
|
| 146 |
+
with open(deploy_dir / ".gitignore", "w") as f:
|
| 147 |
+
f.write(hf_gitignore)
|
| 148 |
+
print("β
Created HuggingFace .gitignore")
|
| 149 |
+
|
| 150 |
+
print("\n" + "=" * 60)
|
| 151 |
+
print("β
Deployment preparation complete!")
|
| 152 |
+
print(f"π Deployment files ready in: {deploy_dir}")
|
| 153 |
+
print("\nπ Next steps:")
|
| 154 |
+
print("1. Create a new HuggingFace Space")
|
| 155 |
+
print("2. Upload all files from hf_deploy/ directory")
|
| 156 |
+
print("3. Set environment variables:")
|
| 157 |
+
print(" - HF_TOKEN (your HuggingFace token)")
|
| 158 |
+
print(" - REPO_ID (if needed)")
|
| 159 |
+
print("4. The app will automatically create necessary directories")
|
| 160 |
+
print("\nπ The Generated, static, and view_session directories will be")
|
| 161 |
+
print(" created automatically when the Space starts!")
|
| 162 |
+
|
| 163 |
+
if __name__ == "__main__":
|
| 164 |
+
prepare_hf_deployment()
|