Browse Source

🐛 Close FormData (uploaded files) after the request is done (#5465)

Co-authored-by: Sebastián Ramírez <[email protected]>
pull/5570/head
Adrian Garcia Badaracco 2 years ago
committed by GitHub
parent
commit
ac9f56ea5e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      fastapi/routing.py
  2. 28
      tests/test_datastructures.py

4
fastapi/routing.py

@ -3,6 +3,7 @@ import dataclasses
import email.message
import inspect
import json
from contextlib import AsyncExitStack
from enum import Enum, IntEnum
from typing import (
Any,
@ -190,6 +191,9 @@ def get_request_handler(
if body_field:
if is_body_form:
body = await request.form()
stack = request.scope.get("fastapi_astack")
assert isinstance(stack, AsyncExitStack)
stack.push_async_callback(body.close)
else:
body_bytes = await request.body()
if body_bytes:

28
tests/test_datastructures.py

@ -1,6 +1,10 @@
from pathlib import Path
from typing import List
import pytest
from fastapi import UploadFile
from fastapi import FastAPI, UploadFile
from fastapi.datastructures import Default
from fastapi.testclient import TestClient
def test_upload_file_invalid():
@ -20,3 +24,25 @@ def test_default_placeholder_bool():
placeholder_b = Default("")
assert placeholder_a
assert not placeholder_b
def test_upload_file_is_closed(tmp_path: Path):
path = tmp_path / "test.txt"
path.write_bytes(b"<file content>")
app = FastAPI()
testing_file_store: List[UploadFile] = []
@app.post("/uploadfile/")
def create_upload_file(file: UploadFile):
testing_file_store.append(file)
return {"filename": file.filename}
client = TestClient(app)
with path.open("rb") as file:
response = client.post("/uploadfile/", files={"file": file})
assert response.status_code == 200, response.text
assert response.json() == {"filename": "test.txt"}
assert testing_file_store
assert testing_file_store[0].file.closed

Loading…
Cancel
Save