kspchary commited on
Commit
fbfef4d
·
verified ·
1 Parent(s): 4763c0a

Upload 5 files

Browse files
Files changed (5) hide show
  1. Dockerfile +21 -0
  2. README.md +43 -10
  3. app.py +87 -0
  4. index.html +287 -0
  5. requirements.txt +6 -0
Dockerfile ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use official Python image
2
+ FROM python:3.10-slim
3
+
4
+ # Set working directory
5
+ WORKDIR /app
6
+
7
+ # Install dependencies
8
+ COPY requirements.txt .
9
+ RUN pip install --no-cache-dir -r requirements.txt
10
+
11
+ # Copy application code
12
+ COPY . .
13
+
14
+ # Set environment variables
15
+ ENV PORT=7860
16
+
17
+ # Expose the port HF Spaces uses
18
+ EXPOSE 7860
19
+
20
+ # Run the application
21
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,10 +1,43 @@
1
- ---
2
- title: Deep
3
- emoji: 💻
4
- colorFrom: purple
5
- colorTo: gray
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Vibe Coding Backend (DeepSeek)
2
+
3
+ This is a premium FastAPI backend designed for "Vibe Coding" applications. It proxies requests to the DeepSeek API while maintaining high performance and security.
4
+
5
+ ## Deployment on Hugging Face Spaces (100% FREE)
6
+
7
+ This backend uses the **Hugging Face Serverless Inference API**, which means you don't pay for tokens or GPU time. It is 100% free.
8
+
9
+ 1. **Create a New Space**:
10
+ - Go to [huggingface.co/new-space](https://huggingface.co/new-space).
11
+ - Select **Docker** as the SDK.
12
+ - Choose a name (e.g., `vibe-coding-free`).
13
+
14
+ 2. **Add Files**:
15
+ - Upload `app.py`, `index.html`, `Dockerfile`, and `requirements.txt`.
16
+
17
+ 3. **Set your FREE Token**:
18
+ - In your Space's **Settings**, go to **Variables and Secrets**.
19
+ - Add a new **Secret**:
20
+ - Key: `HF_TOKEN`
21
+ - Value: your_hf_token (Get it for free at [huggingface.co/settings/tokens](https://huggingface.co/settings/tokens))
22
+
23
+ 4. **API Usage**:
24
+ - Your backend will be available at `https://your-username-vibe-coding-backend.hf.space`.
25
+ - Use the `/vibe` endpoint with a POST request to generate code.
26
+
27
+ ## Example Request (JSON)
28
+
29
+ ```json
30
+ {
31
+ "messages": [
32
+ {"role": "user", "content": "Make a beautiful landing page for a SaaS product."}
33
+ ],
34
+ "model": "deepseek-chat",
35
+ "stream": true
36
+ }
37
+ ```
38
+
39
+ ## Features
40
+ - **Streaming Support**: Get real-time code generation.
41
+ - **Vibe Prompting**: Injected system prompt for high-quality, full-stack generations.
42
+ - **CORS Enabled**: Ready to be called from any frontend.
43
+ - **Scalable**: Built with FastAPI and asynchronous processing to handle numerous concurrent users.
app.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ from fastapi import FastAPI, Request, HTTPException
4
+ from fastapi.responses import StreamingResponse, HTMLResponse
5
+ from fastapi.middleware.cors import CORSMiddleware
6
+ from pydantic import BaseModel
7
+ from typing import List, Optional
8
+ from huggingface_hub import AsyncInferenceClient
9
+ from dotenv import load_dotenv
10
+
11
+ load_dotenv()
12
+
13
+ app = FastAPI(title="Vibe Coding Backend - 100% Free Edition")
14
+
15
+ # Enable CORS
16
+ app.add_middleware(
17
+ CORSMiddleware,
18
+ allow_origins=["*"],
19
+ allow_credentials=True,
20
+ allow_methods=["*"],
21
+ allow_headers=["*"],
22
+ )
23
+
24
+ # Initialize Hugging Face Inference Client (100% Free)
25
+ # User needs a FREE HF Token from huggingface.co/settings/tokens
26
+ HF_TOKEN = os.getenv("HF_TOKEN")
27
+ # Model: DeepSeek-Coder-V2-Lite-Instruct (Very powerful and free on HF API)
28
+ MODEL_ID = "deepseek-ai/DeepSeek-Coder-V2-Lite-Instruct"
29
+
30
+ client = AsyncInferenceClient(model=MODEL_ID, token=HF_TOKEN)
31
+
32
+ class Message(BaseModel):
33
+ role: str
34
+ content: str
35
+
36
+ class ChatRequest(BaseModel):
37
+ messages: List[Message]
38
+ stream: bool = True
39
+ temperature: float = 0.6
40
+ max_tokens: int = 4096
41
+
42
+ VIBE_SYSTEM_PROMPT = """You are the ultimate 'Vibe Coder'. Your purpose is to build entire, high-end web applications from top to bottom in a single response.
43
+ When a user gives you a 'vibe' or a concept:
44
+ 1. Write 100% complete, functional code (HTML, CSS, JS).
45
+ 2. Use modern, premium aesthetics: Glassmorphism, deep gradients, silky animations (Framer Motion style), and high-end typography (Inter/Outfit).
46
+ 3. Do not use placeholders. If you need images, use Unsplash URLs.
47
+ 4. Structure the code so it's ready to be copied into a single file or a clean project structure.
48
+ 5. Be bold. Be creative. Make it look like a $100k startup design."""
49
+
50
+ @app.get("/", response_class=HTMLResponse)
51
+ async def root():
52
+ with open("index.html", "r") as f:
53
+ return f.read()
54
+
55
+ @app.post("/vibe")
56
+ async def vibe_coding(request: ChatRequest):
57
+ """
58
+ 100% Free Vibe Coding using Hugging Face Serverless API.
59
+ """
60
+ # Inject Vibe System Prompt
61
+ messages = [{"role": "system", "content": VIBE_SYSTEM_PROMPT}]
62
+ for msg in request.messages:
63
+ messages.append({"role": msg.role, "content": msg.content})
64
+
65
+ async def stream_generator():
66
+ try:
67
+ # Using HF's free streaming capability
68
+ stream = await client.chat_completion(
69
+ messages=messages,
70
+ max_tokens=request.max_tokens,
71
+ stream=True,
72
+ temperature=request.temperature,
73
+ )
74
+
75
+ async for chunk in stream:
76
+ content = chunk.choices[0].delta.content
77
+ if content:
78
+ yield f"data: {json.dumps({'content': content})}\n\n"
79
+ except Exception as e:
80
+ yield f"data: {json.dumps({'error': str(e)})}\n\n"
81
+
82
+ return StreamingResponse(stream_generator(), media_type="text/event-stream")
83
+
84
+ if __name__ == "__main__":
85
+ import uvicorn
86
+ port = int(os.getenv("PORT", 7860))
87
+ uvicorn.run(app, host="0.0.0.0", port=port)
index.html ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Vibe Coding | Create Anything</title>
8
+ <link
9
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Fira+Code:wght@400;500&display=swap"
10
+ rel="stylesheet">
11
+ <style>
12
+ :root {
13
+ --bg: #03040b;
14
+ --sidebar: #0a0b14;
15
+ --accent: #3b82f6;
16
+ --accent-glow: rgba(59, 130, 246, 0.4);
17
+ --text: #f8fafc;
18
+ --text-dim: #94a3b8;
19
+ --border: rgba(255, 255, 255, 0.08);
20
+ --glass: rgba(15, 23, 42, 0.8);
21
+ }
22
+
23
+ * {
24
+ box-sizing: border-box;
25
+ margin: 0;
26
+ padding: 0;
27
+ }
28
+
29
+ body {
30
+ font-family: 'Inter', sans-serif;
31
+ background-color: var(--bg);
32
+ color: var(--text);
33
+ height: 100vh;
34
+ display: flex;
35
+ flex-direction: column;
36
+ overflow: hidden;
37
+ }
38
+
39
+ header {
40
+ padding: 1rem 2rem;
41
+ display: flex;
42
+ justify-content: space-between;
43
+ align-items: center;
44
+ border-bottom: 1px solid var(--border);
45
+ background: var(--glass);
46
+ backdrop-filter: blur(12px);
47
+ z-index: 100;
48
+ }
49
+
50
+ .logo {
51
+ font-weight: 600;
52
+ font-size: 1.25rem;
53
+ background: linear-gradient(to right, #60a5fa, #3b82f6);
54
+ -webkit-background-clip: text;
55
+ background-clip: text;
56
+ -webkit-text-fill-color: transparent;
57
+ letter-spacing: -0.02em;
58
+ }
59
+
60
+ main {
61
+ flex: 1;
62
+ display: flex;
63
+ overflow: hidden;
64
+ }
65
+
66
+ .editor-container {
67
+ flex: 1;
68
+ display: flex;
69
+ flex-direction: column;
70
+ border-right: 1px solid var(--border);
71
+ }
72
+
73
+ .preview-container {
74
+ flex: 1;
75
+ background: white;
76
+ position: relative;
77
+ }
78
+
79
+ #code-editor {
80
+ flex: 1;
81
+ background: var(--sidebar);
82
+ color: #e2e8f0;
83
+ font-family: 'Fira Code', monospace;
84
+ font-size: 14px;
85
+ padding: 2rem;
86
+ border: none;
87
+ resize: none;
88
+ outline: none;
89
+ line-height: 1.6;
90
+ }
91
+
92
+ iframe {
93
+ width: 100%;
94
+ height: 100%;
95
+ border: none;
96
+ }
97
+
98
+ .input-bar {
99
+ padding: 1.5rem 2rem;
100
+ background: var(--glass);
101
+ backdrop-filter: blur(20px);
102
+ border-top: 1px solid var(--border);
103
+ display: flex;
104
+ gap: 1rem;
105
+ align-items: center;
106
+ }
107
+
108
+ #vibe-input {
109
+ flex: 1;
110
+ background: rgba(255, 255, 255, 0.03);
111
+ border: 1px solid var(--border);
112
+ border-radius: 12px;
113
+ padding: 14px 20px;
114
+ color: white;
115
+ font-size: 1rem;
116
+ outline: none;
117
+ transition: all 0.2s;
118
+ }
119
+
120
+ #vibe-input:focus {
121
+ border-color: var(--accent);
122
+ box-shadow: 0 0 0 4px var(--accent-glow);
123
+ }
124
+
125
+ button {
126
+ background: var(--accent);
127
+ color: white;
128
+ border: none;
129
+ border-radius: 12px;
130
+ padding: 0 24px;
131
+ height: 52px;
132
+ font-weight: 600;
133
+ cursor: pointer;
134
+ transition: all 0.2s;
135
+ }
136
+
137
+ button:hover {
138
+ transform: translateY(-1px);
139
+ box-shadow: 0 8px 20px var(--accent-glow);
140
+ }
141
+
142
+ button:active {
143
+ transform: translateY(0);
144
+ }
145
+
146
+ .loader {
147
+ display: none;
148
+ width: 20px;
149
+ height: 20px;
150
+ border: 2px solid rgba(255, 255, 255, 0.3);
151
+ border-radius: 50%;
152
+ border-top-color: white;
153
+ animation: spin 0.8s linear infinite;
154
+ }
155
+
156
+ @keyframes spin {
157
+ to {
158
+ transform: rotate(360deg);
159
+ }
160
+ }
161
+
162
+ .tag {
163
+ font-size: 0.75rem;
164
+ text-transform: uppercase;
165
+ letter-spacing: 0.05em;
166
+ color: var(--text-dim);
167
+ margin-bottom: 0.5rem;
168
+ display: block;
169
+ }
170
+ </style>
171
+ </head>
172
+
173
+ <body>
174
+ <header>
175
+ <div class="logo">Vibe Coding IDE</div>
176
+ <div style="font-size: 0.8rem; color: var(--text-dim)">Powered by DeepSeek-V2</div>
177
+ </header>
178
+
179
+ <main>
180
+ <div class="editor-container">
181
+ <div style="padding: 0.75rem 2rem; border-bottom: 1px solid var(--border); background: var(--sidebar)">
182
+ <span class="tag">Code Output</span>
183
+ </div>
184
+ <textarea id="code-editor" readonly placeholder="Your code will appear here..."></textarea>
185
+ </div>
186
+ <div class="preview-container" id="preview-box">
187
+ <div
188
+ style="position: absolute; top: 10px; right: 10px; z-index: 10; font-size: 0.7rem; background: rgba(0,0,0,0.5); padding: 4px 8px; border-radius: 4px; color: white">
189
+ Live Preview
190
+ </div>
191
+ <iframe id="preview-frame"></iframe>
192
+ </div>
193
+ </main>
194
+
195
+ <div class="input-bar">
196
+ <input type="text" id="vibe-input"
197
+ placeholder="Describe the vibe... (e.g., 'Modern glassmorphism landing page for a coffee brand')">
198
+ <button id="vibe-btn">
199
+ <span id="btn-text">Vibe It</span>
200
+ <div class="loader" id="btn-loader"></div>
201
+ </button>
202
+ </div>
203
+
204
+ <script>
205
+ const input = document.getElementById('vibe-input');
206
+ const btn = document.getElementById('vibe-btn');
207
+ const editor = document.getElementById('code-editor');
208
+ const frame = document.getElementById('preview-frame');
209
+ const loader = document.getElementById('btn-loader');
210
+ const btnText = document.getElementById('btn-text');
211
+
212
+ async function startVibe() {
213
+ const prompt = input.value.trim();
214
+ if (!prompt) return;
215
+
216
+ // Update UI
217
+ btn.disabled = true;
218
+ btnText.style.display = 'none';
219
+ loader.style.display = 'block';
220
+ editor.value = '';
221
+
222
+ try {
223
+ const response = await fetch('/vibe', {
224
+ method: 'POST',
225
+ headers: { 'Content-Type': 'application/json' },
226
+ body: JSON.stringify({
227
+ messages: [{ role: 'user', content: prompt }]
228
+ })
229
+ });
230
+
231
+ const reader = response.body.getReader();
232
+ const decoder = new TextDecoder();
233
+ let fullCode = '';
234
+
235
+ while (true) {
236
+ const { done, value } = await reader.read();
237
+ if (done) break;
238
+
239
+ const chunk = decoder.decode(value);
240
+ const lines = chunk.split('\n');
241
+
242
+ for (const line of lines) {
243
+ if (line.startsWith('data: ')) {
244
+ try {
245
+ const data = JSON.parse(line.slice(6));
246
+ if (data.content) {
247
+ fullCode += data.content;
248
+ editor.value = fullCode;
249
+ editor.scrollTop = editor.scrollHeight;
250
+
251
+ // Live update preview (extract HTML/CSS/JS)
252
+ // For simplicity in this demo, we assume the AI is returning a single block of code
253
+ // that can be injected into an iframe.
254
+ updatePreview(fullCode);
255
+ }
256
+ } catch (e) {
257
+ console.error("Error parsing JSON", e);
258
+ }
259
+ }
260
+ }
261
+ }
262
+ } catch (error) {
263
+ console.error("Vibe failed", error);
264
+ editor.value = "Error: " + error.message;
265
+ } finally {
266
+ btn.disabled = false;
267
+ btnText.style.display = 'inline';
268
+ loader.style.display = 'none';
269
+ }
270
+ }
271
+
272
+ function updatePreview(code) {
273
+ // Remove markdown code fences if present
274
+ const cleanCode = code.replace(/```html|```javascript|```css|```/g, '').trim();
275
+
276
+ const blob = new Blob([cleanCode], { type: 'text/html' });
277
+ frame.src = URL.createObjectURL(blob);
278
+ }
279
+
280
+ btn.addEventListener('click', startVibe);
281
+ input.addEventListener('keypress', (e) => {
282
+ if (e.key === 'Enter') startVibe();
283
+ });
284
+ </script>
285
+ </body>
286
+
287
+ </html>
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ httpx
4
+ pydantic
5
+ python-dotenv
6
+ huggingface_hub