amine_dubs commited on
Commit
02efbd4
·
0 Parent(s):

Add application code and configuration for HF Space

Browse files
Files changed (7) hide show
  1. .gitignore +26 -0
  2. backend +1 -0
  3. project_details.txt +124 -0
  4. project_report.md +227 -0
  5. static/script.js +113 -0
  6. static/style.css +118 -0
  7. templates/index.html +85 -0
.gitignore ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+ *.pyd
6
+ *build*/
7
+ *dist*/
8
+ *.egg-info/
9
+ venv/
10
+ .venv/
11
+ env/
12
+ .env
13
+ *.env.*
14
+
15
+ # Uploads
16
+ uploads/
17
+
18
+ # IDE / OS specific
19
+ .vscode/
20
+ .idea/
21
+ *.DS_Store
22
+ Thumbs.db
23
+
24
+ # Local secrets (if any)
25
+ secrets.yaml
26
+ *.credential
backend ADDED
@@ -0,0 +1 @@
 
 
1
+ Subproject commit da27106172ae5acc2deda738eee913963fdaac6f
project_details.txt ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Deployment Guide: AI Translator on Hugging Face Spaces (Docker)
2
+
3
+ This guide outlines the steps to deploy the AI Translator web application to Hugging Face (HF) Spaces using Docker.
4
+
5
+ ## Prerequisites
6
+
7
+ 1. **Docker:** Ensure Docker Desktop (or Docker Engine on Linux) is installed and running on your local machine.
8
+ 2. **Git & Git LFS:** Install Git and Git Large File Storage (LFS) if you plan to use large model files directly in your repository (though it's often better to load them dynamically). Install LFS with `git lfs install`.
9
+ 3. **Hugging Face Account:** You need an account on [huggingface.co](https://huggingface.co/).
10
+ 4. **Hugging Face CLI (Optional but Recommended):** Install the HF command-line interface for easier repository management:
11
+ ```bash
12
+ pip install -U huggingface_hub
13
+ # Login to your account
14
+ huggingface-cli login
15
+ ```
16
+
17
+ ## Steps
18
+
19
+ 1. **Create a Hugging Face Repository:**
20
+ * Go to [huggingface.co](https://huggingface.co/) and create a new "Space".
21
+ * Give it a name (e.g., `your-username/ai-translator`).
22
+ * Select "Docker" as the Space SDK.
23
+ * Choose "Public" or "Private" visibility.
24
+ * Click "Create Space".
25
+
26
+ 2. **Prepare Your Local Repository:**
27
+ * Make sure your project directory is a Git repository. If not, initialize it:
28
+ ```bash
29
+ git init
30
+ ```
31
+ * Create a `.gitignore` file to exclude virtual environments, `uploads`, `__pycache__`, etc. (A basic example is provided below).
32
+ * **Crucially**, create a `README.md` file *at the root of your project* (or edit the existing one created by HF) with the following metadata block at the top:
33
+ ```markdown
34
+ ---
35
+ title: AI Translator
36
+ emoji: 🌍
37
+ colorFrom: blue
38
+ colorTo: green
39
+ sdk: docker
40
+ app_port: 8000 # Must match the port EXPOSEd in Dockerfile and run by uvicorn
41
+ # Optional: Specify hardware requirements if needed (default is free CPU)
42
+ # hardware: cpu-basic # cpu-upgrade, t4-small, t4-medium, a10g-small, etc.
43
+ # Optional: Add secrets if your app needs API keys (e.g., HF_TOKEN)
44
+ # secrets:
45
+ # - HF_TOKEN
46
+ ---
47
+
48
+ # AI Translator
49
+
50
+ This Space hosts an AI-powered web application for translating text and documents to/from Arabic.
51
+ Built with FastAPI, Docker, and Hugging Face Transformers.
52
+ ```
53
+ * **Important:** Ensure `app_port` matches the port exposed in your `backend/Dockerfile` (which is `8000` in the current setup).
54
+
55
+ 3. **Clone the HF Space Repository (Optional but Recommended):**
56
+ * Cloning ensures you have the correct remote configured. Go to your Space page on HF, click the "Files and versions" tab, then the "Clone repository" button to get the command.
57
+ * ```bash
58
+ # Example:
59
+ git clone https://huggingface.co/spaces/your-username/ai-translator
60
+ cd ai-translator
61
+ ```
62
+ * Copy your project files (`backend/`, `static/`, `templates/`, `Dockerfile` at the root, `README.md`, `.gitignore`, etc.) into this cloned directory. *Make sure the `Dockerfile` is at the root level if HF expects it there, or adjust paths in the Dockerfile if it stays in `backend/`.* **Correction:** The current `Dockerfile` assumes it's run from the project root and copies files like `backend/requirements.txt`. Let's keep the `Dockerfile` in the `backend/` directory as initially created and adjust the `README.md` if needed, or adjust the Dockerfile copy paths. *Let's assume the `Dockerfile` stays in `backend/` for now, as created.*
63
+
64
+ 4. **Add and Commit Files:**
65
+ * Stage all your project files:
66
+ ```bash
67
+ git add .
68
+ ```
69
+ * Commit the changes:
70
+ ```bash
71
+ git commit -m "Initial commit of AI Translator application"
72
+ ```
73
+
74
+ 5. **Push to Hugging Face:**
75
+ * If you cloned the repository, the remote (`origin`) should already be set.
76
+ * If you initialized Git locally, add the HF Space remote:
77
+ ```bash
78
+ git remote add origin https://huggingface.co/spaces/your-username/ai-translator
79
+ ```
80
+ * Push your code to the `main` branch on Hugging Face:
81
+ ```bash
82
+ git push origin main
83
+ ```
84
+
85
+ 6. **Monitor Build Process:**
86
+ * Go back to your Space page on Hugging Face.
87
+ * The Space will automatically start building the Docker image based on your `backend/Dockerfile`. You can monitor the build logs.
88
+ * If the build is successful, the application container will start.
89
+ * Any errors during the build (e.g., missing dependencies, Dockerfile syntax errors) or runtime errors (e.g., Python code errors, model loading issues) will appear in the logs.
90
+
91
+ 7. **Access Your Application:**
92
+ * Once the status shows "Running", your application should be accessible at the Space URL (e.g., `https://your-username-ai-translator.hf.space`).
93
+
94
+ ## Basic `.gitignore` Example
95
+
96
+ Create a file named `.gitignore` in the project root:
97
+
98
+ ```gitignore
99
+ # Python
100
+ __pycache__/
101
+ *.pyc
102
+ *.pyo
103
+ *.pyd
104
+ *build*/
105
+ *dist*/
106
+ *.egg-info/
107
+ venv/
108
+ env/
109
+ .env
110
+ *.env.*
111
+
112
+ # Uploads
113
+ uploads/
114
+
115
+ # IDE / OS specific
116
+ .vscode/
117
+ .idea/
118
+ *.DS_Store
119
+ Thumbs.db
120
+
121
+ # Local secrets (if any)
122
+ secrets.yaml
123
+ *.credential
124
+ ```
project_report.md ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AI-Powered Translation Web Application - Project Report
2
+
3
+ **Date:** April 27, 2025
4
+
5
+ **Author:** [Your Name/Team Name]
6
+
7
+ ## 1. Introduction
8
+
9
+ This report details the development process of an AI-powered web application designed for translating text and documents between various languages and Arabic (Modern Standard Arabic - Fusha). The application features a RESTful API backend built with FastAPI and a user-friendly frontend using HTML, CSS, and JavaScript. It is designed for deployment on Hugging Face Spaces using Docker.
10
+
11
+ ## 2. Project Objectives
12
+
13
+ * Develop a functional web application with AI translation capabilities.
14
+ * Deploy the application on Hugging Face Spaces using Docker.
15
+ * Build a RESTful API backend using FastAPI.
16
+ * Integrate Hugging Face LLMs/models for translation.
17
+ * Create a user-friendly frontend for interacting with the API.
18
+ * Support translation for direct text input and uploaded documents (PDF, DOCX, XLSX, PPTX, TXT).
19
+ * Focus on high-quality Arabic translation, emphasizing meaning and eloquence (Balagha) over literal translation.
20
+ * Document the development process comprehensively.
21
+
22
+ ## 3. Backend Architecture and API Design
23
+
24
+ ### 3.1. Framework and Language
25
+
26
+ * **Framework:** FastAPI
27
+ * **Language:** Python 3.9+
28
+
29
+ ### 3.2. Directory Structure
30
+
31
+ ```
32
+ /
33
+ |-- backend/
34
+ | |-- Dockerfile
35
+ | |-- main.py # FastAPI application logic, API endpoints
36
+ | |-- requirements.txt # Python dependencies
37
+ |-- static/
38
+ | |-- script.js # Frontend JavaScript
39
+ | |-- style.css # Frontend CSS
40
+ |-- templates/
41
+ | |-- index.html # Frontend HTML structure
42
+ |-- uploads/ # Temporary storage for uploaded files (created by app)
43
+ |-- project_report.md # This report
44
+ |-- deployment_guide.md # Deployment instructions
45
+ |-- project_details.txt # Original project requirements
46
+ ```
47
+
48
+ ### 3.3. API Endpoints
49
+
50
+ * **`GET /`**
51
+ * **Description:** Serves the main HTML frontend page (`index.html`).
52
+ * **Response:** `HTMLResponse` containing the rendered HTML.
53
+ * **`POST /translate/text`**
54
+ * **Description:** Translates a snippet of text provided in the request body.
55
+ * **Request Body (Form Data):**
56
+ * `text` (str): The text to translate.
57
+ * `source_lang` (str): The source language code (e.g., 'en', 'fr', 'ar'). 'auto' might be supported depending on the model.
58
+ * `target_lang` (str): The target language code (currently fixed to 'ar').
59
+ * **Response (`JSONResponse`):**
60
+ * `translated_text` (str): The translated text.
61
+ * `source_lang` (str): The detected or provided source language.
62
+ * **Error Responses:** `400 Bad Request` (e.g., missing text), `500 Internal Server Error` (translation failure), `501 Not Implemented` (if required libraries missing).
63
+ * **`POST /translate/document`**
64
+ * **Description:** Uploads a document, extracts its text, and translates it.
65
+ * **Request Body (Multipart Form Data):**
66
+ * `file` (UploadFile): The document file (.pdf, .docx, .xlsx, .pptx, .txt).
67
+ * `source_lang` (str): The source language code.
68
+ * `target_lang` (str): The target language code (currently fixed to 'ar').
69
+ * **Response (`JSONResponse`):**
70
+ * `original_filename` (str): The name of the uploaded file.
71
+ * `detected_source_lang` (str): The detected or provided source language.
72
+ * `translated_text` (str): The translated text extracted from the document.
73
+ * **Error Responses:** `400 Bad Request` (e.g., no file, unsupported file type), `500 Internal Server Error` (extraction or translation failure), `501 Not Implemented` (if required libraries missing).
74
+
75
+ ### 3.4. Dependencies
76
+
77
+ Key Python libraries used:
78
+
79
+ * `fastapi`: Web framework.
80
+ * `uvicorn`: ASGI server.
81
+ * `python-multipart`: For handling form data (file uploads).
82
+ * `jinja2`: For HTML templating.
83
+ * `transformers`: For interacting with Hugging Face models.
84
+ * `torch` (or `tensorflow`): Backend for `transformers`.
85
+ * `sentencepiece`, `sacremoses`: Often required by translation models.
86
+ * `PyMuPDF`: For PDF text extraction.
87
+ * `python-docx`: For DOCX text extraction.
88
+ * `openpyxl`: For XLSX text extraction.
89
+ * `python-pptx`: For PPTX text extraction.
90
+
91
+ *(List specific versions from requirements.txt if necessary)*
92
+
93
+ ### 3.5. Data Flow
94
+
95
+ 1. **User Interaction:** User accesses the web page served by `GET /`.
96
+ 2. **Text Input:** User enters text, selects languages, and submits the text form.
97
+ 3. **Text API Call:** Frontend JS sends a `POST` request to `/translate/text` with form data.
98
+ 4. **Text Backend Processing:** FastAPI receives the request, calls the internal translation function (using the AI model via `transformers`), and returns the result.
99
+ 5. **Document Upload:** User selects a document, selects languages, and submits the document form.
100
+ 6. **Document API Call:** Frontend JS sends a `POST` request to `/translate/document` with multipart form data.
101
+ 7. **Document Backend Processing:** FastAPI receives the file, saves it temporarily, extracts text using appropriate libraries (PyMuPDF, python-docx, etc.), calls the internal translation function, cleans up the temporary file, and returns the result.
102
+ 8. **Response Handling:** Frontend JS receives the JSON response and updates the UI to display the translation or an error message.
103
+
104
+ ## 4. Prompt Engineering and Optimization
105
+
106
+ ### 4.1. Initial Prompt Design
107
+
108
+ The core requirement is to translate *from* a source language *to* Arabic (MSA Fusha) with a focus on meaning and eloquence (Balagha), avoiding overly literal translations.
109
+
110
+ The initial prompt structure designed for the `translate_text_internal` function is:
111
+
112
+ ```
113
+ Translate the following text from {source_lang} to Arabic (Modern Standard Arabic - Fusha) precisely. Do not provide a literal translation; focus on conveying the meaning accurately while respecting Arabic eloquence (balagha) by rephrasing if necessary:
114
+
115
+ {text}
116
+ ```
117
+
118
+ ### 4.2. Rationale
119
+
120
+ * **Explicit Target:** Specifies "Arabic (Modern Standard Arabic - Fusha)" to guide the model towards the desired dialect and register.
121
+ * **Precision Instruction:** "precisely" encourages accuracy.
122
+ * **Constraint against Literal Translation:** "Do not provide a literal translation" directly addresses a potential pitfall.
123
+ * **Focus on Meaning:** "focus on conveying the meaning accurately" sets the primary goal.
124
+ * **Eloquence (Balagha):** "respecting Arabic eloquence (balagha)" introduces the key stylistic requirement.
125
+ * **Mechanism:** "by rephrasing if necessary" suggests *how* to achieve non-literal translation and eloquence.
126
+ * **Clear Input:** `{text}` placeholder clearly separates the instruction from the input text.
127
+ * **Source Language Context:** `{source_lang}` provides context, which can be crucial for disambiguation.
128
+
129
+ ### 4.3. Testing and Refinement (Planned/Hypothetical)
130
+
131
+ *(This section would be filled in after actual model integration and testing)*
132
+
133
+ * **Model Selection:** The choice of model (e.g., a fine-tuned NLLB model, AraT5, or a large multilingual model like Qwen or Llama adapted for translation) will significantly impact performance. Initial tests would involve selecting a candidate model from Hugging Face Hub known for strong multilingual or English-Arabic capabilities.
134
+ * **Baseline Test:** Translate sample sentences/paragraphs using the initial prompt and evaluate the output quality based on accuracy, fluency, and adherence to Balagha principles.
135
+ * **Prompt Variations:**
136
+ * *Simpler Prompts:* Test shorter prompts (e.g., "Translate to eloquent MSA Arabic: {text}") to see if the model can infer the constraints.
137
+ * *More Explicit Examples (Few-Shot):* If needed, add examples within the prompt (though this increases complexity and token count): "Translate ... Example: 'Hello world' -> 'مرحباً بالعالم' (eloquent). Input: {text}"
138
+ * *Emphasis:* Use different phrasing or emphasis (e.g., "Prioritize conveying the core meaning over word-for-word translation.")
139
+ * **Parameter Tuning:** Experiment with model generation parameters (e.g., `temperature`, `top_k`, `num_beams` if using beam search) available through the `transformers` pipeline or `generate` method to influence output style and creativity.
140
+ * **Evaluation Metrics:**
141
+ * *Human Evaluation:* Subjective assessment by Arabic speakers focusing on accuracy, naturalness, and eloquence.
142
+ * *Automated Metrics (with caution):* BLEU, METEOR scores against reference translations (if available), primarily for tracking relative improvements during iteration, acknowledging their limitations for stylistic nuances like Balagha.
143
+ * **Final Prompt Justification:** Based on the tests, the prompt that consistently produces the best balance of accurate meaning and desired Arabic style will be chosen. The current prompt is a strong starting point based on explicitly stating all requirements.
144
+
145
+ ## 5. Frontend Design and User Experience
146
+
147
+ ### 5.1. Design Choices
148
+
149
+ * **Simplicity:** A clean, uncluttered interface with two main sections: one for text translation and one for document translation.
150
+ * **Standard HTML Elements:** Uses standard forms, labels, text areas, select dropdowns, and buttons for familiarity.
151
+ * **Clear Separation:** Distinct forms and result areas for text vs. document translation.
152
+ * **Feedback:** Provides visual feedback during processing (disabling buttons, changing text) and displays results or errors clearly.
153
+ * **Responsiveness (Basic):** Includes basic CSS media queries for better usability on smaller screens.
154
+
155
+ ### 5.2. UI/UX Considerations
156
+
157
+ * **Workflow:** Intuitive flow – select languages, input text/upload file, click translate, view result.
158
+ * **Language Selection:** Dropdowns for selecting source and target languages. Includes common languages and an option for Arabic as a source (for potential future reverse translation). 'Auto-Detect' is included but noted as not yet implemented.
159
+ * **File Input:** Standard file input restricted to supported types (`accept` attribute).
160
+ * **Error Handling:** Displays clear error messages in a dedicated area if API calls fail or validation issues occur.
161
+ * **Result Display:** Uses `<pre><code>` for potentially long translated text, preserving formatting and allowing wrapping. Results for Arabic are displayed RTL. Document results include filename and detected source language.
162
+
163
+ ### 5.3. Interactivity (JavaScript)
164
+
165
+ * Handles form submissions asynchronously using `fetch`.
166
+ * Prevents default form submission behavior.
167
+ * Provides loading state feedback on buttons.
168
+ * Parses JSON responses from the backend.
169
+ * Updates the DOM to display translated text or error messages.
170
+ * Clears previous results/errors before new submissions.
171
+
172
+ ## 6. Deployment and Scalability
173
+
174
+ ### 6.1. Dockerization
175
+
176
+ * **Base Image:** Uses an official `python:3.9-slim` image for a smaller footprint.
177
+ * **Dependency Management:** Copies `requirements.txt` and installs dependencies early to leverage Docker caching.
178
+ * **Code Copying:** Copies the necessary application code (`backend`, `templates`, `static`) into the container.
179
+ * **Directory Creation:** Ensures necessary directories (`templates`, `static`, `uploads`) exist within the container.
180
+ * **Port Exposure:** Exposes port 8000 (used by `uvicorn`).
181
+ * **Entrypoint:** Uses `uvicorn` to run the FastAPI application (`backend.main:app`), making it accessible on `0.0.0.0`.
182
+
183
+ *(See `backend/Dockerfile` for the exact implementation)*
184
+
185
+ ### 6.2. Hugging Face Spaces Deployment
186
+
187
+ * **Method:** Uses the Docker Space SDK option.
188
+ * **Configuration:** Requires creating a `README.md` file in the repository root with specific Hugging Face metadata (e.g., `sdk: docker`, `app_port: 8000`).
189
+ * **Repository:** The project code (including the `Dockerfile` and the `README.md` with HF metadata) needs to be pushed to a Hugging Face Hub repository (either model or space repo).
190
+ * **Build Process:** Hugging Face Spaces automatically builds the Docker image from the `Dockerfile` in the repository and runs the container.
191
+
192
+ *(See `deployment_guide.md` for detailed steps)*
193
+
194
+ ### 6.3. Scalability Considerations
195
+
196
+ * **Stateless API:** The API endpoints are designed to be stateless (apart from temporary file storage during upload processing), which aids horizontal scaling.
197
+ * **Model Loading:** The translation model is intended to be loaded once on application startup (currently placeholder) rather than per-request, improving performance. However, large models consume significant memory.
198
+ * **Hugging Face Spaces Resources:** Scalability on HF Spaces depends on the chosen hardware tier. Free tiers have limited resources (CPU, RAM). Larger models or high traffic may require upgrading to paid tiers.
199
+ * **Async Processing:** FastAPI's asynchronous nature allows handling multiple requests concurrently, improving I/O bound performance. CPU-bound tasks like translation itself might still block the event loop if not handled carefully (e.g., running in a separate thread pool if necessary, though `transformers` pipelines often manage this).
200
+ * **Database:** No database is currently used. If user accounts or saved translations were added, a database would be needed, adding another scaling dimension.
201
+ * **Load Balancing:** For high availability and scaling beyond a single container, a load balancer and multiple container instances would be required (typically managed by orchestration platforms like Kubernetes, which is beyond the basic HF Spaces setup).
202
+
203
+ ## 7. Challenges and Future Work
204
+
205
+ ### 7.1. Challenges
206
+
207
+ * **Model Selection:** Finding the optimal balance between translation quality (especially for Balagha), performance (speed/resource usage), and licensing.
208
+ * **Prompt Engineering:** Iteratively refining the prompt to consistently achieve the desired non-literal, eloquent translation style across diverse inputs.
209
+ * **Resource Constraints:** Large translation models require significant RAM and potentially GPU resources, which might be limiting on free deployment tiers.
210
+ * **Document Parsing Robustness:** Handling variations and potential errors in different document formats and encodings.
211
+ * **Language Detection:** Implementing reliable automatic source language detection if the 'auto' option is fully developed.
212
+
213
+ ### 7.2. Future Work
214
+
215
+ * **Implement Actual Translation:** Replace placeholder logic with a real Hugging Face `transformers` pipeline using a selected model.
216
+ * **Implement Reverse Translation:** Add functionality and models to translate *from* Arabic *to* other languages.
217
+ * **Improve Error Handling:** Provide more specific user feedback for different error types.
218
+ * **Add User Accounts:** Allow users to save translation history.
219
+ * **Implement Language Auto-Detection:** Integrate a library (e.g., `langdetect`, `fasttext`) for the 'auto' source language option.
220
+ * **Enhance UI/UX:** Improve visual design, add loading indicators, potentially show translation progress for large documents.
221
+ * **Optimize Performance:** Profile the application and optimize bottlenecks, potentially exploring model quantization or different model architectures if needed.
222
+ * **Add More Document Types:** Support additional formats if required.
223
+ * **Testing:** Implement unit and integration tests for backend logic.
224
+
225
+ ## 8. Conclusion
226
+
227
+ This project successfully lays the foundation for an AI-powered translation web service focusing on high-quality Arabic translation. The FastAPI backend provides a robust API, and the frontend offers a simple interface for text and document translation. Dockerization ensures portability and simplifies deployment to platforms like Hugging Face Spaces. Key next steps involve integrating a suitable translation model and refining the prompt engineering based on real-world testing.
static/script.js ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener('DOMContentLoaded', () => {
2
+ const textForm = document.getElementById('text-translation-form');
3
+ const docForm = document.getElementById('doc-translation-form');
4
+ const textResultBox = document.getElementById('text-result');
5
+ const textOutput = document.getElementById('text-output');
6
+ const docResultBox = document.getElementById('doc-result');
7
+ const docOutput = document.getElementById('doc-output');
8
+ const docFilename = document.getElementById('doc-filename');
9
+ const docSourceLang = document.getElementById('doc-source-lang');
10
+ const errorMessageDiv = document.getElementById('error-message');
11
+
12
+ // Helper function to display errors
13
+ function displayError(message) {
14
+ errorMessageDiv.textContent = `Error: ${message}`;
15
+ errorMessageDiv.style.display = 'block';
16
+ // Hide result boxes on error
17
+ textResultBox.style.display = 'none';
18
+ docResultBox.style.display = 'none';
19
+ }
20
+
21
+ // Helper function to clear errors and results
22
+ function clearFeedback() {
23
+ errorMessageDiv.style.display = 'none';
24
+ errorMessageDiv.textContent = '';
25
+ textResultBox.style.display = 'none';
26
+ textOutput.textContent = '';
27
+ docResultBox.style.display = 'none';
28
+ docOutput.textContent = '';
29
+ docFilename.textContent = '';
30
+ docSourceLang.textContent = '';
31
+ }
32
+
33
+ // Handle Text Translation Form Submission
34
+ textForm.addEventListener('submit', async (event) => {
35
+ event.preventDefault();
36
+ clearFeedback();
37
+
38
+ const formData = new FormData(textForm);
39
+ const button = textForm.querySelector('button');
40
+ button.disabled = true;
41
+ button.textContent = 'Translating...';
42
+
43
+ try {
44
+ const response = await fetch('/translate/text', {
45
+ method: 'POST',
46
+ body: formData
47
+ });
48
+
49
+ if (!response.ok) {
50
+ const errorData = await response.json();
51
+ throw new Error(errorData.detail || `HTTP error! status: ${response.status}`);
52
+ }
53
+
54
+ const result = await response.json();
55
+ textOutput.textContent = result.translated_text;
56
+ textResultBox.style.display = 'block';
57
+ // Optionally update language direction based on result if needed
58
+ // textResultBox.dir = result.target_lang === 'ar' ? 'rtl' : 'ltr';
59
+
60
+ } catch (error) {
61
+ console.error('Text translation error:', error);
62
+ displayError(error.message || 'An unexpected error occurred during text translation.');
63
+ } finally {
64
+ button.disabled = false;
65
+ button.textContent = 'Translate Text';
66
+ }
67
+ });
68
+
69
+ // Handle Document Translation Form Submission
70
+ docForm.addEventListener('submit', async (event) => {
71
+ event.preventDefault();
72
+ clearFeedback();
73
+
74
+ const formData = new FormData(docForm);
75
+ const fileInput = document.getElementById('doc-input');
76
+ const button = docForm.querySelector('button');
77
+
78
+ if (!fileInput.files || fileInput.files.length === 0) {
79
+ displayError('Please select a document to upload.');
80
+ return;
81
+ }
82
+
83
+ button.disabled = true;
84
+ button.textContent = 'Translating...';
85
+
86
+ try {
87
+ const response = await fetch('/translate/document', {
88
+ method: 'POST',
89
+ body: formData // FormData handles multipart/form-data automatically
90
+ });
91
+
92
+ if (!response.ok) {
93
+ const errorData = await response.json();
94
+ throw new Error(errorData.detail || `HTTP error! status: ${response.status}`);
95
+ }
96
+
97
+ const result = await response.json();
98
+ docFilename.textContent = result.original_filename || 'N/A';
99
+ docSourceLang.textContent = result.detected_source_lang || 'N/A';
100
+ docOutput.textContent = result.translated_text;
101
+ docResultBox.style.display = 'block';
102
+ // Optionally update language direction based on result if needed
103
+ // docResultBox.dir = result.target_lang === 'ar' ? 'rtl' : 'ltr';
104
+
105
+ } catch (error) {
106
+ console.error('Document translation error:', error);
107
+ displayError(error.message || 'An unexpected error occurred during document translation.');
108
+ } finally {
109
+ button.disabled = false;
110
+ button.textContent = 'Translate Document';
111
+ }
112
+ });
113
+ });
static/style.css ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ font-family: sans-serif;
3
+ margin: 20px;
4
+ background-color: #f4f4f4;
5
+ line-height: 1.6;
6
+ }
7
+
8
+ h1 {
9
+ text-align: center;
10
+ color: #333;
11
+ }
12
+
13
+ .container {
14
+ background: #fff;
15
+ padding: 20px;
16
+ margin-bottom: 20px;
17
+ border-radius: 8px;
18
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
19
+ }
20
+
21
+ h2 {
22
+ color: #555;
23
+ border-bottom: 1px solid #eee;
24
+ padding-bottom: 10px;
25
+ margin-top: 0;
26
+ }
27
+
28
+ .input-group {
29
+ margin-bottom: 15px;
30
+ }
31
+
32
+ label {
33
+ display: block;
34
+ margin-bottom: 5px;
35
+ font-weight: bold;
36
+ color: #333;
37
+ }
38
+
39
+ select,
40
+ textarea,
41
+ input[type="file"] {
42
+ width: 100%;
43
+ padding: 10px;
44
+ border: 1px solid #ccc;
45
+ border-radius: 4px;
46
+ box-sizing: border-box; /* Prevents padding from adding to width */
47
+ }
48
+
49
+ textarea {
50
+ min-height: 100px;
51
+ resize: vertical;
52
+ }
53
+
54
+ button {
55
+ background-color: #5cb85c;
56
+ color: white;
57
+ padding: 10px 15px;
58
+ border: none;
59
+ border-radius: 4px;
60
+ cursor: pointer;
61
+ font-size: 1em;
62
+ transition: background-color 0.3s ease;
63
+ }
64
+
65
+ button:hover {
66
+ background-color: #4cae4c;
67
+ }
68
+
69
+ .result-box {
70
+ margin-top: 20px;
71
+ padding: 15px;
72
+ background-color: #e9e9e9;
73
+ border: 1px solid #ddd;
74
+ border-radius: 4px;
75
+ min-height: 50px;
76
+ }
77
+
78
+ .result-box h3 {
79
+ margin-top: 0;
80
+ color: #333;
81
+ }
82
+
83
+ pre {
84
+ white-space: pre-wrap; /* Allows text to wrap */
85
+ word-wrap: break-word; /* Breaks long words */
86
+ background: #f9f9f9;
87
+ padding: 10px;
88
+ border-radius: 4px;
89
+ }
90
+
91
+ code {
92
+ font-family: monospace;
93
+ font-size: 0.95em;
94
+ }
95
+
96
+ .error-box {
97
+ margin-top: 20px;
98
+ padding: 15px;
99
+ background-color: #f2dede;
100
+ border: 1px solid #ebccd1;
101
+ color: #a94442;
102
+ border-radius: 4px;
103
+ }
104
+
105
+ /* RTL support for results */
106
+ [dir="rtl"] {
107
+ text-align: right;
108
+ }
109
+
110
+ /* Basic responsiveness */
111
+ @media (max-width: 600px) {
112
+ body {
113
+ margin: 10px;
114
+ }
115
+ .container {
116
+ padding: 15px;
117
+ }
118
+ }
templates/index.html ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en" dir="ltr"> <!- Default to LTR, can be changed dynamically ->
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AI Translator</title>
7
+ <link rel="stylesheet" href="/static/style.css">
8
+ </head>
9
+ <body>
10
+ <h1>AI Translation Service</h1>
11
+
12
+ <div class="container">
13
+ <h2>Direct Text Translation</h2>
14
+ <form id="text-translation-form">
15
+ <div class="input-group">
16
+ <label for="source-lang-text">Source Language:</label>
17
+ <select id="source-lang-text" name="source_lang">
18
+ <option value="en">English</option>
19
+ <option value="fr">French</option>
20
+ <option value="es">Spanish</option>
21
+ <option value="de">German</option>
22
+ <option value="ar">Arabic</option> <!- Added Arabic as source ->
23
+ <option value="auto">Auto-Detect (Not implemented)</option>
24
+ <!- Add more languages as needed ->
25
+ </select>
26
+ </div>
27
+ <div class="input-group">
28
+ <label for="target-lang-text">Target Language:</label>
29
+ <select id="target-lang-text" name="target_lang">
30
+ <option value="ar">Arabic (MSA Fusha)</option>
31
+ <!- Add other target languages if reverse translation is implemented ->
32
+ <!- <option value="en">English</option> ->
33
+ </select>
34
+ </div>
35
+ <textarea id="text-input" name="text" placeholder="Enter text to translate..."></textarea>
36
+ <button type="submit">Translate Text</button>
37
+ </form>
38
+ <div id="text-result" class="result-box" dir="rtl"> <!- Set default to RTL for Arabic output ->
39
+ <h3>Translation:</h3>
40
+ <pre><code id="text-output"></code></pre>
41
+ </div>
42
+ </div>
43
+
44
+ <div class="container">
45
+ <h2>Document Translation</h2>
46
+ <form id="doc-translation-form" enctype="multipart/form-data">
47
+ <div class="input-group">
48
+ <label for="source-lang-doc">Source Language:</label>
49
+ <select id="source-lang-doc" name="source_lang">
50
+ <option value="en">English</option>
51
+ <option value="fr">French</option>
52
+ <option value="es">Spanish</option>
53
+ <option value="de">German</option>
54
+ <option value="ar">Arabic</option> <!- Added Arabic as source ->
55
+ <option value="auto">Auto-Detect (Not implemented)</option>
56
+ <!- Add more languages as needed ->
57
+ </select>
58
+ </div>
59
+ <div class="input-group">
60
+ <label for="target-lang-doc">Target Language:</label>
61
+ <select id="target-lang-doc" name="target_lang">
62
+ <option value="ar">Arabic (MSA Fusha)</option>
63
+ <!- Add other target languages if reverse translation is implemented ->
64
+ <!- <option value="en">English</option> ->
65
+ </select>
66
+ </div>
67
+ <div class="input-group">
68
+ <label for="doc-input">Upload Document (.pdf, .docx, .xlsx, .pptx, .txt):</label>
69
+ <input type="file" id="doc-input" name="file" accept=".pdf,.docx,.xlsx,.pptx,.txt">
70
+ </div>
71
+ <button type="submit">Translate Document</button>
72
+ </form>
73
+ <div id="doc-result" class="result-box" dir="rtl"> <!- Set default to RTL for Arabic output ->
74
+ <h3>Translation:</h3>
75
+ <p>Original Filename: <span id="doc-filename"></span></p>
76
+ <p>Detected Source Language: <span id="doc-source-lang"></span></p>
77
+ <pre><code id="doc-output"></code></pre>
78
+ </div>
79
+ </div>
80
+
81
+ <div id="error-message" class="error-box" style="display: none;"></div>
82
+
83
+ <script src="/static/script.js"></script>
84
+ </body>
85
+ </html>