GenAIDevTOProd commited on
Commit
05dab2a
·
verified ·
1 Parent(s): 32df8a9

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +151 -0
app.py ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """app.py
3
+
4
+ Automatically generated by Colab.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/1zVrT1lKxARrm_wPS9sX-L8z5K4cxaAXm
8
+ """
9
+
10
+ import gradio as gr
11
+ import yaml, json, requests
12
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
13
+ import os
14
+
15
+ # Optional fallback: Falcon 1B generator
16
+ tokenizer = AutoTokenizer.from_pretrained("tiiuae/falcon-rw-1b")
17
+ model = AutoModelForCausalLM.from_pretrained("tiiuae/falcon-rw-1b")
18
+ falcon_generator = pipeline("text-generation", model=model, tokenizer=tokenizer)
19
+
20
+ # Call Mistral-7B via OpenRouter
21
+ def call_mistral_openrouter(prompt):
22
+ headers = {
23
+ "Authorization": f"Bearer {os.getenv('OpenRouter_Secret_Key')}",
24
+ "Content-Type": "application/json"
25
+ }
26
+ data = {
27
+ "model": "mistralai/mistral-7b-instruct:free",
28
+ "messages": [
29
+ {"role": "system", "content": "You are a helpful technical writer."},
30
+ {"role": "user", "content": prompt}
31
+ ]
32
+ }
33
+ res = requests.post("https://openrouter.ai/api/v1/chat/completions", headers=headers, json=data)
34
+ try:
35
+ return res.json()["choices"][0]["message"]["content"].strip()
36
+ except Exception as e:
37
+ return f"⚠️ LLM Error: {e}\nFull response: {res.text}"
38
+
39
+ # Prompt builder
40
+ def format_prompt(spec: dict, format_type: str, style: str) -> str:
41
+ prompt_lines = [style.strip() + "\n\n"]
42
+
43
+ if format_type.lower() == "openapi":
44
+ seen = set()
45
+ paths = spec.get("paths", {})
46
+ for path, methods in paths.items():
47
+ for method, meta in methods.items():
48
+ key = (path, method)
49
+ if key in seen:
50
+ continue
51
+ seen.add(key)
52
+
53
+ line = f"Endpoint `{path}` supports `{method.upper()}` requests.\n"
54
+ summary = meta.get("summary", "")
55
+ if summary:
56
+ line += f"Purpose: {summary}\n"
57
+ for p in meta.get("parameters", []):
58
+ pname = p.get("name", "unknown")
59
+ ploc = p.get("in", "unknown")
60
+ ptype = p.get("schema", {}).get("type", "unknown")
61
+ line += f"- Parameter `{pname}` in `{ploc}` of type `{ptype}`\n"
62
+ for code, resp in meta.get("responses", {}).items():
63
+ desc = resp.get("description", "")
64
+ line += f"- Returns `{code}`: {desc}\n"
65
+ prompt_lines.append(line + "\n")
66
+
67
+ elif format_type.lower() == "terraform":
68
+ resources = spec.get("resource", {})
69
+ for rtype, rblocks in resources.items():
70
+ for name, config in rblocks.items():
71
+ line = f"Terraform resource `{rtype}.{name}` has configuration:\n"
72
+ for k, v in config.items():
73
+ line += f"- {k}: {v}\n"
74
+ prompt_lines.append(line + "\n")
75
+
76
+ elif format_type.lower() == "kubernetes":
77
+ kind = spec.get("kind", "Unknown")
78
+ metadata = spec.get("metadata", {})
79
+ name = metadata.get("name", "Unnamed")
80
+ spec_section = spec.get("spec", {})
81
+ line = f"Kubernetes `{kind}` named `{name}` includes:\n"
82
+ for k, v in spec_section.items():
83
+ v_fmt = json.dumps(v) if isinstance(v, (list, dict)) else str(v)
84
+ line += f"- {k}: {v_fmt}\n"
85
+ prompt_lines.append(line + "\n")
86
+
87
+ elif format_type.lower() in {"cicd", "ci/cd", "github-actions", "github"}:
88
+ jobs = spec.get("jobs", {})
89
+ for job_name, job_config in jobs.items():
90
+ line = f"CI/CD Job `{job_name}` consists of:\n"
91
+ steps = job_config.get("steps", [])
92
+ for step in steps:
93
+ if "name" in step:
94
+ line += f"- Step: {step['name']}\n"
95
+ if "uses" in step:
96
+ line += f" Uses: {step['uses']}\n"
97
+ if "run" in step:
98
+ line += f" Run: {step['run']}\n"
99
+ prompt_lines.append(line + "\n")
100
+
101
+ return "".join(prompt_lines)
102
+
103
+ # End-to-end summarization
104
+ def summarize_spec(format_type, raw_text, url, file, eli5):
105
+ style = (
106
+ "You are a technical writer. Explain like I'm 5. "
107
+ if eli5 else "You are a technical writer. "
108
+ )
109
+ style += f"Summarize the following {format_type.upper()} spec in clear, developer-friendly language. Use full sentences. Combine related endpoints where appropriate."
110
+
111
+ try:
112
+ if file:
113
+ content = file.read()
114
+ spec = yaml.safe_load(content)
115
+ elif url:
116
+ response = requests.get(url)
117
+ spec = response.json() if url.endswith(".json") else yaml.safe_load(response.text)
118
+ elif raw_text:
119
+ spec = yaml.safe_load(raw_text)
120
+ else:
121
+ return "⚠️ No input provided."
122
+ except Exception as e:
123
+ return f"⚠️ Parsing error: {e}"
124
+
125
+ try:
126
+ prompt = format_prompt(spec, format_type, style)
127
+ result = call_mistral_openrouter(prompt)
128
+ return result
129
+ except Exception as e:
130
+ return f"⚠️ Inference error: {e}"
131
+
132
+ # Gradio UI
133
+ with gr.Blocks() as demo:
134
+ gr.Markdown("## 📄 YAML/JSON Explainer — Mistral-7B via OpenRouter")
135
+
136
+ format_dropdown = gr.Dropdown(choices=["openapi", "terraform", "kubernetes", "cicd"], value="openapi", label="Select Spec Format")
137
+ raw_input = gr.Textbox(lines=10, placeholder="Paste YAML/JSON here...", label="Raw Spec")
138
+ eli5_toggle = gr.Checkbox(label="Explain like I'm 5", value=False)
139
+ file_input = gr.File(file_types=[".yaml", ".yml", ".json"], label="Upload File")
140
+ url_input = gr.Textbox(placeholder="https://example.com/spec.yaml", label="OR enter a URL")
141
+
142
+ submit_btn = gr.Button("Generate Summary")
143
+ output = gr.TextArea(label="Natural Language Explanation", lines=12)
144
+
145
+ submit_btn.click(
146
+ summarize_spec,
147
+ inputs=[format_dropdown, raw_input, url_input, file_input, eli5_toggle],
148
+ outputs=output
149
+ )
150
+
151
+ demo.launch(share=True)