File size: 8,742 Bytes
f723f6c
8a2f1bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f723f6c
8a2f1bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f723f6c
8a2f1bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f723f6c
8a2f1bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f723f6c
8a2f1bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
DOCUMENTATION = """# Assembler Space API Documentation

## Overview
The **Assembler Space** is a Hugging Face Space that acts as a factory for creating new Hugging Face Spaces dynamically. It exposes a Flask-based API that accepts JSON input containing code, files, parameters, and configuration details. Upon receiving a valid request, it creates a new Space repository on Hugging Face, populates it with the provided files, and triggers its deployment. The API supports multiple Space types (e.g., `gradio`, `static`, `docker`, `streamlit`) and multi-file submissions, making it versatile for generating a wide range of applications.

The Assembler Space itself runs as a Docker-based Space on Hugging Face, accessible via a public URL: `https://broadfield-dev-assembler.hf.space`.

## Base URL
The API is hosted at:
https://broadfield-dev-assembler.hf.space/create-space

## Endpoints

### `POST /create-space`
Creates a new Hugging Face Space based on the provided JSON payload.

#### Request Format
- **Method**: `POST`
- **Content-Type**: `application/json`
- **Body**: A JSON object with the following fields:

| Field        | Type     | Required | Description                                                                 |
|--------------|----------|----------|-----------------------------------------------------------------------------|
| `space_type` | String   | No       | The type of Space to create. Options: `gradio`, `static`, `docker`, `streamlit`. Defaults to `gradio` if omitted. |
| `files`      | Object   | Yes      | A dictionary where keys are filenames (e.g., `app.py`, `index.html`) and values are file contents as strings. |
| `parameters` | Object   | No       | A dictionary of key-value pairs to be injected into Python files as `PARAMS` or used by the generated Space’s code. |

#### Request Constraints
- At least one file must be provided in `files`.
- Filenames in `files` should include extensions (e.g., `.py`, `.html`, `.css`, `.txt`) to ensure correct handling.
- `space_type` must match one of the supported values, or the request will fail.
- File contents should be valid for the intended `space_type` (e.g., Python code for `gradio` or `docker`, HTML for `static`).

#### Response Format
- **Content-Type**: `application/json`
- **Status Codes**:
  - `200 OK`: Space creation succeeded.
  - `400 Bad Request`: Invalid JSON or missing/invalid fields.
  - `500 Internal Server Error`: Unexpected error during Space creation.
- **Body**: A JSON object with the following fields:

| Field     | Type   | Description                                                                 |
|-----------|--------|-----------------------------------------------------------------------------|
| `message` | String | A brief status message (e.g., `"New Space created"`).                      |
| `url`     | String | The URL of the newly created Space (e.g., `https://huggingface.co/spaces/Space-Share/<space-name>`). |
| `note`    | String | Additional information (e.g., deployment time warning).                    |
| `error`   | String | (Only in error responses) Description of what went wrong.                  |

### `GET /docs`
Returns this documentation as plain text in Markdown format.

#### Request Format
- **Method**: `GET`
- **Content-Type**: None required

#### Response Format
- **Content-Type**: `text/plain`
- **Status Codes**:
  - `200 OK`: Documentation returned successfully.
- **Body**: The full Markdown documentation as a string.

#### Example Requests and Responses

##### Example 1: Static Space
**Request (`POST /create-space`):**
~~~json
{
  "space_type": "static",
  "files": {
    "index.html": "<html><body><h1>Hello World</h1><p>Message: {{params['message']}}</p></body></html>",
    "style.css": "h1 { color: green; }"
  },
  "parameters": {
    "message": "Static Space Test"
  }
}
~~~

**Response (200 OK):**
~~~json
{
  "message": "New Space created",
  "url": "https://huggingface.co/spaces/Space-Share/GeneratedSpace-abc123",
  "note": "It may take a few minutes to build and deploy."
}
~~~

**Notes:**
- Static Spaces don’t automatically process `parameters`. The new Space’s code must handle them (e.g., via JavaScript or server-side templating if added).

##### Example 2: Docker Space with Flask
**Request (`POST /create-space`):**
~~~json
{
  "space_type": "docker",
  "files": {
    "app.py": "from flask import Flask\\napp = Flask(__name__)\\[email protected]('/')\\ndef home():\\n    return f'Hello, {PARAMS['name']}'\\nif __name__ == '__main__':\\n    app.run(host='0.0.0.0', port=7860)",
    "requirements.txt": "flask",
    "Dockerfile": "FROM python:3.10-slim\\nWORKDIR /app\\nCOPY . .\\nRUN pip install -r requirements.txt\\nEXPOSE 7860\\nCMD [\\"python\\", \\"app.py\\"]"
  },
  "parameters": {
    "name": "Docker User"
  }
}
~~~

**Response (200 OK):**
~~~json
{
  "message": "New Space created",
  "url": "https://huggingface.co/spaces/Space-Share/GeneratedSpace-xyz789",
  "note": "It may take a few minutes to build and deploy."
}
~~~

**Notes:**
- The `parameters` are injected into `app.py` as `PARAMS`. The port is set to 7860 to match Hugging Face’s default.

##### Example 3: Gradio Space
**Request (`POST /create-space`):**
~~~json
{
  "space_type": "gradio",
  "files": {
    "app.py": "import gradio as gr\\ndef greet():\\n    return f'Hi, {PARAMS['user']}'\\ninterface = gr.Interface(fn=greet, inputs=None, outputs='text')\\ninterface.launch()"
  },
  "parameters": {
    "user": "Gradio Fan"
  }
}
~~~

**Response (200 OK):**
~~~json
{
  "message": "New Space created",
  "url": "https://huggingface.co/spaces/Space-Share/GeneratedSpace-def456",
  "note": "It may take a few minutes to build and deploy."
}
~~~

##### Example 4: Invalid Request
**Request (`POST /create-space`):**
~~~json
{
  "space_type": "invalid",
  "files": {}
}
~~~

**Response (400 Bad Request):**
~~~json
{
  "error": "Invalid space_type. Must be one of ['gradio', 'static', 'docker', 'streamlit']"
}
~~~

##### Example 5: Get Documentation
**Request (`GET /docs`):**
GET https://broadfield-dev-assembler.hf.space/docs

**Response (200 OK):**
<The full Markdown text of this documentation>
```

Usage Example (Python)
Here’s how to call the API using Python’s requests library:
python
import requests

# Create a new Space
url = "https://broadfield-dev-assembler.hf.space/create-space"
payload = {
    "space_type": "static",
    "files": {
        "index.html": "<html><body><h1>Test Page</h1></body></html>"
    },
    "parameters": {
        "key": "value"
    }
}
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload)
if response.status_code == 200:
    print("Success:", response.json())
else:
    print("Error:", response.status_code, response.json())

# Fetch documentation
docs_url = "https://broadfield-dev-assembler.hf.space/docs"
docs_response = requests.get(docs_url)
if docs_response.status_code == 200:
    print("Documentation:", docs_response.text)
Additional Details
Supported Space Types
gradio: For interactive Python apps using the Gradio framework. Requires an app.py with Gradio code.
static: For static websites. Requires at least an index.html file; supports additional files like style.css.
docker: For custom apps (e.g., Flask, FastAPI). Requires a Dockerfile or uses a default one if omitted.
streamlit: For Streamlit apps. Requires an app.py with Streamlit code.
File Handling
Python Files (.py): The parameters object is injected as a global PARAMS variable at the top of the file.
Other Files: Contents are uploaded as-is; no automatic parameter injection (e.g., HTML files need custom logic to use parameters).
Requirements: If requirements.txt isn’t provided, a default is generated based on space_type (e.g., gradio for Gradio, flask for Docker).
Deployment Notes
Build Time: New Spaces take 1-5 minutes to build and deploy on Hugging Face. The API returns immediately with a URL, but the Space won’t be live until the build completes.
Port for Docker: Hugging Face expects Docker Spaces to listen on port 7860. Ensure your Dockerfile and app code align with this (see Example 2).
Security Considerations
The Assembler doesn’t execute the provided code; it only creates a new Space. However, ensure the generated Space’s code is safe if deploying publicly.
Avoid sending sensitive data in parameters unless the new Space is private (not implemented here but can be adjusted).
Limitations
Rate Limits: Hugging Face may restrict frequent Space creation. Check their API documentation for quotas.
File Size: Large files may fail to upload; keep contents reasonable (e.g., <1MB per file).
Error Handling: Basic validation is included, but complex syntax checking isn’t performed.
"""