使用Django启动和停止定期后台任务

时间:2018-08-09 12:40:44

标签: django python-3.x task bots django-channels

我想用Django发出比特币通知。如果设法让一个能正常工作的Telegram机器人在我要求他发送比特币统计信息时发送该比特币统计信息。现在,如果比特币达到特定值,我希望他向我发送消息。有些教程在服务器上运行python脚本,而Django没有。我阅读了有关Django频道的一些答案和说明,但无法使其适应我的项目。

我想通过电报发送有关数量和持续时间的命令。然后,Django将使用这些值和我从后台发送的通道的值开始一个过程。如果现在,在持续时间内,数量已达到,则Django将消息发送回我的频道。一个以上的人也应该有可能。

这些是否可能与Django开箱即用,也许与装饰器有关,还是我需要django-channel或其他东西?

编辑2018-08-10: 也许我的代码更好地解释了我想做什么。

import requests
import json
from datetime import datetime

from django.shortcuts import render
from django.http import HttpResponse
from django.conf import settings

from django.views.generic import TemplateView
from django.views.decorators.csrf 
import csrf_exempt


class AboutView(TemplateView):
    template_name = 'telapi/about.html'


bot_token = settings.BOT_TOKEN


def get_url(method):
    return 'https://api.telegram.org/bot{}/{}'.format(bot_token, method)


def process_message(update):
    data = {}
    data['chat_id'] = update['message']['from']['id']
    data['text'] = "I can hear you!"
    r = requests.post(get_url('sendMessage'), data=data)


@csrf_exempt
def process_update(request, r_bot_token):
    ''' Method that is called from telegram-bot'''
    if request.method == 'POST' and r_bot_token == bot_token:
        update = json.loads(request.body.decode('utf-8'))
        if 'message' in update:
            if update['message']['text'] == 'give me news':
                new_bitcoin_price(update)
            else:
                process_message(update)
            return HttpResponse(status=200)


bitconin_api_uri = 'https://api.coinmarketcap.com/v2/ticker/1/?convert=EUR'
# response = requests.get(bitconin_api_uri)


def get_latest_bitcoin_price():
    response = requests.get(bitconin_api_uri)
    response_json = response.json()
    euro_price = float(response_json['data']['quotes']['EUR']['price'])
    timestamp = int(response_json['metadata']['timestamp'])
    date = datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
    return euro_price, date


def new_bitcoin_price(update):
    data = {}
    data['chat_id'] = update['message']['from']['id']
    euro_price, date = get_latest_bitcoin_price()
    data['text'] = "Aktuel ({}) beträgt der Preis {:.2f}€".format(
        date, euro_price)
    r = requests.post(get_url('sendMessage'), data=data)

编辑2018-08-13: 我认为解决方案将是芹菜和渠道。有谁知道一个好的教程?

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,有几种典型的方法:Celery,Django-Channels等。 但是您可以通过简单的方法避免它们全部使用:https://docs.djangoproject.com/en/2.1/howto/custom-management-commands/

我在项目中使用django命令来定期运行任务以重建用户统计信息:

  1. 执行自己的应用程序命令,例如,您的应用程序名称为myapp,并且您已将my_periodic_task.py放在myapp/management/commands文件夹中,因此可以通过键入python manage.py my_periodic_task一次运行任务
  2. 使用相同的代码在manage.py文件新文件(例如background.py)旁边放置

-

import os
from subprocess import call

BASE = os.path.dirname(__file__)
MANAGE_BASE = os.path.join(BASE, 'manage.py')

while True:
    sleep(YOUR_TIMEOUT)
    call(['python', MANAGE_BASE , 'my_periodic_task'])
  1. 例如,运行服务器:python background.py & python manage.py runserver 0.0.0.0:8000

答案 1 :(得分:1)

我的一个队友使用django-celery-beat,可以在https://github.com/celery/django-celery-beat上进行此操作,他从中给了我一些很好的反馈。您可以使用crontab语法安排芹菜任务。