Add support for UploadFile class annotations (#63)

*  Add support for UploadFile annotations

* 📝 Update File upload docs with FileUpload class

*  Add tests for UploadFile support

* 📝 Update UploadFile docs
This commit is contained in:
Sebastián Ramírez
2019-03-03 20:52:37 +04:00
committed by GitHub
parent 1f03e85f06
commit 0b9fe62a10
11 changed files with 224 additions and 26 deletions

View File

@@ -39,7 +39,39 @@ openapi_schema = {
"required": True,
},
}
}
},
"/uploadfile/": {
"post": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"summary": "Create Upload File Post",
"operationId": "create_upload_file_uploadfile__post",
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"$ref": "#/components/schemas/Body_create_upload_file"
}
}
},
"required": True,
},
}
},
},
"components": {
"schemas": {
@@ -51,6 +83,14 @@ openapi_schema = {
"file": {"title": "File", "type": "string", "format": "binary"}
},
},
"Body_create_upload_file": {
"title": "Body_create_upload_file",
"required": ["file"],
"type": "object",
"properties": {
"file": {"title": "File", "type": "string", "format": "binary"}
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
@@ -131,3 +171,14 @@ def test_post_large_file(tmpdir):
response = client.post("/files/", files={"file": open(path, "rb")})
assert response.status_code == 200
assert response.json() == {"file_size": default_pydantic_max_size + 1}
def test_post_upload_file(tmpdir):
path = os.path.join(tmpdir, "test.txt")
with open(path, "wb") as file:
file.write(b"<file content>")
client = TestClient(app)
response = client.post("/uploadfile/", files={"file": open(path, "rb")})
assert response.status_code == 200
assert response.json() == {"filename": "test.txt"}

View File

@@ -1,4 +1,5 @@
import os
from pathlib import Path
from starlette.testclient import TestClient
@@ -45,10 +46,11 @@ openapi_schema = {
"schemas": {
"Body_create_file": {
"title": "Body_create_file",
"required": ["file", "token"],
"required": ["file", "fileb", "token"],
"type": "object",
"properties": {
"file": {"title": "File", "type": "string", "format": "binary"},
"fileb": {"title": "Fileb", "type": "string", "format": "binary"},
"token": {"title": "Token", "type": "string"},
},
},
@@ -94,20 +96,32 @@ file_required = {
"loc": ["body", "file"],
"msg": "field required",
"type": "value_error.missing",
}
},
{
"loc": ["body", "fileb"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
token_required = {
"detail": [
{
"loc": ["body", "fileb"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "token"],
"msg": "field required",
"type": "value_error.missing",
}
},
]
}
# {'detail': [, {'loc': ['body', 'token'], 'msg': 'field required', 'type': 'value_error.missing'}]}
file_and_token_required = {
"detail": [
{
@@ -115,6 +129,11 @@ file_and_token_required = {
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "fileb"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "token"],
"msg": "field required",
@@ -153,14 +172,24 @@ def test_post_file_no_token(tmpdir):
assert response.json() == token_required
def test_post_file_and_token(tmpdir):
path = os.path.join(tmpdir, "test.txt")
with open(path, "wb") as file:
file.write(b"<file content>")
def test_post_files_and_token(tmpdir):
patha = Path(tmpdir) / "test.txt"
pathb = Path(tmpdir) / "testb.txt"
patha.write_text("<file content>")
pathb.write_text("<file b content>")
client = TestClient(app)
response = client.post(
"/files/", data={"token": "foo"}, files={"file": open(path, "rb")}
"/files/",
data={"token": "foo"},
files={
"file": patha.open("rb"),
"fileb": ("testb.txt", pathb.open("rb"), "text/plain"),
},
)
assert response.status_code == 200
assert response.json() == {"file_size": 14, "token": "foo"}
assert response.json() == {
"file_size": 14,
"token": "foo",
"fileb_content_type": "text/plain",
}