Skip to content

Commit

Permalink
Load all images at once
Browse files Browse the repository at this point in the history
  • Loading branch information
kompoth committed Apr 3, 2024
1 parent 89b6967 commit 2012293
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 36 deletions.
46 changes: 32 additions & 14 deletions muckraker/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from pathlib import Path
from shutil import rmtree
from tempfile import gettempdir, mkdtemp
from typing import List

import aiofiles
from fastapi import Depends, FastAPI, File, Response, UploadFile
Expand Down Expand Up @@ -47,23 +48,40 @@ async def dir_path(issue_id: str):
@app.patch("/issue/{issue_id}")
async def patch_s_issue(
dir_path: Path = Depends(dir_path),
image: UploadFile = File()
images: List[UploadFile] = File()
):
# Validate image
if image.content_type not in ACCEPTED_FILE_TYPES:
detail = f"Invalid file type: {image.filename}"
# Check if there are already images
uploaded_files = dir_path.glob('**/*')
uploaded_images = [
x for x in uploaded_files
if x.is_file() and x.suffix in IMAGE_SUFFIXES
]
if len(uploaded_images) > 0:
rmtree(dir_path)
raise HTTPException(415, detail=detail)
if image.size > MAX_IMAGE_SIZE:
detail = f"File is too large: {image.filename}"
rmtree(dir_path)
raise HTTPException(413, detail=detail)
raise HTTPException(429, detail="To many uploads")

# Save image to the disk
image_path = dir_path / image.filename
async with aiofiles.open(image_path, "wb") as fd:
while content := await image.read(IMAGE_BATCH):
await fd.write(content)
# Validate number of images
if len(images) > MAX_IMAGE_NUM:
rmtree(dir_path)
raise HTTPException(413, detail="To many images")

# Validate images
for image in images:
if image.content_type not in ACCEPTED_FILE_TYPES:
detail = f"Invalid file type: {image.filename}"
rmtree(dir_path)
raise HTTPException(415, detail=detail)
if image.size > MAX_IMAGE_SIZE:
detail = f"File is too large: {image.filename}"
rmtree(dir_path)
raise HTTPException(413, detail=detail)

# Save images to the disk
for image in images:
image_path = dir_path / image.filename
async with aiofiles.open(image_path, "wb") as fd:
while content := await image.read(IMAGE_BATCH):
await fd.write(content)
return JSONResponse(content={"filename": image.filename})


Expand Down
17 changes: 8 additions & 9 deletions static/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ async function generatePDF() {

var resp;
var respJson;
const resourceUrl = "/api/issue/";
//const resourceUrl = "http://127.0.0.1:8001/issue/";
//const resourceUrl = "/api/issue/";
const resourceUrl = "http://127.0.0.1:8001/issue/";

try {
resp = await fetch(resourceUrl, {
Expand All @@ -71,20 +71,19 @@ async function generatePDF() {
if (resp.ok) var issueId = respJson.issue_id
else throw new Error("Failed to send issue data");

const files = Array.from(
document.getElementById("image-input").files
).slice(0, 4);

await Promise.all(files.map(async (file) => {
const imageInput = document.getElementById("image-input");
if (imageInput.files.length > 0) {
var formData = new FormData();
formData.append("image", file, file.name);
Array.from(imageInput.files).slice(0, 4).forEach((file) => {
formData.append("images", file, file.name);
});
resp = await fetch(resourceUrl + issueId, {
method: "PATCH",
body: formData
});
respJson = await resp.json();
if (!resp.ok) throw new Error("Failed to send file");
}));
}

resp = await fetch(resourceUrl + issueId, {method: "GET"});
if (resp.ok) resp.blob().then(
Expand Down
38 changes: 25 additions & 13 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ def test_correct(issue_dict, good_image):
assert resp.status_code == 200
issue_id = resp.json()["issue_id"]

files = {"image": good_image}
files = {"images": good_image}
resp = client.patch(f"/issue/{issue_id}", files=files)
assert resp.status_code == 200

resp = client.get(f"/issue/{issue_id}") # Deletes tempdir
assert resp.status_code == 200
with open("file.pdf", "wb") as fd:
fd.write(resp.content)


def test_thick_body(issue_dict):
Expand Down Expand Up @@ -45,7 +43,7 @@ def test_thick_image(issue_dict, thick_image):
resp = client.post("/issue/", json=issue_dict)
issue_id = resp.json()["issue_id"]

files = {"image": thick_image}
files = {"images": thick_image}
# Deletes tempdir on 413
resp = client.patch(f"/issue/{issue_id}", files=files)
assert resp.status_code == 413
Expand All @@ -59,16 +57,30 @@ def test_issue_not_found(issue_dict, good_image):
resp = client.get(f"/issue/{issue_id}")
assert resp.status_code == 404

files = {"image": good_image}
files = {"images": good_image}
resp = client.patch(f"/issue/{issue_id}", files=files)
assert resp.status_code == 404


# def test_too_many_images(issue_dict, good_image):
# resp = client.post("/issue/", json=issue_dict)
# issue_id = resp.json()["issue_id"]
#
# for no in range(1, 5):
# files = {"image": (f"{no}.png", good_image)}
# resp = client.patch(f"/issue/{issue_id}", files=files)
# assert resp.status_code == 429
def test_multiple_images(issue_dict, good_image):
resp = client.post("/issue/", json=issue_dict)
issue_id = resp.json()["issue_id"]

# Send 4 images
files = [("images", (f"{no}.png", good_image)) for no in range(1, 5)]
resp = client.patch(f"/issue/{issue_id}", files=files)
assert resp.status_code == 200

resp = client.get(f"/issue/{issue_id}") # Deletes tempdir
assert resp.status_code == 200


def test_too_many_images(issue_dict, good_image):
resp = client.post("/issue/", json=issue_dict)
issue_id = resp.json()["issue_id"]

# Send 5 images
files = [("images", (f"{no}.png", good_image)) for no in range(1, 6)]
# Deletes tempdir on 413
resp = client.patch(f"/issue/{issue_id}", files=files)
assert resp.status_code == 413

0 comments on commit 2012293

Please sign in to comment.