Spaces:
Running
Running
File size: 6,510 Bytes
1e5eb40 1579e31 67e6ea6 18d0b22 1579e31 67e6ea6 1579e31 67e6ea6 1579e31 18d0b22 b257fdf 67e6ea6 1579e31 67e6ea6 1579e31 67e6ea6 18d0b22 90bdafc 18d0b22 90bdafc 67e6ea6 18d0b22 90bdafc 67e6ea6 18d0b22 90bdafc 18d0b22 46001b0 67e6ea6 46001b0 18d0b22 90bdafc 18d0b22 90bdafc 46001b0 67e6ea6 46001b0 90bdafc 18d0b22 90bdafc 46001b0 67e6ea6 46001b0 90bdafc 18d0b22 90bdafc 18d0b22 e9dd265 46001b0 67e6ea6 46001b0 8cc42bf 18d0b22 90bdafc 1579e31 1890cbb 67e6ea6 1890cbb 18d0b22 b257fdf 67e6ea6 1e5eb40 18d0b22 c08b935 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
from flask import Flask, request, jsonify, Response
import os
import json
from huggingface_hub import HfApi, create_repo, upload_file
import random
import string
from flask_httpauth import HTTPTokenAuth
# Import documentation from assembler_docs.py
from assembler_docs import DOCUMENTATION
app = Flask(__name__)
# Set up HTTP Token Authentication
auth = HTTPTokenAuth(scheme='Bearer')
# Hugging Face API token (set in Space settings or provided in request)
HF_TOKEN = os.getenv("HF_TOKEN")
if not HF_TOKEN:
raise ValueError("HF_TOKEN not set. Add it in Space settings.")
hf_api = HfApi()
# Authentication function to validate the token
@auth.verify_token
def verify_token(token):
if not token:
return False
try:
# Attempt to verify the token by checking if it can access the user's profile or Space-Share
user_info = hf_api.whoami(token=token)
# Optionally, check if the token has write access to Space-Share
# This is a basic check; you might want to add more specific permission checks
return bool(user_info and "Space-Share" in user_info.get('orgs', [])) or token == HF_TOKEN
except Exception:
return False
def generate_space_name():
"""Generate a unique Space name."""
random_suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6))
return f"GeneratedSpace-{random_suffix}"
@app.route('/create-space', methods=['POST'])
@auth.login_required
def create_hf_space():
try:
# Use the authenticated token for Hugging Face operations
token = auth.current_user()
hf_api = HfApi(token=token)
# Parse JSON input
data = request.get_json()
if not data:
return jsonify({"error": "No JSON data provided"}), 401
# Extract parameters
space_type = data.get("space_type", "gradio") # Default to gradio if not specified
files = data.get("files", {}) # Dictionary of filename: content
params = data.get("parameters", {}) # Optional parameters
if not files:
return jsonify({"error": "No files provided in JSON"}), 401
# Validate space_type
valid_space_types = ["gradio", "static", "docker", "streamlit"]
if space_type not in valid_space_types:
return jsonify({"error": f"Invalid space_type. Must be one of {valid_space_types}"}), 401
# Create a unique Space name and repo under Space-Share namespace
space_name = generate_space_name()
full_repo_id = f"Space-Share/{space_name}"
try:
# Attempt to create the repository
repo_info = create_repo(
repo_id=space_name,
repo_type="space",
space_sdk=space_type,
token=token,
private=False,
exist_ok=True # Allow creation even if the repo might exist (rare case)
)
except Exception as e:
return jsonify({"error": f"Failed to create repository: {str(e)}"}), 500
# Handle multi-file uploads
for filename, content in files.items():
# Write content to a temporary file
with open(f"temp_{filename}", "w") as f:
if filename.endswith(".py"):
# Inject parameters into Python files if present
content = f"PARAMS = {json.dumps(params)}\n\n{content}"
f.write(content)
# Upload to the new Space
try:
upload_file(
path_or_fileobj=f"temp_{filename}",
path_in_repo=filename,
repo_id=full_repo_id,
repo_type="space",
token=token
)
except Exception as e:
os.remove(f"temp_{filename}")
return jsonify({"error": f"Failed to upload file {filename}: {str(e)}"}), 500
os.remove(f"temp_{filename}")
# Add requirements.txt if not provided (basic defaults)
if "requirements.txt" not in files:
default_requirements = {
"gradio": "gradio",
"static": "",
"docker": "flask", # Example; adjust based on needs
"streamlit": "streamlit"
}.get(space_type, "")
with open("temp_requirements.txt", "w") as f:
f.write(default_requirements)
try:
upload_file(
path_or_fileobj="temp_requirements.txt",
path_in_repo="requirements.txt",
repo_id=full_repo_id,
repo_type="space",
token=token
)
except Exception as e:
os.remove("temp_requirements.txt")
return jsonify({"error": f"Failed to upload requirements.txt: {str(e)}"}), 500
os.remove("temp_requirements.txt")
# Special handling for Docker Spaces
if space_type == "docker" and "Dockerfile" not in files:
default_dockerfile = """
FROM python:3.10-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
EXPOSE 7860
CMD ["python", "app.py"]
"""
with open("temp_Dockerfile", "w") as f:
f.write(default_dockerfile)
try:
upload_file(
path_or_fileobj="temp_Dockerfile",
path_in_repo="Dockerfile",
repo_id=full_repo_id,
repo_type="space",
token=token
)
except Exception as e:
os.remove("temp_Dockerfile")
return jsonify({"error": f"Failed to upload Dockerfile: {str(e)}"}), 500
os.remove("temp_Dockerfile")
space_url = f"https://huggingface.co/spaces/Space-Share/{space_name}"
return jsonify({
"message": "New Space created",
"url": space_url,
"note": "It may take a few minutes to build and deploy."
}), 200
except json.JSONDecodeError:
return jsonify({"error": "Invalid JSON format"}), 401
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.route('/docs', methods=['GET'])
@auth.login_required
def get_docs():
"""Return the API documentation as plain text."""
return Response(DOCUMENTATION, mimetype='text/plain'), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860) |