FYI
I was trying to get it to work with docker and got some startup problems but got is working after some minor changes:
I am using a separate redis container:
docker-compose:
.....
py4web etc.
.....
redis:
restart: always
image: redis
ports:
- "6379:6379"
based on _scaffold:
in common I add:
# #######################################################
# Optionally configure celery
# #######################################################
if settings.USE_CELERY:
from celery import Celery
# to use "from .common import scheduler" and then use it according
# to celery docs, examples in tasks.py
scheduler = Celery(
"apps.%s.tasks" % settings.APP_NAME, broker=settings.CELERY_BROKER, backend='redis://redis:6379/0')
scheduler.conf.broker_connection_retry_on_startup = True #added this to get rid of
CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
in settings:
# Celery settings
USE_CELERY = True
CELERY_BROKER = "redis://redis:6379/0"
my example task:
import time
@scheduler.task()
def MyLongRunningTask(arg1, arg2):
time.sleep(30)
return 'Task finished! Args: {} – {}'.format(arg1, arg2)
mydocker entrypoint.sh to get the scheduler going and start py4web
#!/bin/bash
. /home/py4web/.venv/bin/activate
exec .venv/bin/celery -A apps.myapp.tasks beat &
exec .venv/bin/celery -A apps.myapp.tasks worker --loglevel=info &
exec py4web run --password_file password.txt --host 0.0.0.0 --port 8000 apps
controller:
To start the task:
#import the tasks module and the task
from .tasks import MyLongRunningTask
@action('MyLongRunningTask', method=['GET'])
@action.uses(db, session )
def long_running_task():
results = MyLongRunningTask.delay('Hello', 'world!')
print('Task id: {}'.format(
results.id))
print('Task status: {}'.format(results.status))
return dict(id=
results.id , status=results.status)
To get the status of the task:
from .common import scheduler # instead of from celery.result import AsyncResult
@action('status/<id>', method=['GET'])
@action.uses(db, session )
def status(id=None):
res = scheduler.AsyncResult(id) # instead of
AsyncResult(id)
if res.status == 'SUCCESS':
return res.status, res.get()
print(res.get())
return res.status
Hope this can help some other beginners,