ganna217 commited on
Commit
14adcdb
·
0 Parent(s):

Initial commit with all files

Browse files
Files changed (5) hide show
  1. Dockerfile +12 -0
  2. Moon.PNG +0 -0
  3. app.py +87 -0
  4. index.html +258 -0
  5. requirements.txt +4 -0
Dockerfile ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt .
6
+ RUN pip install --no-cache-dir -r requirements.txt
7
+
8
+ COPY . .
9
+
10
+ EXPOSE 7860
11
+
12
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
Moon.PNG ADDED
app.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, Request
2
+ from fastapi.responses import HTMLResponse
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ from fastapi.staticfiles import StaticFiles
5
+ from transformers import pipeline
6
+ import traceback
7
+
8
+ app = FastAPI()
9
+
10
+ # Enable CORS to allow POST requests
11
+ app.add_middleware(
12
+ CORSMiddleware,
13
+ allow_origins=["*"],
14
+ allow_credentials=True,
15
+ allow_methods=["*"],
16
+ allow_headers=["*"],
17
+ )
18
+
19
+ # Serve static files (like Moon.png) under /assets
20
+ app.mount("/assets", StaticFiles(directory="."), name="static")
21
+
22
+ # Serve the HTML page at the root
23
+ @app.get("/", response_class=HTMLResponse)
24
+ async def serve_html():
25
+ with open("index.html", "r", encoding="utf-8") as f:
26
+ return HTMLResponse(content=f.read())
27
+
28
+ # Load pre-trained models from Hugging Face Hub
29
+ try:
30
+ summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
31
+ translators = {
32
+ "fr": pipeline("translation", model="Helsinki-NLP/opus-mt-en-fr"),
33
+ "de": pipeline("translation", model="Helsinki-NLP/opus-mt-en-de"),
34
+ "es": pipeline("translation", model="Helsinki-NLP/opus-mt-en-es"),
35
+ "ar": pipeline("translation", model="Helsinki-NLP/opus-mt-en-ar")
36
+ }
37
+ except Exception as e:
38
+ print(f"Error loading models: {str(e)}")
39
+ raise e
40
+
41
+ # Summarization endpoint
42
+ @app.post("/summarize")
43
+ async def summarize(request: Request):
44
+ try:
45
+ data = await request.json()
46
+ text = data["text"]
47
+ input_length = len(summarizer.tokenizer(text)["input_ids"])
48
+ max_length = max(30, input_length // 2)
49
+ summary = summarizer(text, max_length=max_length, min_length=30, do_sample=False)
50
+ return {"summary": summary[0]["summary_text"]}
51
+ except Exception as e:
52
+ print(f"Error in summarize: {str(e)}")
53
+ print(traceback.format_exc())
54
+ return {"error": f"Failed to summarize: {str(e)}"}
55
+
56
+ # Translation endpoint
57
+ @app.post("/translate")
58
+ async def translate(request: Request):
59
+ try:
60
+ data = await request.json()
61
+ text = data["text"]
62
+ lang = data["lang"]
63
+ if lang not in translators:
64
+ return {"error": "Language not supported"}
65
+
66
+ # Perform translation
67
+ result = translators[lang](text)
68
+ print(f"Translation result for {lang}: {result}") # Debugging
69
+
70
+ # Check if result is a list and has at least one item
71
+ if not isinstance(result, list) or len(result) == 0:
72
+ return {"error": "Translation failed: empty or invalid result"}
73
+
74
+ # Extract the translated text (correct key is "translation_text")
75
+ translation = result[0].get("translation_text")
76
+ if translation is None:
77
+ return {"error": "Translation failed: 'translation_text' not found in result"}
78
+
79
+ return {"translation": translation}
80
+ except Exception as e:
81
+ print(f"Error in translate: {str(e)}")
82
+ print(traceback.format_exc())
83
+ return {"error": f"Failed to translate: {str(e)}"}
84
+
85
+ if __name__ == "__main__":
86
+ import uvicorn
87
+ uvicorn.run(app, host="0.0.0.0", port=7860)
index.html ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>QuickBrief</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Papyrus&display=swap" rel="stylesheet">
8
+ <style>
9
+ * {
10
+ box-sizing: border-box;
11
+ }
12
+ body {
13
+ font-family: Arial, sans-serif;
14
+ background-color: #000000;
15
+ color: #e0e0e0;
16
+ margin: 0;
17
+ padding: 20px;
18
+ min-height: 100vh;
19
+ display: flex;
20
+ justify-content: center;
21
+ align-items: center;
22
+ }
23
+ .container {
24
+ max-width: 1000px;
25
+ width: 100%;
26
+ margin: 0 auto;
27
+ }
28
+ .header {
29
+ display: flex;
30
+ align-items: center;
31
+ justify-content: center;
32
+ margin-bottom: 4px;
33
+ }
34
+ .header img {
35
+ width: 60px;
36
+ height: auto;
37
+ margin-right: 15px;
38
+ }
39
+ .header h1 {
40
+ font-family: 'Papyrus', sans-serif;
41
+ font-size: 32px;
42
+ margin: 0;
43
+ color: #ffffff;
44
+ text-shadow: 2px 2px 5px rgba(107, 72, 255, 0.5);
45
+ }
46
+ .tagline {
47
+ font-family: 'Orbitron', sans-serif;
48
+ font-size: 16px;
49
+ font-weight: 700;
50
+ color: #b0b0b0;
51
+ text-align: center;
52
+ margin-bottom: 30px;
53
+ letter-spacing: 1px;
54
+ }
55
+ /* Summarization Section */
56
+ .summarize-section {
57
+ display: flex;
58
+ flex-wrap: wrap;
59
+ gap: 20px;
60
+ margin-bottom: 40px;
61
+ }
62
+ .summarize-section div {
63
+ flex: 1;
64
+ min-width: 300px;
65
+ }
66
+ .summarize-section label {
67
+ display: block;
68
+ font-size: 18px;
69
+ color: #ffffff;
70
+ margin-bottom: 10px;
71
+ }
72
+ textarea, .output {
73
+ width: 100%;
74
+ padding: 15px;
75
+ border-radius: 10px;
76
+ border: 2px solid #6b48ff;
77
+ font-size: 16px;
78
+ background-color: #1a1a1a;
79
+ color: #ffffff;
80
+ box-shadow: 0 0 10px rgba(107, 72, 255, 0.3);
81
+ }
82
+ textarea {
83
+ height: 200px;
84
+ resize: both;
85
+ }
86
+ .output {
87
+ height: 200px;
88
+ }
89
+ .translation-output {
90
+ height: 120px;
91
+ }
92
+ .button-container {
93
+ width: 100%;
94
+ text-align: left;
95
+ margin-top: 10px;
96
+ }
97
+ button {
98
+ background: linear-gradient(90deg, #6b48ff, #a73aff);
99
+ color: white;
100
+ padding: 12px 30px;
101
+ border: none;
102
+ border-radius: 25px;
103
+ cursor: pointer;
104
+ font-size: 16px;
105
+ transition: transform 0.2s, box-shadow 0.3s;
106
+ box-shadow: 0 4px 15px rgba(107, 72, 255, 0.4);
107
+ }
108
+ button:hover {
109
+ background: linear-gradient(90deg, #5a38e7, #9632e6);
110
+ transform: scale(1.05);
111
+ box-shadow: 0 6px 20px rgba(107, 72, 255, 0.6);
112
+ }
113
+ /* Translation Section */
114
+ .translate-section {
115
+ margin-top: 40px;
116
+ display: flex;
117
+ flex-wrap: wrap;
118
+ gap: 15px;
119
+ align-items: center;
120
+ margin-bottom: 20px;
121
+ }
122
+ .translate-section label {
123
+ font-size: 18px;
124
+ color: #ffffff;
125
+ }
126
+ select {
127
+ padding: 10px;
128
+ border-radius: 5px;
129
+ border: 2px solid #a73aff;
130
+ font-size: 16px;
131
+ background-color: #1a1a1a;
132
+ color: #ffffff;
133
+ cursor: pointer;
134
+ width: 200px;
135
+ appearance: none;
136
+ background-image: url('data:image/svg+xml;utf8,<svg fill="white" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M7 10l5 5 5-5z"/></svg>');
137
+ background-repeat: no-repeat;
138
+ background-position: right 10px center;
139
+ }
140
+ select:focus {
141
+ outline: none;
142
+ border-color: #6b48ff;
143
+ }
144
+ /* Responsive Design */
145
+ @media (max-width: 768px) {
146
+ .summarize-section {
147
+ flex-direction: column;
148
+ }
149
+ .summarize-section div {
150
+ min-width: 100%;
151
+ }
152
+ .translate-section {
153
+ flex-direction: column;
154
+ align-items: flex-start;
155
+ }
156
+ select {
157
+ width: 100%;
158
+ }
159
+ button {
160
+ width: 100%;
161
+ }
162
+ }
163
+ </style>
164
+ </head>
165
+ <body>
166
+ <div class="container">
167
+ <div class="header">
168
+ <img src="/assets/Moon.png" alt="QuickBrief Logo">
169
+ <h1>QuickBrief</h1>
170
+ </div>
171
+ <p class="tagline">Simplify. Summarize. Translate. Understand.</p>
172
+
173
+ <!-- Summarization Section -->
174
+ <div class="summarize-section">
175
+ <div>
176
+ <label>Input Text</label>
177
+ <textarea id="inputText" placeholder="Enter your text here..."></textarea>
178
+ <div class="button-container">
179
+ <button onclick="summarize()">SUMMARIZE</button>
180
+ </div>
181
+ </div>
182
+ <div>
183
+ <label>Summary</label>
184
+ <div id="summary" class="output"></div>
185
+ </div>
186
+ </div>
187
+
188
+ <!-- Translation Section -->
189
+ <div class="translate-section">
190
+ <label>Translate Summary</label>
191
+ <select id="language">
192
+ <option value="default">Select Language</option>
193
+ <option value="fr">French</option>
194
+ <option value="de">German</option>
195
+ <option value="es">Spanish</option>
196
+ <option value="ar">Arabic</option>
197
+ </select>
198
+ <button onclick="doTranslate()">TRANSLATE</button>
199
+ </div>
200
+ <div>
201
+ <label>Translation</label>
202
+ <div id="translation" class="output translation-output"></div>
203
+ </div>
204
+ </div>
205
+
206
+ <script>
207
+ console.log("Script loaded successfully");
208
+
209
+ async function summarize() {
210
+ const text = document.getElementById("inputText").value;
211
+ try {
212
+ const response = await fetch("/summarize", {
213
+ method: "POST",
214
+ headers: { "Content-Type": "application/json" },
215
+ body: JSON.stringify({ text: text })
216
+ });
217
+ const data = await response.json();
218
+ console.log("Summarize response:", JSON.stringify(data, null, 2));
219
+ if (data.summary) {
220
+ document.getElementById("summary").innerText = data.summary;
221
+ } else {
222
+ document.getElementById("summary").innerText = "No summary returned: " + (data.error || "Unknown error");
223
+ }
224
+ } catch (error) {
225
+ console.error("Summarize error:", error);
226
+ document.getElementById("summary").innerText = "Failed to summarize: " + error.message;
227
+ }
228
+ }
229
+
230
+ async function doTranslate() {
231
+ const summary = document.getElementById("summary").innerText;
232
+ const lang = document.getElementById("language").value;
233
+ if (lang === "default" || summary === "") {
234
+ document.getElementById("translation").innerText = "Please select a language and ensure a summary is available.";
235
+ return;
236
+ }
237
+ console.log("Translate called with lang:", lang, "Text:", summary);
238
+ try {
239
+ const response = await fetch("/translate", {
240
+ method: "POST",
241
+ headers: { "Content-Type": "application/json" },
242
+ body: JSON.stringify({ text: summary, lang: lang })
243
+ });
244
+ const data = await response.json();
245
+ console.log("Translate response:", JSON.stringify(data, null, 2));
246
+ if (data.translation) {
247
+ document.getElementById("translation").innerText = data.translation;
248
+ } else {
249
+ document.getElementById("translation").innerText = "Error: " + (data.error || "Unknown error");
250
+ }
251
+ } catch (error) {
252
+ console.error("Translate error:", error);
253
+ document.getElementById("translation").innerText = "Failed to translate: " + error.message;
254
+ }
255
+ }
256
+ </script>
257
+ </body>
258
+ </html>
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ transformers
4
+ torch