-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
47 lines (42 loc) · 2.01 KB
/
Copy pathapp.py
File metadata and controls
47 lines (42 loc) · 2.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import io, os, uuid
from typing import List
from fastapi import FastAPI, File, UploadFile, Form, HTTPException
from fastapi.responses import StreamingResponse
from pptx import Presentation
from pptx.util import Inches
app = FastAPI(title="Images to PPT")
def build_ppt_from_uploads(files: List[UploadFile], fit="height", height_inches=6.5, margin_inches=0.5) -> bytes:
prs = Presentation()
blank = prs.slide_layouts[6]
for f in files:
if f.content_type and not f.content_type.startswith("image/"):
# allow only images
raise HTTPException(status_code=400, detail=f"Unsupported file type: {f.filename}")
img_bytes = f.file.read()
# write to temp on disk because python-pptx needs a file-like path or stream
temp_name = f"{uuid.uuid4()}_{f.filename or 'image'}"
with open(temp_name, "wb") as tmp:
tmp.write(img_bytes)
slide = prs.slides.add_slide(blank)
if fit == "height":
slide.shapes.add_picture(temp_name, Inches(margin_inches), Inches(margin_inches), height=Inches(height_inches))
else:
slide.shapes.add_picture(temp_name, Inches(margin_inches), Inches(margin_inches), width=Inches(10 - 2*margin_inches))
os.remove(temp_name)
bio = io.BytesIO()
prs.save(bio)
bio.seek(0)
return bio.getvalue()
@app.post("/make-ppt")
async def make_ppt(images: List[UploadFile] = File(...), filename: str = Form(default="presentation.pptx")):
if not images:
raise HTTPException(status_code=400, detail="No images uploaded.")
ppt_bytes = build_ppt_from_uploads(images)
return StreamingResponse(
io.BytesIO(ppt_bytes),
media_type="application/vnd.openxmlformats-officedocument.presentationml.presentation",
headers={"Content-Disposition": f'attachment; filename="{filename}"'}
)
@app.get("/")
def root():
return {"status": "ok", "usage": "POST /make-ppt with form-data: images=[files...] and optional filename"}