Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -4,31 +4,54 @@ import json
|
|
4 |
from huggingface_hub import HfApi, create_repo, upload_file
|
5 |
import random
|
6 |
import string
|
|
|
7 |
|
8 |
# Import documentation from assembler_docs.py
|
9 |
from assembler_docs import DOCUMENTATION
|
10 |
|
11 |
app = Flask(__name__)
|
12 |
|
13 |
-
#
|
|
|
|
|
|
|
14 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
15 |
if not HF_TOKEN:
|
16 |
raise ValueError("HF_TOKEN not set. Add it in Space settings.")
|
17 |
|
18 |
hf_api = HfApi()
|
19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
def generate_space_name():
|
21 |
"""Generate a unique Space name."""
|
22 |
random_suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6))
|
23 |
return f"GeneratedSpace-{random_suffix}"
|
24 |
|
25 |
@app.route('/create-space', methods=['POST'])
|
|
|
26 |
def create_hf_space():
|
27 |
try:
|
|
|
|
|
|
|
|
|
28 |
# Parse JSON input
|
29 |
data = request.get_json()
|
30 |
if not data:
|
31 |
-
return jsonify({"error": "No JSON data provided"}),
|
32 |
|
33 |
# Extract parameters
|
34 |
space_type = data.get("space_type", "gradio") # Default to gradio if not specified
|
@@ -36,12 +59,12 @@ def create_hf_space():
|
|
36 |
params = data.get("parameters", {}) # Optional parameters
|
37 |
|
38 |
if not files:
|
39 |
-
return jsonify({"error": "No files provided in JSON"}),
|
40 |
|
41 |
# Validate space_type
|
42 |
valid_space_types = ["gradio", "static", "docker", "streamlit"]
|
43 |
if space_type not in valid_space_types:
|
44 |
-
return jsonify({"error": f"Invalid space_type. Must be one of {valid_space_types}"}),
|
45 |
|
46 |
# Create a unique Space name and repo under Space-Share namespace
|
47 |
space_name = generate_space_name()
|
@@ -53,7 +76,7 @@ def create_hf_space():
|
|
53 |
repo_id=space_name,
|
54 |
repo_type="space",
|
55 |
space_sdk=space_type,
|
56 |
-
token=
|
57 |
private=False,
|
58 |
exist_ok=True # Allow creation even if the repo might exist (rare case)
|
59 |
)
|
@@ -76,7 +99,7 @@ def create_hf_space():
|
|
76 |
path_in_repo=filename,
|
77 |
repo_id=full_repo_id,
|
78 |
repo_type="space",
|
79 |
-
token=
|
80 |
)
|
81 |
except Exception as e:
|
82 |
os.remove(f"temp_{filename}")
|
@@ -100,7 +123,7 @@ def create_hf_space():
|
|
100 |
path_in_repo="requirements.txt",
|
101 |
repo_id=full_repo_id,
|
102 |
repo_type="space",
|
103 |
-
token=
|
104 |
)
|
105 |
except Exception as e:
|
106 |
os.remove("temp_requirements.txt")
|
@@ -125,7 +148,7 @@ CMD ["python", "app.py"]
|
|
125 |
path_in_repo="Dockerfile",
|
126 |
repo_id=full_repo_id,
|
127 |
repo_type="space",
|
128 |
-
token=
|
129 |
)
|
130 |
except Exception as e:
|
131 |
os.remove("temp_Dockerfile")
|
@@ -140,11 +163,12 @@ CMD ["python", "app.py"]
|
|
140 |
}), 200
|
141 |
|
142 |
except json.JSONDecodeError:
|
143 |
-
return jsonify({"error": "Invalid JSON format"}),
|
144 |
except Exception as e:
|
145 |
return jsonify({"error": str(e)}), 500
|
146 |
|
147 |
@app.route('/docs', methods=['GET'])
|
|
|
148 |
def get_docs():
|
149 |
"""Return the API documentation as plain text."""
|
150 |
return Response(DOCUMENTATION, mimetype='text/plain'), 200
|
|
|
4 |
from huggingface_hub import HfApi, create_repo, upload_file
|
5 |
import random
|
6 |
import string
|
7 |
+
from flask_httpauth import HTTPTokenAuth
|
8 |
|
9 |
# Import documentation from assembler_docs.py
|
10 |
from assembler_docs import DOCUMENTATION
|
11 |
|
12 |
app = Flask(__name__)
|
13 |
|
14 |
+
# Set up HTTP Token Authentication
|
15 |
+
auth = HTTPTokenAuth(scheme='Bearer')
|
16 |
+
|
17 |
+
# Hugging Face API token (set in Space settings or provided in request)
|
18 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
19 |
if not HF_TOKEN:
|
20 |
raise ValueError("HF_TOKEN not set. Add it in Space settings.")
|
21 |
|
22 |
hf_api = HfApi()
|
23 |
|
24 |
+
# Authentication function to validate the token
|
25 |
+
@auth.verify_token
|
26 |
+
def verify_token(token):
|
27 |
+
if not token:
|
28 |
+
return False
|
29 |
+
try:
|
30 |
+
# Attempt to verify the token by checking if it can access the user's profile or Space-Share
|
31 |
+
user_info = hf_api.whoami(token=token)
|
32 |
+
# Optionally, check if the token has write access to Space-Share
|
33 |
+
# This is a basic check; you might want to add more specific permission checks
|
34 |
+
return bool(user_info and "Space-Share" in user_info.get('orgs', [])) or token == HF_TOKEN
|
35 |
+
except Exception:
|
36 |
+
return False
|
37 |
+
|
38 |
def generate_space_name():
|
39 |
"""Generate a unique Space name."""
|
40 |
random_suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6))
|
41 |
return f"GeneratedSpace-{random_suffix}"
|
42 |
|
43 |
@app.route('/create-space', methods=['POST'])
|
44 |
+
@auth.login_required
|
45 |
def create_hf_space():
|
46 |
try:
|
47 |
+
# Use the authenticated token for Hugging Face operations
|
48 |
+
token = auth.current_user()
|
49 |
+
hf_api = HfApi(token=token)
|
50 |
+
|
51 |
# Parse JSON input
|
52 |
data = request.get_json()
|
53 |
if not data:
|
54 |
+
return jsonify({"error": "No JSON data provided"}), 401
|
55 |
|
56 |
# Extract parameters
|
57 |
space_type = data.get("space_type", "gradio") # Default to gradio if not specified
|
|
|
59 |
params = data.get("parameters", {}) # Optional parameters
|
60 |
|
61 |
if not files:
|
62 |
+
return jsonify({"error": "No files provided in JSON"}), 401
|
63 |
|
64 |
# Validate space_type
|
65 |
valid_space_types = ["gradio", "static", "docker", "streamlit"]
|
66 |
if space_type not in valid_space_types:
|
67 |
+
return jsonify({"error": f"Invalid space_type. Must be one of {valid_space_types}"}), 401
|
68 |
|
69 |
# Create a unique Space name and repo under Space-Share namespace
|
70 |
space_name = generate_space_name()
|
|
|
76 |
repo_id=space_name,
|
77 |
repo_type="space",
|
78 |
space_sdk=space_type,
|
79 |
+
token=token,
|
80 |
private=False,
|
81 |
exist_ok=True # Allow creation even if the repo might exist (rare case)
|
82 |
)
|
|
|
99 |
path_in_repo=filename,
|
100 |
repo_id=full_repo_id,
|
101 |
repo_type="space",
|
102 |
+
token=token
|
103 |
)
|
104 |
except Exception as e:
|
105 |
os.remove(f"temp_{filename}")
|
|
|
123 |
path_in_repo="requirements.txt",
|
124 |
repo_id=full_repo_id,
|
125 |
repo_type="space",
|
126 |
+
token=token
|
127 |
)
|
128 |
except Exception as e:
|
129 |
os.remove("temp_requirements.txt")
|
|
|
148 |
path_in_repo="Dockerfile",
|
149 |
repo_id=full_repo_id,
|
150 |
repo_type="space",
|
151 |
+
token=token
|
152 |
)
|
153 |
except Exception as e:
|
154 |
os.remove("temp_Dockerfile")
|
|
|
163 |
}), 200
|
164 |
|
165 |
except json.JSONDecodeError:
|
166 |
+
return jsonify({"error": "Invalid JSON format"}), 401
|
167 |
except Exception as e:
|
168 |
return jsonify({"error": str(e)}), 500
|
169 |
|
170 |
@app.route('/docs', methods=['GET'])
|
171 |
+
@auth.login_required
|
172 |
def get_docs():
|
173 |
"""Return the API documentation as plain text."""
|
174 |
return Response(DOCUMENTATION, mimetype='text/plain'), 200
|