Ошибка при вызове конечной точки django rest framework с того же сервера
У меня есть конечная точка API, допустим sampleapi.domain.com/api/v1/1
, которая хорошо работала при разработке, как локально (127.0.0.1)
, так и онлайн sampleapi-dev.domain.com
, но когда я вызываю ту же конечную точку sampleapi.domain.com/api/v1/1
с сервера, с которого осуществляется вызов sampleapi.domain.com
, я получаю
json.decoder.JSONDecodeError: Ожидаемое значение: строка 1 столбец 1 (char 0)
что необычно, так как один и тот же код работает в разработке и онлайн. Возвращенный HTTP-код был 500 вместо 200 (который был возвращен для того же вызова API на локальном сервере тестирования и сервере разработки)
Когда я изменил способ запуска gunicorn
от gunicorn --certfile=crt --keyfile=key --bind 0.0.0.0:8000 a.wsgi
к gunicorn --certfile=crt --keyfile=key --bind 0.0.0.0:8000 a.wsgi -w 1 --threads 2
Похоже, это решает проблему, но я не совсем уверен, почему так происходит.
Может быть, единственный поток был недоступен для вызова API, потому что он был занят загрузкой страницы, на которой находится API? Если причина не в этом, то в чем она может быть?
File "/path/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/path/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/path/venv/lib/python3.6/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/path/venv/lib/python3.6/site-packages/django/views/decorators/http.py", line 40, in inner
return func(request, *args, **kwargs)
File "/path/png/script.py", line 128, in get_api
return response.json()
File "/path/venv/lib/python3.6/site-packages/requests/models.py", line 910, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/lib64/python3.6/json/__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "/usr/lib64/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib64/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Попробуйте использовать его
gunicorn Config.wsgi:application --bind 0.0.0.0:8000 -w 3
Кажется, что все равно
response = requests.get(url, headers=params)
иногда возвращается, не является json
.
Если вам трудно отлаживать, и эта проблема возникает только в определенных средах, где вы не можете зависеть от отладчика и зависите от ответа третьей стороны, просто добавьте туда лог.
import logging
logger = logging.getLogger(__name__)
def get_api():
url = 'https://sampleapi.domain.com/api/v1/1'
params = {'Authorization': 'Token ' + os.environ.get("token")}
try:
response = requests.get(url, headers=params)
except requests.exceptions.RequestException:
return "Could not grab api text."
# .debug or .info or whatever level of logging you use
logger.debug(f"Status code is {response.status_code} and text is {response.text}")
return response.json()
Если, как вы упомянули, это 500 и он возвращает общую ошибку сервера, вы не сможете отладить проблему с клиента, поскольку это не указывает на какое-либо потенциальное решение.
Если вы можете видеть журналы приложения Django, просто посмотрите, что оно возвращает. Если вы не видите ни одной ошибки, добавьте sentry
. Если вы не можете этого сделать, попросите кого-нибудь, кто контролирует сервер.
Скорее всего, это ALLOWED_HOSTS
или cors.