반응형
Fast 테스트 방법이미지를 소비하는 API 끝점?
나는 Fast를 테스트하기 위해 pytest를 사용하고 있다.이진 형식으로 이미지를 입력하는 API 끝점
@app.post("/analyse")
async def analyse(file: bytes = File(...)):
image = Image.open(io.BytesIO(file)).convert("RGB")
stats = process_image(image)
return stats
서버를 시작한 후 다음과 같이 호출을 실행하여 엔드포인트를 수동으로 테스트할 수 있습니다.
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
url = "http://127.0.0.1:8000/analyse"
filename = "./example.jpg"
m = MultipartEncoder(
fields={'file': ('filename', open(filename, 'rb'), 'image/jpeg')}
)
r = requests.post(url, data=m, headers={'Content-Type': m.content_type}, timeout = 8000)
assert r.status_code == 200
그러나 다음 형식의 함수로 테스트를 설정합니다.
from fastapi.testclient import TestClient
from requests_toolbelt.multipart.encoder import MultipartEncoder
from app.server import app
client = TestClient(app)
def test_image_analysis():
filename = "example.jpg"
m = MultipartEncoder(
fields={'file': ('filename', open(filename, 'rb'), 'image/jpeg')}
)
response = client.post("/analyse",
data=m,
headers={"Content-Type": "multipart/form-data"}
)
assert response.status_code == 200
로 테스트를 실행할 때, 그것은 나를 다시 돌려준다.
> assert response.status_code == 200
E assert 400 == 200
E + where 400 = <Response [400]>.status_code
tests\test_server.py:22: AssertionError
-------------------------------------------------------- Captured log call ---------------------------------------------------------
ERROR fastapi:routing.py:133 Error getting request body: can't concat NoneType to bytes
===================================================== short test summary info ======================================================
FAILED tests/test_server.py::test_image_analysis - assert 400 == 200
내가 뭘 잘못하고 있지? 이미지 파일을 사용하여 테스트 기능을 작성하는 올바른 방법은 무엇입니까?
모든 면에서 랩과 동일하지 않기 때문에 다른 동작을 볼 수 있습니다. 더 깊이 파고들려면 소스 코드를 참조하십시오: (FYI, starlette 라이브러리에서 사용 중)
https://github.com/encode/starlette/blob/master/starlette/testclient.py
해결하기 위해, 당신은 파일 바이트를 받아들이고 그것을 다음과 같은 것으로 포맷으로 인코딩할 수 있기 때문에 제거할 수 있다.
# change it
r = requests.post(url, data=m, headers={'Content-Type': m.content_type}, timeout = 8000)
# to
r = requests.post(url, files={"file": ("filename", open(filename, "rb"), "image/jpeg")})
그리고 Fast를 수정합니다.API 테스트 코드:
# change
response = client.post("/analyse",
data=m,
headers={"Content-Type": "multipart/form-data"}
)
# to
response = client.post(
"/analyse", files={"file": ("filename", open(filename, "rb"), "image/jpeg")}
)
아래 코드가 작동합니다.
** API 구조: **
파일:
from fastapi import APIRouter, File, UploadFile, Query
router = APIRouter()
@router.post(path="{{API_PATH}}", tags=["Prediction"])
def prediction(id: str, uploadFile: UploadFile):
...
{{CODE}}
return response
테스트 코드
파일:
import pytest
import os
from fastapi.testclient import TestClient
import.api_routers
client = TestClient(api_routers.router)
def test_prediction(constants):
# Use constants if fixture created
file_path = "{{IMAGE PATH}}"
if os.path.isfile(file_path):
_files = {'uploadFile': open(file_path, 'rb')}
response = client.post('{{API_PATH}}',
params={
"id": {{ID}}
},
files=_files
)
assert response.status_code == 200
else:
pytest.fail("Scratch file does not exists.")
반응형
'개발하자' 카테고리의 다른 글
테라포름: 문자열 목록 (0) | 2022.12.07 |
---|---|
Floot MediaQuery.of(context.size)의 device_preview 플러그인을 사용합니다.너비는 에뮬레이트된 전화기의 위젯을 제공하지 않습니다. (0) | 2022.12.06 |
Excel 데이터에서 Python 사전 만들기 (0) | 2022.12.05 |
Python에서 한 번에 여러 요소를 선택하는 것을 반복합니다. (0) | 2022.12.04 |
매트랩의 벡터 할당을 파이썬 형태로 변환 (1) | 2022.12.04 |