ganna217 commited on
Commit
5820f9b
·
1 Parent(s): 4575056
Files changed (3) hide show
  1. Dockerfile +5 -2
  2. app.py +12 -16
  3. index.html +74 -46
Dockerfile CHANGED
@@ -9,8 +9,11 @@ COPY requirements.txt .
9
  RUN pip install --no-cache-dir -r requirements.txt
10
 
11
  # Pre-download models to cache them in the Docker image
12
- RUN python -c "from transformers import pipeline; pipeline('summarization', model='sshleifer/distilbart-cnn-6-6')"
13
- RUN python -c "from transformers import pipeline; pipeline('translation', model='facebook/m2m100_418M')"
 
 
 
14
 
15
  # Copy the rest of the application
16
  COPY . .
 
9
  RUN pip install --no-cache-dir -r requirements.txt
10
 
11
  # Pre-download models to cache them in the Docker image
12
+ RUN python -c "from transformers import pipeline; pipeline('summarization', model='facebook/bart-large-cnn')"
13
+ RUN python -c "from transformers import pipeline; pipeline('translation', model='Helsinki-NLP/opus-mt-en-fr')"
14
+ RUN python -c "from transformers import pipeline; pipeline('translation', model='Helsinki-NLP/opus-mt-en-de')"
15
+ RUN python -c "from transformers import pipeline; pipeline('translation', model='Helsinki-NLP/opus-mt-en-es')"
16
+ RUN python -c "from transformers import pipeline; pipeline('translation', model='Helsinki-NLP/opus-mt-en-ar')"
17
 
18
  # Copy the rest of the application
19
  COPY . .
app.py CHANGED
@@ -27,10 +27,13 @@ async def serve_html():
27
 
28
  # Load pre-trained models from Hugging Face Hub
29
  try:
30
- # Use a lighter summarization model
31
- summarizer = pipeline("summarization", model="sshleifer/distilbart-cnn-6-6")
32
- # Use a single multilingual translation model
33
- translator = pipeline("translation", model="facebook/m2m100_418M")
 
 
 
34
  except Exception as e:
35
  print(f"Error loading models: {str(e)}")
36
  raise e
@@ -57,26 +60,19 @@ async def translate(request: Request):
57
  data = await request.json()
58
  text = data["text"]
59
  lang = data["lang"]
60
- # Map language codes to M2M100 language codes
61
- lang_map = {
62
- "fr": "fr",
63
- "de": "de",
64
- "es": "es",
65
- "ar": "ar"
66
- }
67
- if lang not in lang_map:
68
  return {"error": "Language not supported"}
69
 
70
- # Perform translation using M2M100
71
- result = translator(text, src_lang="en", tgt_lang=lang_map[lang])
72
  print(f"Translation result for {lang}: {result}") # Debugging
73
 
74
  # Check if result is a list and has at least one item
75
  if not isinstance(result, list) or len(result) == 0:
76
  return {"error": "Translation failed: empty or invalid result"}
77
 
78
- # Extract the translated text
79
- translation = result[0]["translation_text"]
80
  if translation is None:
81
  return {"error": "Translation failed: 'translation_text' not found in result"}
82
 
 
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
 
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
 
index.html CHANGED
@@ -11,127 +11,129 @@
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;
@@ -160,6 +162,24 @@
160
  width: 100%;
161
  }
162
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  </style>
164
  </head>
165
  <body>
@@ -205,28 +225,32 @@
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;
@@ -236,17 +260,21 @@
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);
 
11
  }
12
  body {
13
  font-family: Arial, sans-serif;
14
+ background-color: #000000;
15
  color: #e0e0e0;
16
  margin: 0;
17
+ padding: 10px;
18
  min-height: 100vh;
19
  display: flex;
20
  justify-content: center;
21
+ align-items: flex-start;
22
  }
23
  .container {
24
  max-width: 1000px;
25
  width: 100%;
26
  margin: 0 auto;
27
+ padding: 0 10px;
28
  }
29
  .header {
30
  display: flex;
31
  align-items: center;
32
  justify-content: center;
33
+ margin-bottom: 10px;
34
  }
35
  .header img {
36
+ width: 50px;
37
  height: auto;
38
+ margin-right: 10px;
39
  }
40
  .header h1 {
41
+ font-family: 'Papyrus', sans-serif;
42
+ font-size: 24px;
43
  margin: 0;
44
  color: #ffffff;
45
+ text-shadow: 2px 2px 5px rgba(107, 72, 255, 0.5);
46
  }
47
  .tagline {
48
+ font-family: 'Orbitron', sans-serif;
49
+ font-size: 14px;
50
+ font-weight: 700;
51
  color: #b0b0b0;
52
  text-align: center;
53
+ margin-bottom: 20px;
54
+ letter-spacing: 1px;
55
  }
56
  /* Summarization Section */
57
  .summarize-section {
58
  display: flex;
59
  flex-wrap: wrap;
60
+ gap: 10px;
61
+ margin-bottom: 20px;
62
  }
