manuelcaccone commited on
Commit
978295b
·
verified ·
1 Parent(s): 50186b0

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. app.py +105 -3
  2. validator.py +26 -0
app.py CHANGED
@@ -1,10 +1,11 @@
1
- from fastapi import FastAPI, HTTPException
2
- from fastapi.responses import HTMLResponse
3
  from pydantic import BaseModel
4
  from pathlib import Path
5
  import uuid
6
  import shutil
7
- from validator import validate_rmd
 
8
 
9
  app = FastAPI(
10
  title="RMD Validator API",
@@ -156,6 +157,107 @@ async def validate_rmd_and_cleanup(rmd_data: RmdContent):
156
  shutil.rmtree(temp_dir, ignore_errors=True)
157
 
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  @app.delete("/cleanup/{request_id}")
160
  async def cleanup_request(request_id: str):
161
  temp_dir = Path(f"/app/temp/{request_id}")
 
1
+ from fastapi import FastAPI, HTTPException, BackgroundTasks
2
+ from fastapi.responses import HTMLResponse, FileResponse
3
  from pydantic import BaseModel
4
  from pathlib import Path
5
  import uuid
6
  import shutil
7
+ import subprocess
8
+ from validator import validate_rmd, render_rmd_format
9
 
10
  app = FastAPI(
11
  title="RMD Validator API",
 
157
  shutil.rmtree(temp_dir, ignore_errors=True)
158
 
159
 
160
+ def _prepare_rmd(rmd_data, temp_dir):
161
+ if not rmd_data.filename.endswith('.rmd'):
162
+ rmd_data.filename += '.rmd'
163
+ rmd_file = temp_dir / rmd_data.filename
164
+ rmd_file.write_text(rmd_data.content, encoding='utf-8')
165
+ return rmd_file
166
+
167
+
168
+ @app.post("/download/html")
169
+ async def download_html(rmd_data: RmdContent, background_tasks: BackgroundTasks):
170
+ request_id = str(uuid.uuid4())
171
+ temp_dir = Path(f"/app/temp/{request_id}")
172
+ temp_dir.mkdir(parents=True, exist_ok=True)
173
+
174
+ try:
175
+ rmd_file = _prepare_rmd(rmd_data, temp_dir)
176
+ render_rmd_format(str(rmd_file), 'html_document')
177
+
178
+ html_file = temp_dir / f"{rmd_file.stem}.html"
179
+ if not html_file.exists():
180
+ raise HTTPException(status_code=500, detail="HTML non generato")
181
+
182
+ background_tasks.add_task(shutil.rmtree, temp_dir, True)
183
+ return FileResponse(
184
+ path=str(html_file),
185
+ filename=f"{rmd_file.stem}.html",
186
+ media_type="text/html",
187
+ )
188
+
189
+ except subprocess.CalledProcessError as e:
190
+ shutil.rmtree(temp_dir, ignore_errors=True)
191
+ raise HTTPException(status_code=422, detail=f"Errore rendering: {e.stderr}")
192
+ except HTTPException:
193
+ raise
194
+ except Exception as e:
195
+ shutil.rmtree(temp_dir, ignore_errors=True)
196
+ raise HTTPException(status_code=500, detail=str(e))
197
+
198
+
199
+ @app.post("/download/pdf")
200
+ async def download_pdf(rmd_data: RmdContent, background_tasks: BackgroundTasks):
201
+ request_id = str(uuid.uuid4())
202
+ temp_dir = Path(f"/app/temp/{request_id}")
203
+ temp_dir.mkdir(parents=True, exist_ok=True)
204
+
205
+ try:
206
+ rmd_file = _prepare_rmd(rmd_data, temp_dir)
207
+ render_rmd_format(str(rmd_file), 'pdf_document')
208
+
209
+ pdf_file = temp_dir / f"{rmd_file.stem}.pdf"
210
+ if not pdf_file.exists():
211
+ raise HTTPException(status_code=500, detail="PDF non generato")
212
+
213
+ background_tasks.add_task(shutil.rmtree, temp_dir, True)
214
+ return FileResponse(
215
+ path=str(pdf_file),
216
+ filename=f"{rmd_file.stem}.pdf",
217
+ media_type="application/pdf",
218
+ )
219
+
220
+ except subprocess.CalledProcessError as e:
221
+ shutil.rmtree(temp_dir, ignore_errors=True)
222
+ raise HTTPException(status_code=422, detail=f"Errore rendering: {e.stderr}")
223
+ except HTTPException:
224
+ raise
225
+ except Exception as e:
226
+ shutil.rmtree(temp_dir, ignore_errors=True)
227
+ raise HTTPException(status_code=500, detail=str(e))
228
+
229
+
230
+ @app.post("/download/tex")
231
+ async def download_tex(rmd_data: RmdContent, background_tasks: BackgroundTasks):
232
+ request_id = str(uuid.uuid4())
233
+ temp_dir = Path(f"/app/temp/{request_id}")
234
+ temp_dir.mkdir(parents=True, exist_ok=True)
235
+
236
+ try:
237
+ rmd_file = _prepare_rmd(rmd_data, temp_dir)
238
+ render_rmd_format(str(rmd_file), 'latex_document')
239
+
240
+ tex_file = temp_dir / f"{rmd_file.stem}.tex"
241
+ if not tex_file.exists():
242
+ raise HTTPException(status_code=500, detail="LaTeX non generato")
243
+
244
+ background_tasks.add_task(shutil.rmtree, temp_dir, True)
245
+ return FileResponse(
246
+ path=str(tex_file),
247
+ filename=f"{rmd_file.stem}.tex",
248
+ media_type="application/x-tex",
249
+ )
250
+
251
+ except subprocess.CalledProcessError as e:
252
+ shutil.rmtree(temp_dir, ignore_errors=True)
253
+ raise HTTPException(status_code=422, detail=f"Errore rendering: {e.stderr}")
254
+ except HTTPException:
255
+ raise
256
+ except Exception as e:
257
+ shutil.rmtree(temp_dir, ignore_errors=True)
258
+ raise HTTPException(status_code=500, detail=str(e))
259
+
260
+
261
  @app.delete("/cleanup/{request_id}")
262
  async def cleanup_request(request_id: str):
263
  temp_dir = Path(f"/app/temp/{request_id}")
validator.py CHANGED
@@ -49,3 +49,29 @@ def validate_rmd(path):
49
  f.write(error_message)
50
 
51
  return status, error_message if status == 404 else "OK"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  f.write(error_message)
50
 
51
  return status, error_message if status == 404 else "OK"
52
+
53
+
54
+ def render_rmd_format(path, output_format):
55
+ rmd_path = Path(path)
56
+ if not rmd_path.is_file():
57
+ raise FileNotFoundError(f"File non trovato: {path}")
58
+
59
+ report_dir = rmd_path.parent
60
+
61
+ render_cmd = [
62
+ "Rscript", "--vanilla", "-e",
63
+ f"rmarkdown::render("
64
+ f"input = '{rmd_path.as_posix()}', "
65
+ f"output_format = '{output_format}', "
66
+ f"output_dir = '{report_dir.as_posix()}')"
67
+ ]
68
+
69
+ result = subprocess.run(
70
+ render_cmd,
71
+ check=True,
72
+ capture_output=True,
73
+ text=True,
74
+ encoding='utf-8'
75
+ )
76
+
77
+ return result