상황
사내 API에서는 요청 쿼리의 결과 값에 wrapper를 씌워서 아래와 같이 내부 정의 응답코드, 요청 url 쿼리, data 등을 출력한다.
즉, 실제 결과는 data 파라미터에 딕셔너리 형태로 출력되는데, 여기서 data에 null 출력을 위해 nan, None 값이 포함되면 다음 에러가 발생한다.
Traceback (most recent call last):
File "/home/mining/projects/finance_advisor/some_money/somemoney_api_server/somemoney_api_server/sub_noAuth.py", line 215, in api_middleware
response = await call_next(request)
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/starlette/middleware/base.py", line 46, in call_next
raise app_exc
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/starlette/middleware/base.py", line 36, in coro
await self.app(scope, request.receive, send_stream.send)
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/starlette/exceptions.py", line 93, in __call__
raise exc
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/starlette/exceptions.py", line 82, in __call__
await self.app(scope, receive, sender)
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
raise e
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/starlette/routing.py", line 670, in __call__
await route.handle(scope, receive, send)
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/starlette/routing.py", line 266, in handle
await self.app(scope, receive, send)
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/starlette/routing.py", line 65, in app
response = await func(request)
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/fastapi/routing.py", line 227, in app
raw_response = await run_endpoint_function(
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/fastapi/routing.py", line 160, in run_endpoint_function
return await dependant.call(**values)
File "/home/mining/projects/finance_advisor/some_money/somemoney_api_server/somemoney_api_server/api/api_v3/endpoints/etc.py", line 261, in dartgpt_summary
return JSONResponse(response_wrapper(request, results))
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/starlette/responses.py", line 187, in __init__
super().__init__(content, status_code, headers, media_type, background)
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/starlette/responses.py", line 49, in __init__
self.body = self.render(content)
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/site-packages/starlette/responses.py", line 190, in render
return json.dumps(
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/json/__init__.py", line 234, in dumps
return cls(
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/home/mining/.conda/envs/some_money_api/lib/python3.8/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
ValueError: Out of range float values are not JSON compliant
사내에서는 다음 에러로 null 값을 string으로 감싸 "null" 등으로 출력하고 있었는데, null 값 출력 자체가 필요한 상황이라 이번 기회에 변경하게 됐다.
해결 방법
API 의 디폴트 출력 클래스를 변경해주면 된다.
우선 orjson 라이브러리를 설치하자.
orjson은 json파일을 읽고 쓰는데 사용되는 라이브러리 중 하나이다.
pip install orjson
다음으로 API의 출력 형식을 다음과 같이 설정해주면 된다.
from fastapi import FastAPI
from fastapi.responses import ORJSONResponse
router = FastAPI(default_response_class=ORJSONResponse)
[...]
일부 라우터에서 출력 형식을 다음과 같이 변경하는 것도 가능하다.
from fastapi import APIRouter
from fastapi.responses import ORJSONResponse
router = APIRouter(default_response_class=ORJSONResponse)
[...]
수정하고 값에 None을 넣어 출력하면 다음과 같이 null로 나오는걸 확인할 수 있다.
{
"api_name": "/no_auth/api/v3/dartgpt_summary.json",
"data": [
{
"time": null,
"code": "A413640",
"dart_report_date": null,
"dart_report_type": null,
"data": null
}
],
"error_msg": "",
"request": "{query_params:[[stocks,A413640]],path_params:[]}",
"return_code": "00"
}
Reference
'서버 및 환경 > Utils' 카테고리의 다른 글
[Docker] 스크립트 변경 내용이 컨테이너에 적용되지 않을 때 (0) | 2024.10.28 |
---|---|
[Kafka] 클라이언트와 서버간 time zone 문제 (Negative message latency=-32376435 ms) (1) | 2024.10.22 |
[Docker] 컨테이너 No CUDA GPUs are available 에러 발생 해결방법 (1) | 2024.04.04 |
[Airflow] retry와 상관없이 특정 시간 이후 task fail시키기 (0) | 2024.03.28 |
[conda] base 환경은 다른 가상환경 패키지에 모두 영향을 미친다! (0) | 2024.03.20 |