63
  .summarize-section div {
64
  flex: 1;
65
+ min-width: 100%;
66
  }
67
  .summarize-section label {
68
  display: block;
69
+ font-size: 16px;
70
  color: #ffffff;
71
+ margin-bottom: 5px;
72
  }
73
  textarea, .output {
74
  width: 100%;
75
+ padding: 10px;
76
+ border-radius: 5px;
77
  border: 2px solid #6b48ff;
78
+ font-size: 14px; /* Reduced for mobile */
79
  background-color: #1a1a1a;
80
  color: #ffffff;
81
+ box-shadow: 0 0 5px rgba(107, 72, 255, 0.3);
82
  }
83
  textarea {
84
+ height: 150px;
85
+ resize: vertical;
86
  }
87
  .output {
88
+ height: 150px;
89
  }
90
  .translation-output {
91
+ height: 100px;
92
  }
93
  .button-container {
94
  width: 100%;
95
  text-align: left;
96
+ margin-top: 5px;
97
  }
98
  button {
99
  background: linear-gradient(90deg, #6b48ff, #a73aff);
100
  color: white;
101
+ padding: 10px 20px;
102
  border: none;
103
+ border-radius: 20px;
104
  cursor: pointer;
105
+ font-size: 14px;
106
  transition: transform 0.2s, box-shadow 0.3s;
107
+ box-shadow: 0 4px 10px rgba(107, 72, 255, 0.4);
108
+ width: 100%;
109
  }
110
  button:hover {
111
  background: linear-gradient(90deg, #5a38e7, #9632e6);
112
  transform: scale(1.05);
113
+ box-shadow: 0 6px 15px rgba(107, 72, 255, 0.6);
114
  }
115
  /* Translation Section */
116
  .translate-section {
117
+ margin-top: 20px;
118
  display: flex;
119
  flex-wrap: wrap;
120
+ gap: 10px;
121
  align-items: center;
122
+ margin-bottom: 10px;
123
  }
124
  .translate-section label {
125
+ font-size: 16px;
126
  color: #ffffff;
127
  }
128
  select {
129
+ padding: 8px;
130
  border-radius: 5px;
131
  border: 2px solid #a73aff;
132
+ font-size: 14px;
133
  background-color: #1a1a1a;
134
  color: #ffffff;
135
  cursor: pointer;
136
+ width: 100%;
137
  appearance: none;
138
  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>');
139
  background-repeat: no-repeat;
 
162
  width: 100%;
163
  }
164
  }
165
+ @media (max-width: 480px) {
166
+ .header h1 {
167
+ font-size: 20px;
168
+ }
169
+ .tagline {
170
+ font-size: 12px;
171
+ }
172
+ textarea, .output {
173
+ height: 120px;
174
+ }
175
+ .translation-output {
176
+ height: 80px;
177
+ }
178
+ button {
179
+ padding: 8px 15px;
180
+ font-size: 12px;
181
+ }
182
+ }
183
  </style>
184
  </head>
185
  <body>
 
225
 
226
  <script>
227
  console.log("Script loaded successfully");
228
+
229
  async function summarize() {
230
  const text = document.getElementById("inputText").value;
231
  try {
232
+ const controller = new AbortController();
233
+ const timeoutId = setTimeout(() => controller.abort(), 120000);
234
  const response = await fetch("/summarize", {
235
  method: "POST",
236
  headers: { "Content-Type": "application/json" },
237
+ body: JSON.stringify({ text: text }),
238
+ signal: controller.signal
239
  });
240
+ clearTimeout(timeoutId);
241
  const data = await response.json();
242
  console.log("Summarize response:", JSON.stringify(data, null, 2));
243
  if (data.summary) {
244
  document.getElementById("summary").innerText = data.summary;
245
  } else {
246
+ document.getElementById("summary").innerText = "Error: " + (data.error || "No summary returned");
247
  }
248
  } catch (error) {
249
  console.error("Summarize error:", error);
250
  document.getElementById("summary").innerText = "Failed to summarize: " + error.message;
251
  }
252
  }
253
+
254
  async function doTranslate() {
255
  const summary = document.getElementById("summary").innerText;
256
  const lang = document.getElementById("language").value;
 
260
  }
261
  console.log("Translate called with lang:", lang, "Text:", summary);
262
  try {
263
+ const controller = new AbortController();
264
+ const timeoutId = setTimeout(() => controller.abort(), 120000);
265
  const response = await fetch("/translate", {
266
  method: "POST",
267
  headers: { "Content-Type": "application/json" },
268
+ body: JSON.stringify({ text: summary, lang: lang }),
269
+ signal: controller.signal
270
  });
271
+ clearTimeout(timeoutId);
272
  const data = await response.json();
273
  console.log("Translate response:", JSON.stringify(data, null, 2));
274
  if (data.translation) {
275
  document.getElementById("translation").innerText = data.translation;
276
  } else {
277
+ document.getElementById("translation").innerText = "Error: " + (data.error || "No translation returned");
278
  }
279
  } catch (error) {
280
  console.error("Translate error:", error);