Проблема с запросами к внешним ресурсам из приложения Django
UPDATE: Оставляю изначальное сообщение без изменений, дополнение ниже после "UPDATE" Пишу свое первое Джанго-приложение, появилась необходимость получить данные о транзакции в сети BSC по ее хэшу. Как водится, спросил совет у ChatGPT, он надоумил на следующее:
checker.py (это я создал файл для проверки функции) - При запуске отдельно от приложения python checker.py работает как надо - возвращает необходимые данные
#checker.py - тестовый файл, запускаемый отдельно от приложения (работает)
from web3 import Web3
web3 = Web3(Web3.HTTPProvider('https://bsc-dataseed1.binance.org:443'))
def get_transaction_data(transaction_hash):
try:
transaction = web3.eth.get_transaction(transaction_hash)
return transaction
except Exception as e:
print(f'CHECKER - Error getting transaction data: {e}')
return None
test_transaction_hash = '0x0000000000000000000000000000000000000aaaaaabbbbbbccccccddddddeee' # Just example
transaction_data = get_transaction_data(test_transaction_hash)
print(f'TRANSACTION {transaction_data}')
Но в приложении, запущенном через python manage.py runserver, такая функция выдает ошибку о множественной рекурсии (это тестовая фукнция, в которой я получаю хэш с клиента, хэш приходит корректный):
test SOKECT CHECK WEB3 CONNECTION - ERROR: maximum recursion depth exceeded
#my_app.sockets.py - файл приложения, в котором обрабатываются сокетные обращения клиента
import socketio
sio = socketio.Server(cors_allowed_origins=[settings.CLIENT_URL])
from web3 import Web3
web3 = Web3(Web3.HTTPProvider('https://bsc-dataseed1.binance.org:443'))
@sio.event
def check_web3_connection(sid, input_data):
hash = input_data['hash']
print(f'test SOKECT CHECK WEB3 CONNECTION... hash: {hash}')
try:
data = web3.eth.get_transaction(hash)
print(f'test SOKECT CHECK WEB3 CONNECTION - data: {data}')
except Exception as e:
print(f'test SOKECT CHECK WEB3 CONNECTION - ERROR: {e}')
Если же пытаюсь импортировать функцию get_transaction_data из файла checker.py и использовать ее в своем приложении, то происходит следующее:
- При запуске (перезапуске после CTRL+S) приложения функция get_transaction_data отрабатывает корректно (хотя я ее не вызываю, а просто импортирую).
- При вызове дает результат ERROR: maximum recursion depth exceeded
Как я уже сказал, приложение на моем веку первое, т.е. я еще нуб. Есть догадки, что, вероятно, тут дело в необходимости использования асинхронности (с этим еще не разобрался), но, может как-то можно обойтись без asyncio и иже с ним? Запускается мое приложения через wsgi.py, использует для обмена с клиентом Http и SocketIO. Вот мой wsgi.py, может, это тоже нужно для понимания картины:
#wsgi.py
from django.conf import settings
import os
import socketio
import eventlet
from django.core.wsgi import get_wsgi_application
from my_app.sockets import sio
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.executors.pool import ThreadPoolExecutor
eventlet.monkey_patch()
executor = ThreadPoolExecutor()
# Создание планировщика задач
scheduler = BackgroundScheduler(executors={"default": executor})
scheduler.add_job(minute_scheduler, 'interval', minutes=1)
# Запуск планировщика
scheduler.start()
app = get_wsgi_application()
application = socketio.WSGIApp(sio, app)
eventlet.wsgi.server(eventlet.listen(('', 8000)), application)
Буду рад, если кто-то сможет что-либо посоветовать. Спасибо за ознакомление.
UPDATE На следующий день попробовал взять инфу через API BSC Scan, используя requests:
url = f'https://api.bscscan.com/api?module=proxy&action=eth_getTransactionByHash&txhash={hash}&apikey={api_key}'
try:
response = requests.get(url)
data = response.json()
print(f'CHECK BSC SCAN API - {data['result']}')
#return data['result']
except Exception as e:
print(f'Error getting transaction data: {e}')
#return None
результат тот же. Потом попробовал обратиться с запросом requests к сайту https://httpbin.org/get - то же самое. Получается, проблема с исходящими запросами из приложения ВООБЩЕ. Причем, при запуске этих запросов из отдельных файлов все прекрасно работает. Пробовал также в settings.py вносить указанные ресурсы в CORS_ALLOWED_ORIGINS, ALLOWED_HOSTS, а также установил CORS_ALLOW_ALL_ORIGINS = True - ничего не меняется, при попытке отправки запроса возникает ошибка с рекурсией
Короче, всем спасибо (в смысле мне), вопрос снимается. Проблема была в том, что приложение Джанго пытается обратиться на ресурс по протоколу https://, а в приложении не установлены SSL сертификаты. Правда, я не совсем понял, почему из отдельного файла такой запрос тогда проходит, но это ладно. Выяснил:
- По протоколу http:// запрос проходит (и получает ответ).
- Нужно в любом случае как-то настраивать https://, так как в продакшене это мастхэв.