从不在 Celery 任务中调用 API returns
Calling API within Celery task never returns
我想从 web3.eth.getTransactionCount
中获取一个值。它只是挂起。此功能在其他地方(普通应用程序、控制台)工作正常。
要重现此行为,只需创建一个新文件夹,将这 3 个文件添加到该文件夹中,然后放入该文件夹 运行 docker-compose up
。 *请注意,infura 凭据可以安全使用。
docker文件
FROM python:3.7
WORKDIR /usr/src/app
RUN pip install flask celery[redis] web3
docker-compose.yml
version: "3"
services:
redis:
image: redis:5.0.7
container_name: redis
ports:
- "6379:6379"
myapp:
build: .
container_name: myapp
ports:
- "5000:5000"
volumes:
- .:/usr/src/app
environment:
- FLASK_ENV=development
- WEB3_INFURA_PROJECT_ID=1cc71ab02b99475b8a3172b6a790c2f8
- WEB3_INFURA_API_SECRET=6a343124ed8e4a6f9b36d28c50ad65ca
entrypoint: |
bash -c "python /usr/src/app/app.py"
celery:
build: .
container_name: celery
volumes:
- .:/usr/src/app
environment:
- WEB3_INFURA_PROJECT_ID=1cc71ab02b99475b8a3172b6a790c2f8
- WEB3_INFURA_API_SECRET=6a343124ed8e4a6f9b36d28c50ad65ca
command: celery worker -A app.client -l info
app.py
from flask import Flask
from web3.auto.infura.rinkeby import w3 as web3
from celery import Celery
app = Flask(__name__)
client = Celery(app.name, broker='redis://redis:6379', backend='redis://redis:6379')
@client.task
def never_return():
print('start') # this is printed
nonce = web3.eth.getTransactionCount('0x51cDD4A883144F01Bf0753b6189f3A034866465f')
print('nonce', nonce) # this is never printed
@app.route('/')
def index():
never_return.apply_async()
return "hello celery"
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
我在这里只发现了 1 个类似的未解决问题 post:
在 Celery 任务中由其他库发出请求调用时似乎有些奇怪。当我尝试使用 request
发出 post 请求时,一切正常。不幸的是,我不知道如何使用这个 request
库解决这个问题。
非常感谢任何类型的建议。
在我看来,这个问题与 websockets 有关。所以我试着把它切换到 HTTP。并且有效。
此处修改app.py
from flask import Flask
from web3 import Web3
from celery import Celery
from web3.middleware import geth_poa_middleware
import os
app = Flask(__name__)
client = Celery(app.name, broker='redis://redis:6379', backend='redis://redis:6379')
@client.task
def never_return():
w3 = Web3(Web3.HTTPProvider(f"https://rinkeby.infura.io/v3/{os.getenv('WEB3_INFURA_PROJECT_ID')}", request_kwargs={'timeout': 60}))
w3.middleware_onion.inject(geth_poa_middleware, layer=0)
print('started')
l = w3.eth.getBlock('latest')
print(f'block number: {l}')
print('finished ok')
@app.route('/')
def index():
never_return.apply_async()
return f"hello celery"
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
我想从 web3.eth.getTransactionCount
中获取一个值。它只是挂起。此功能在其他地方(普通应用程序、控制台)工作正常。
要重现此行为,只需创建一个新文件夹,将这 3 个文件添加到该文件夹中,然后放入该文件夹 运行 docker-compose up
。 *请注意,infura 凭据可以安全使用。
docker文件
FROM python:3.7
WORKDIR /usr/src/app
RUN pip install flask celery[redis] web3
docker-compose.yml
version: "3"
services:
redis:
image: redis:5.0.7
container_name: redis
ports:
- "6379:6379"
myapp:
build: .
container_name: myapp
ports:
- "5000:5000"
volumes:
- .:/usr/src/app
environment:
- FLASK_ENV=development
- WEB3_INFURA_PROJECT_ID=1cc71ab02b99475b8a3172b6a790c2f8
- WEB3_INFURA_API_SECRET=6a343124ed8e4a6f9b36d28c50ad65ca
entrypoint: |
bash -c "python /usr/src/app/app.py"
celery:
build: .
container_name: celery
volumes:
- .:/usr/src/app
environment:
- WEB3_INFURA_PROJECT_ID=1cc71ab02b99475b8a3172b6a790c2f8
- WEB3_INFURA_API_SECRET=6a343124ed8e4a6f9b36d28c50ad65ca
command: celery worker -A app.client -l info
app.py
from flask import Flask
from web3.auto.infura.rinkeby import w3 as web3
from celery import Celery
app = Flask(__name__)
client = Celery(app.name, broker='redis://redis:6379', backend='redis://redis:6379')
@client.task
def never_return():
print('start') # this is printed
nonce = web3.eth.getTransactionCount('0x51cDD4A883144F01Bf0753b6189f3A034866465f')
print('nonce', nonce) # this is never printed
@app.route('/')
def index():
never_return.apply_async()
return "hello celery"
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
我在这里只发现了 1 个类似的未解决问题 post:
在 Celery 任务中由其他库发出请求调用时似乎有些奇怪。当我尝试使用 request
发出 post 请求时,一切正常。不幸的是,我不知道如何使用这个 request
库解决这个问题。
非常感谢任何类型的建议。
在我看来,这个问题与 websockets 有关。所以我试着把它切换到 HTTP。并且有效。
此处修改app.py
from flask import Flask
from web3 import Web3
from celery import Celery
from web3.middleware import geth_poa_middleware
import os
app = Flask(__name__)
client = Celery(app.name, broker='redis://redis:6379', backend='redis://redis:6379')
@client.task
def never_return():
w3 = Web3(Web3.HTTPProvider(f"https://rinkeby.infura.io/v3/{os.getenv('WEB3_INFURA_PROJECT_ID')}", request_kwargs={'timeout': 60}))
w3.middleware_onion.inject(geth_poa_middleware, layer=0)
print('started')
l = w3.eth.getBlock('latest')
print(f'block number: {l}')
print('finished ok')
@app.route('/')
def index():
never_return.apply_async()
return f"hello celery"
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')