Merge pull request #437 from christianlouis/copilot/add-file-download-endpoint
fix(api): change download endpoint default version from `original` to `processed`
This commit is contained in:
+3
-3
@@ -968,14 +968,14 @@ def download_file(
|
|||||||
request: Request,
|
request: Request,
|
||||||
file_id: int,
|
file_id: int,
|
||||||
db: DbSession,
|
db: DbSession,
|
||||||
version: str = Query("original", description="original or processed"),
|
version: str = Query("processed", description="'processed' (default) or 'original'"),
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Download file (original or processed version) as attachment.
|
Download file (processed or original version) as attachment.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
file_id: ID of the file
|
file_id: ID of the file
|
||||||
version: "original" for tmp file, "processed" for processed file
|
version: "processed" (default) for the post-processing file, "original" for the raw upload
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
File content as attachment download
|
File content as attachment download
|
||||||
|
|||||||
+26
@@ -487,6 +487,32 @@ curl "http://<your-instance>/api/files/123/preview?version=processed"
|
|||||||
- `404`: File not found in database or on disk
|
- `404`: File not found in database or on disk
|
||||||
- `400`: Invalid version parameter
|
- `400`: Invalid version parameter
|
||||||
|
|
||||||
|
### File Download
|
||||||
|
|
||||||
|
**GET** `/api/files/{file_id}/download`
|
||||||
|
|
||||||
|
Download a file as an attachment. The `Content-Disposition` header is set to `attachment` with the original filename so the browser prompts a save dialog.
|
||||||
|
|
||||||
|
**Parameters**:
|
||||||
|
- `version` (optional, default: `processed`): Either `processed` or `original`
|
||||||
|
- `processed` *(default)*: Downloads the post-processing file (with embedded metadata)
|
||||||
|
- `original`: Downloads the raw file as originally uploaded
|
||||||
|
|
||||||
|
**Response**: File content with `Content-Disposition: attachment; filename="<original_filename>"`.
|
||||||
|
|
||||||
|
**Example**:
|
||||||
|
```bash
|
||||||
|
# Download processed file (default)
|
||||||
|
curl -OJ "http://<your-instance>/api/files/123/download"
|
||||||
|
|
||||||
|
# Download original upload
|
||||||
|
curl -OJ "http://<your-instance>/api/files/123/download?version=original"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Responses**:
|
||||||
|
- `404`: File not found in database or on disk
|
||||||
|
- `400`: Invalid `version` parameter (must be `processed` or `original`)
|
||||||
|
|
||||||
### Batch Processing
|
### Batch Processing
|
||||||
|
|
||||||
**POST** `/api/processall`
|
**POST** `/api/processall`
|
||||||
|
|||||||
@@ -663,6 +663,66 @@ class TestFileDownload:
|
|||||||
response = client.get("/api/files/99999/download?version=original")
|
response = client.get("/api/files/99999/download?version=original")
|
||||||
assert response.status_code == 404
|
assert response.status_code == 404
|
||||||
|
|
||||||
|
def test_download_processed_file_success(self, client: TestClient, db_session, tmp_path):
|
||||||
|
"""Test downloading processed file via ?version=processed."""
|
||||||
|
processed_dir = tmp_path / "processed"
|
||||||
|
processed_dir.mkdir()
|
||||||
|
processed_file = processed_dir / "test.pdf"
|
||||||
|
processed_file.write_bytes(b"%PDF-1.4 processed")
|
||||||
|
|
||||||
|
file = FileRecord(
|
||||||
|
filehash="hashproc",
|
||||||
|
original_filename="test.pdf",
|
||||||
|
local_filename=str(tmp_path / "test.pdf"),
|
||||||
|
processed_file_path=str(processed_file),
|
||||||
|
file_size=1024,
|
||||||
|
mime_type="application/pdf",
|
||||||
|
)
|
||||||
|
db_session.add(file)
|
||||||
|
db_session.commit()
|
||||||
|
|
||||||
|
response = client.get(f"/api/files/{file.id}/download?version=processed")
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert "attachment" in response.headers["content-disposition"]
|
||||||
|
assert "test.pdf" in response.headers["content-disposition"]
|
||||||
|
|
||||||
|
def test_download_default_returns_processed(self, client: TestClient, db_session, tmp_path):
|
||||||
|
"""Test that GET /download without ?version defaults to the processed file."""
|
||||||
|
processed_dir = tmp_path / "processed"
|
||||||
|
processed_dir.mkdir()
|
||||||
|
processed_file = processed_dir / "default.pdf"
|
||||||
|
processed_file.write_bytes(b"%PDF-1.4 default")
|
||||||
|
|
||||||
|
file = FileRecord(
|
||||||
|
filehash="hashdefault",
|
||||||
|
original_filename="default.pdf",
|
||||||
|
local_filename=str(tmp_path / "default.pdf"),
|
||||||
|
processed_file_path=str(processed_file),
|
||||||
|
file_size=1024,
|
||||||
|
mime_type="application/pdf",
|
||||||
|
)
|
||||||
|
db_session.add(file)
|
||||||
|
db_session.commit()
|
||||||
|
|
||||||
|
response = client.get(f"/api/files/{file.id}/download")
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert "attachment" in response.headers["content-disposition"]
|
||||||
|
|
||||||
|
def test_download_invalid_version_returns_400(self, client: TestClient, db_session):
|
||||||
|
"""Test that an invalid ?version value returns HTTP 400."""
|
||||||
|
file = FileRecord(
|
||||||
|
filehash="hashinv",
|
||||||
|
original_filename="test.pdf",
|
||||||
|
local_filename="/nonexistent/test.pdf",
|
||||||
|
file_size=1024,
|
||||||
|
mime_type="application/pdf",
|
||||||
|
)
|
||||||
|
db_session.add(file)
|
||||||
|
db_session.commit()
|
||||||
|
|
||||||
|
response = client.get(f"/api/files/{file.id}/download?version=invalid")
|
||||||
|
assert response.status_code == 400
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
class TestUIUpload:
|
class TestUIUpload:
|
||||||
@@ -1149,6 +1209,6 @@ class TestAdditionalFileOperations:
|
|||||||
db_session.add(file)
|
db_session.add(file)
|
||||||
db_session.commit()
|
db_session.commit()
|
||||||
|
|
||||||
response = client.get(f"/api/files/{file.id}/download")
|
response = client.get(f"/api/files/{file.id}/download?version=original")
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
# Should default to application/pdf
|
# Should default to application/pdf
|
||||||
|
|||||||
Reference in New Issue
Block a user