feat(backend): endpoint to download files by id (#21)

* feat(backend): endpoint to download files by id

* test(backend) coverage for file downloads
This commit is contained in:
Marc 2023-08-17 19:21:08 -04:00 committed by GitHub
parent 5010da18f5
commit 70224d0f28
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 1 deletions

View file

@ -8,7 +8,7 @@ files that live in the system.
import pathlib import pathlib
from fastapi import APIRouter, HTTPException, UploadFile from fastapi import APIRouter, HTTPException, UploadFile
from fastapi.responses import FileResponse
import use_cases.files as files_use_cases import use_cases.files as files_use_cases
from settings import settings from settings import settings
@ -46,6 +46,35 @@ def get_file_details(file_id: str):
return file return file
@router.get("/{file_id}/content/")
def get_file_content(file_id: str) -> FileResponse:
"""
Retrieves the file data associated with a given File ID.
This returns the file for download as a streamed file.
GET /files/{file_id}/content/
200 { <File> }
The file data is returned as a stream if the file exists.
404 {}
The file ID did not map to anything.
"""
file = files_use_cases.get_file_record_by_id(file_id)
if file is None:
raise HTTPException(status_code=404)
return FileResponse(
path=file["path"],
media_type="application/octet-stream",
filename=file["filename"],
)
@router.delete("/{file_id}/") @router.delete("/{file_id}/")
def delete_file(file_id: str) -> files_use_cases.FileRecord: def delete_file(file_id: str) -> files_use_cases.FileRecord:
""" """

View file

@ -92,3 +92,26 @@ def test_file_deletion_200_and_return_deleted_resource(client, tmp_path):
assert response.status_code == 200 assert response.status_code == 200
assert response.json() == response_data assert response.json() == response_data
def test_file_downloads_200_and_return_file(client, tmp_path):
mock_file = tmp_path / "test.txt"
mock_file.write_text("testtest")
with open(str(mock_file), "rb") as mock_file_stream:
response = client.post("/files/", files={"file": mock_file_stream})
response_data = response.json()
file_id = response_data["id"]
response = client.get(f"/files/{file_id}/content/")
assert response.status_code == 200
assert response.text == mock_file.read_text()
def test_file_downloads_404_if_does_not_exist(client):
non_existent_id = "06f02980-864d-4832-a894-2e9d2543a79a"
response = client.get(f"/files/{non_existent_id}/content/")
assert response.status_code == 404