swayamshetkar commited on
Commit
889453a
·
1 Parent(s): 327898f
Files changed (4) hide show
  1. Dockerfile +25 -0
  2. app.py +39 -40
  3. prompt_templates.py +36 -30
  4. requirements.txt +7 -5
Dockerfile ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /code
4
+
5
+ # Install system dependencies
6
+ RUN apt-get update && apt-get install -y \
7
+ build-essential \
8
+ curl \
9
+ && rm -rf /var/lib/apt/lists/*
10
+
11
+ # Copy requirements first for better caching
12
+ COPY requirements.txt .
13
+
14
+ # Install Python dependencies
15
+ RUN pip install --no-cache-dir --upgrade pip && \
16
+ pip install --no-cache-dir -r requirements.txt
17
+
18
+ # Copy application code
19
+ COPY . .
20
+
21
+ # Expose port
22
+ EXPOSE 7860
23
+
24
+ # Run the application
25
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py CHANGED
@@ -1,10 +1,10 @@
1
  from fastapi import FastAPI
2
  from pydantic import BaseModel
3
- from model_loader import tokenizer, model
4
  from prompt_templates import MAIN_PROMPT_TEMPLATE, DETAIL_PROMPT_TEMPLATE
5
- import torch
6
  import json
7
  import re
 
8
 
9
  app = FastAPI()
10
 
@@ -15,54 +15,53 @@ class DetailRequest(BaseModel):
15
  idea_id: int
16
  idea_title: str
17
 
18
-
19
- @app.get("/")
20
- def home():
21
- return {"status": "Local GPT-2 Backend Running", "endpoints": ["/generate", "/details"]}
22
-
23
-
24
- def run_gpt2(prompt: str):
25
- inputs = tokenizer.encode(prompt, return_tensors="pt")
26
- outputs = model.generate(
27
- inputs,
28
- max_new_tokens=500,
29
- temperature=0.8,
30
- top_p=0.9,
31
- do_sample=True
32
- )
33
- return tokenizer.decode(outputs[0], skip_special_tokens=True)
34
-
35
-
36
  def extract_json(text):
37
  try:
38
- match = re.search(r"\{[\s\S]*\}", text)
39
- if match:
40
- return json.loads(match.group())
41
  except:
42
  pass
 
 
 
 
 
 
 
 
43
  return {"error": "JSON parsing failed", "raw_output": text}
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
- # -----------------------
47
- # STEP 1 → GENERATE IDEAS
48
- # -----------------------
49
  @app.post("/generate")
50
  def generate(req: GenerateRequest):
51
- prompt = MAIN_PROMPT_TEMPLATE.format(CUSTOM_PROMPT=req.custom_prompt)
52
- raw_output = run_gpt2(prompt)
53
- json_data = extract_json(raw_output)
54
- return json_data
55
-
56
 
57
- # -----------------------
58
- # STEP 2 → IDEA DETAILS
59
- # -----------------------
60
  @app.post("/details")
61
  def details(req: DetailRequest):
62
- prompt = DETAIL_PROMPT_TEMPLATE.format(
63
- IDEA_ID=req.idea_id,
64
- IDEA_TITLE=req.idea_title
 
65
  )
66
- raw_output = run_gpt2(prompt)
67
- json_data = extract_json(raw_output)
68
- return json_data
 
1
  from fastapi import FastAPI
2
  from pydantic import BaseModel
3
+ from model_loader import model, tokenizer
4
  from prompt_templates import MAIN_PROMPT_TEMPLATE, DETAIL_PROMPT_TEMPLATE
 
5
  import json
6
  import re
7
+ import torch
8
 
9
  app = FastAPI()
10
 
 
15
  idea_id: int
16
  idea_title: str
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  def extract_json(text):
19
  try:
20
+ return json.loads(text)
 
 
21
  except:
22
  pass
23
+
24
+ m = re.search(r"\{[\s\S]*\}", text)
25
+ if m:
26
+ try:
27
+ return json.loads(m.group())
28
+ except:
29
+ pass
30
+
31
  return {"error": "JSON parsing failed", "raw_output": text}
32
 
33
+ def run_model(prompt: str):
34
+ inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=512).to("cpu")
35
+ with torch.no_grad():
36
+ outputs = model.generate(
37
+ **inputs,
38
+ max_new_tokens=512,
39
+ do_sample=False,
40
+ temperature=1.0
41
+ )
42
+ text = tokenizer.decode(outputs[0], skip_special_tokens=True)
43
+ return text
44
+
45
+ @app.get("/")
46
+ def home():
47
+ return {
48
+ "status": "FLAN-T5 Backend Running",
49
+ "endpoints": ["/generate", "/details"],
50
+ "model": "google/flan-t5-base"
51
+ }
52
 
 
 
 
53
  @app.post("/generate")
54
  def generate(req: GenerateRequest):
55
+ prompt = MAIN_PROMPT_TEMPLATE.replace("{CUSTOM_PROMPT}", req.custom_prompt)
56
+ raw = run_model(prompt)
57
+ return extract_json(raw)
 
 
58
 
 
 
 
59
  @app.post("/details")
60
  def details(req: DetailRequest):
61
+ prompt = (
62
+ DETAIL_PROMPT_TEMPLATE
63
+ .replace("{IDEA_ID}", str(req.idea_id))
64
+ .replace("{IDEA_TITLE}", req.idea_title)
65
  )
66
+ raw = run_model(prompt)
67
+ return extract_json(raw)
 
prompt_templates.py CHANGED
@@ -1,53 +1,65 @@
1
  MAIN_PROMPT_TEMPLATE = """
2
- Generate 3 distinct client-side hackathon ideas. {CUSTOM_PROMPT}
3
- For each idea, provide a title, a short elevator pitch, an overview, primary tech stack, difficulty, and estimated time.
4
- Pick the best one and explain why.
5
- Return ONLY valid JSON matching this exact schema:
6
-
7
  {
8
  "ideas": [
9
  {
10
- "id": <int>,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  "title": "<string>",
12
  "elevator": "<string>",
13
  "overview": "<string>",
14
- "primary_tech_stack": ["<string>", "..."],
15
  "difficulty": "<Easy|Medium|Hard>",
16
  "time_estimate_hours": <number>
17
  }
18
  ],
19
- "best_pick_id": <int>,
20
  "best_pick_reason": "<string>"
21
  }
22
-
23
- Constraints:
24
- - Return exactly 3 ideas.
25
- - Keep all text concise for UI cards.
26
  """.strip()
27
 
28
-
29
  DETAIL_PROMPT_TEMPLATE = """
30
- Expand on the hackathon idea "{IDEA_TITLE}" (ID: {IDEA_ID}).
31
- Create a detailed, step-by-step build plan suitable for a 48-hour hackathon.
32
- Return ONLY valid JSON matching this exact schema:
33
-
34
  {
35
  "id": {IDEA_ID},
36
  "title": "{IDEA_TITLE}",
37
- "mermaid_architecture": "<string starting with 'graph LR'>",
38
  "phases": [
39
  {
40
  "name": "<MVP|Polish|Demo>",
41
  "time_hours": <number>,
42
- "tasks": ["<string>", "..."],
43
- "deliverables": ["<string>", "..."]
44
  }
45
  ],
46
  "critical_code_snippets": [
47
  {
48
  "title": "<string>",
49
- "language": "javascript|html|css",
50
- "code": "<multiline string of code>"
51
  }
52
  ],
53
  "ui_components": [
@@ -59,14 +71,8 @@ Return ONLY valid JSON matching this exact schema:
59
  "risks_and_mitigations": [
60
  {
61
  "risk": "<string>",
62
- "mitigation":"<string>"
63
  }
64
  ]
65
  }
66
-
67
- Constraints:
68
- - The 'phases' array must cover the entire build process.
69
- - Total time for all phases must not exceed 48 hours.
70
- - Mermaid diagrams must be valid and represent the project architecture.
71
- - Include at least one meaningful code snippet.
72
- """.strip()
 
1
  MAIN_PROMPT_TEMPLATE = """
2
+ You are an AI that outputs ONLY valid JSON.
3
+ Do NOT include explanations. Do NOT include any text before or after the JSON.
4
+ Generate 3 client-side hackathon ideas. {CUSTOM_PROMPT}
5
+ Return ONLY JSON in this exact format:
 
6
  {
7
  "ideas": [
8
  {
9
+ "id": 1,
10
+ "title": "<string>",
11
+ "elevator": "<string>",
12
+ "overview": "<string>",
13
+ "primary_tech_stack": ["<string>"],
14
+ "difficulty": "<Easy|Medium|Hard>",
15
+ "time_estimate_hours": <number>
16
+ },
17
+ {
18
+ "id": 2,
19
+ "title": "<string>",
20
+ "elevator": "<string>",
21
+ "overview": "<string>",
22
+ "primary_tech_stack": ["<string>"],
23
+ "difficulty": "<Easy|Medium|Hard>",
24
+ "time_estimate_hours": <number>
25
+ },
26
+ {
27
+ "id": 3,
28
  "title": "<string>",
29
  "elevator": "<string>",
30
  "overview": "<string>",
31
+ "primary_tech_stack": ["<string>"],
32
  "difficulty": "<Easy|Medium|Hard>",
33
  "time_estimate_hours": <number>
34
  }
35
  ],
36
+ "best_pick_id": <1|2|3>,
37
  "best_pick_reason": "<string>"
38
  }
 
 
 
 
39
  """.strip()
40
 
 
41
  DETAIL_PROMPT_TEMPLATE = """
42
+ You are an AI that outputs ONLY valid JSON.
43
+ Do NOT include explanations. Do NOT include any text before or after the JSON.
44
+ Expand the hackathon idea "{IDEA_TITLE}" (ID: {IDEA_ID}) into a 48-hour build plan.
45
+ Return ONLY JSON in this exact format:
46
  {
47
  "id": {IDEA_ID},
48
  "title": "{IDEA_TITLE}",
49
+ "mermaid_architecture": "graph LR; A-->B;",
50
  "phases": [
51
  {
52
  "name": "<MVP|Polish|Demo>",
53
  "time_hours": <number>,
54
+ "tasks": ["<string>", "<string>"],
55
+ "deliverables": ["<string>", "<string>"]
56
  }
57
  ],
58
  "critical_code_snippets": [
59
  {
60
  "title": "<string>",
61
+ "language": "javascript",
62
+ "code": "<string>"
63
  }
64
  ],
65
  "ui_components": [
 
71
  "risks_and_mitigations": [
72
  {
73
  "risk": "<string>",
74
+ "mitigation": "<string>"
75
  }
76
  ]
77
  }
78
+ """.strip()
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1,5 +1,7 @@
1
- fastapi
2
- uvicorn
3
- transformers
4
- torch
5
- python-multipart
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn[standard]==0.24.0
3
+ transformers==4.35.2
4
+ torch==2.1.0
5
+ pydantic==2.5.0
6
+ sentencepiece==0.1.99
7
+ protobuf==4.25.1