broadfield-dev commited on
Commit
1579e31
·
verified ·
1 Parent(s): 7172db0

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +127 -0
app.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify
2
+ import os
3
+ import json
4
+ from huggingface_hub import HfApi, create_repo, upload_file
5
+ import random
6
+ import string
7
+
8
+ app = Flask(__name__)
9
+
10
+ # Hugging Face API token (set in Space settings)
11
+ HF_TOKEN = os.getenv("HF_TOKEN")
12
+ if not HF_TOKEN:
13
+ raise ValueError("HF_TOKEN not set. Add it in Space settings.")
14
+
15
+ hf_api = HfApi()
16
+
17
+ def generate_space_name():
18
+ """Generate a unique Space name."""
19
+ random_suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6))
20
+ return f"GeneratedSpace-{random_suffix}"
21
+
22
+ @app.route('/create-space', methods=['POST'])
23
+ def create_hf_space():
24
+ try:
25
+ # Parse JSON input
26
+ data = request.get_json()
27
+ if not data:
28
+ return jsonify({"error": "No JSON data provided"}), 400
29
+
30
+ # Extract parameters
31
+ space_type = data.get("space_type", "gradio") # Default to gradio if not specified
32
+ files = data.get("files", {}) # Dictionary of filename: content
33
+ params = data.get("parameters", {}) # Optional parameters
34
+
35
+ if not files:
36
+ return jsonify({"error": "No files provided in JSON"}), 400
37
+
38
+ # Validate space_type
39
+ valid_space_types = ["gradio", "static", "docker", "streamlit"]
40
+ if space_type not in valid_space_types:
41
+ return jsonify({"error": f"Invalid space_type. Must be one of {valid_space_types}"}), 400
42
+
43
+ # Create a unique Space name and repo
44
+ space_name = generate_space_name()
45
+ full_repo_id = f"{hf_api.whoami(HF_TOKEN)['name']}/{space_name}"
46
+
47
+ create_repo(
48
+ repo_id=space_name,
49
+ repo_type="space",
50
+ space_sdk=space_type,
51
+ token=HF_TOKEN,
52
+ private=False
53
+ )
54
+
55
+ # Handle multi-file uploads
56
+ for filename, content in files.items():
57
+ # Write content to a temporary file
58
+ with open(f"temp_{filename}", "w") as f:
59
+ if filename.endswith(".py"):
60
+ # Inject parameters into Python files if present
61
+ content = f"PARAMS = {json.dumps(params)}\n\n{content}"
62
+ f.write(content)
63
+
64
+ # Upload to the new Space
65
+ upload_file(
66
+ path_or_fileobj=f"temp_{filename}",
67
+ path_in_repo=filename,
68
+ repo_id=full_repo_id,
69
+ repo_type="space",
70
+ token=HF_TOKEN
71
+ )
72
+ os.remove(f"temp_{filename}")
73
+
74
+ # Add requirements.txt if not provided (basic defaults)
75
+ if "requirements.txt" not in files:
76
+ default_requirements = {
77
+ "gradio": "gradio",
78
+ "static": "",
79
+ "docker": "flask", # Example; adjust based on needs
80
+ "streamlit": "streamlit"
81
+ }.get(space_type, "")
82
+ with open("temp_requirements.txt", "w") as f:
83
+ f.write(default_requirements)
84
+ upload_file(
85
+ path_or_fileobj="temp_requirements.txt",
86
+ path_in_repo="requirements.txt",
87
+ repo_id=full_repo_id,
88
+ repo_type="space",
89
+ token=HF_TOKEN
90
+ )
91
+ os.remove("temp_requirements.txt")
92
+
93
+ # Special handling for Docker Spaces
94
+ if space_type == "docker" and "Dockerfile" not in files:
95
+ default_dockerfile = """
96
+ FROM python:3.10-slim
97
+ WORKDIR /app
98
+ COPY . .
99
+ RUN pip install -r requirements.txt
100
+ EXPOSE 5000
101
+ CMD ["python", "app.py"]
102
+ """
103
+ with open("temp_Dockerfile", "w") as f:
104
+ f.write(default_dockerfile)
105
+ upload_file(
106
+ path_or_fileobj="temp_Dockerfile",
107
+ path_in_repo="Dockerfile",
108
+ repo_id=full_repo_id,
109
+ repo_type="space",
110
+ token=HF_TOKEN
111
+ )
112
+ os.remove("temp_Dockerfile")
113
+
114
+ space_url = f"https://huggingface.co/spaces/{full_repo_id}"
115
+ return jsonify({
116
+ "message": "New Space created",
117
+ "url": space_url,
118
+ "note": "It may take a few minutes to build and deploy."
119
+ }), 200
120
+
121
+ except json.JSONDecodeError:
122
+ return jsonify({"error": "Invalid JSON format"}), 400
123
+ except Exception as e:
124
+ return jsonify({"error": str(e)}), 500
125
+
126
+ if __name__ == '__main__':
127
+ app.run(host='0.0.0.0', port=5000)