SlideShare ist ein Scribd-Unternehmen logo
1 von 32
Downloaden Sie, um offline zu lesen
Celery
Eine asynchrone Task Queue
   (nicht nur) für Django
     Markus Zapke-Gründemann
          FrOSCon 2010
Markus
  Zapke-Gründemann
• Softwareentwickler seit 2001
• Schwerpunkt: Web Application Development
  mit Python und PHP
• Django, symfony & Zend Framework
• Freier Softwareentwickler und Berater seit
  2008
• www.keimlink.de
Überblick
• Warum eine Task Queue?
• Celery
• Python Task
• Django Task
• Zeitgesteuerter Task
• Webhook
Warum eine
         Task Queue?

• Entkoppeln von Informationsproduzenten
  und -konsumenten
• Asynchrone Verarbeitung
• Skalierbarkeit
Task
Produzent           Konsument
            Queue
Produzent           Konsument




             Task
Produzent           Konsument
            Queue




Produzent           Konsument
Produzent           Konsument




             Task
Produzent           Konsument
            Queue




Produzent           Konsument
Produzent           Konsument




             Task
Produzent           Konsument
            Queue




Produzent           Konsument
Celery

• Autor: Ask Solem
• RabbitMQ, Stomp, Redis und Ghetto Queue
• Clustering mit RabbitMQ
• Parallele Ausführung
• Zeitgesteuerte Ausführung
Celery
• Rückgabewert sofort oder später
  verarbeiten
• Speichern der Rückgabe in „Result Stores“
• Webhooks
• Serialisierung (Pickle, JSON,YAML)
• Wiederholen abgebrochener Tasks
Celery
• Callbacks
• Task Sets
• Logging
• Bei Fehler E-Mail versenden
• Ausführliche Dokumentation
• BSD Lizenz
Celery Komponenten

• celeryd      • SQLAlchemy
• celerybeat   • carrot
• celerymon    • anyjson
Celery Installation

 $ pip install celery

 $ easy_install celery
Python Task
# Task als Klasse
from celery.task import Task
from myproject.models import User

class CreateUserTask(Task):
    def run(self, username, password):
        User.create(username, password)

>>> from tasks import CreateUserTask
>>> CreateUserTask().delay('john', 'secret')

# Task als Funktion mit Decorator
from celery.decorators import task
from myproject.models import User

@task
def create_user(username, password):
    User.create(username, password)

>>> from tasks import create_user
>>> create_user.delay('john', 'secret')
Python Task
@task() # Benutzt pickle, um das Objekt zu serialisieren.
def check_means(user):
    return user.has_means()

>>> from tasks import check_means
>>> result = check_means.delay(user)
>>> result.ready() # Gibt True zurück wenn der Task beendet ist.
False
>>> result.result # Task ist noch nicht beendet, kein Ergebnis verfügbar.
None
>>> result.get() # Warten bis der Task fertig ist und Ergebnis zurückgeben.
93.27
>>> result.result # Jetzt ist ein Ergebnis da.
93.27
>>> result.successful() # War der Task erfolgreich?
True
Python Task
          Konfiguration
# celeryconfig.py
BROKER_HOST = "localhost"
BROKER_PORT = 5672
BROKER_USER = "myuser"
BROKER_PASSWORD = "mypassword"
BROKER_VHOST = "myvhost"

CELERY_RESULT_BACKEND = "database"
CELERY_RESULT_DBURI = "mysql://user:password@host/dbname"

CELERY_IMPORTS = ("tasks", )




   $ celeryd --loglevel=INFO
Zeitgesteuerter Task
# Periodic task
from celery.decorators import periodic_task
from datetime import timedelta

@periodic_task(run_every=timedelta(seconds=30))
def every_30_seconds():
    print("Running periodic task!")

# crontab
from celery.task.schedules import crontab
from celery.decorators import periodic_task

@periodic_task(run_every=crontab(hour=7, minute=30, day_of_week=1))
def every_monday_morning():
    print("Execute every Monday at 7:30AM.")

                        $ celerybeat
                        $ celeryd -B
Django Task
      Installation

$ pip install django-celery

$ easy_install django-celery
Django Task
Spamfilter
Django Task
                     Spamfilter

      Produzent


blog.views.add_comment
Django Task
                     Spamfilter

      Produzent


blog.views.add_comment




                         Comment
                          Model
Django Task
                       Spamfilter

      Produzent


blog.views.add_comment



      comment.save()
                          Comment
                           Model
Django Task
                       Spamfilter

                            Task
      Produzent            Queue


blog.views.add_comment



      comment.save()
                          Comment
                           Model
Django Task
                       Spamfilter
     blog.tasks.spam_filter.delay(comment.id,
         remote_addr)


                                 Task
      Produzent                 Queue


blog.views.add_comment



      comment.save()
                               Comment
                                Model
Django Task
                       Spamfilter
     blog.tasks.spam_filter.delay(comment.id,
         remote_addr)


                                 Task
      Produzent                                       Konsument
                                Queue


blog.views.add_comment                          blog.tasks.spam_filter



      comment.save()
                               Comment
                                Model
Django Task
                       Spamfilter
     blog.tasks.spam_filter.delay(comment.id,
         remote_addr)


                                 Task
      Produzent                                       Konsument
                                Queue


blog.views.add_comment                          blog.tasks.spam_filter



      comment.save()
                               Comment
                                Model
Django Task
                       Spamfilter
     blog.tasks.spam_filter.delay(comment.id,
         remote_addr)


                                 Task
      Produzent                                       Konsument
                                Queue


blog.views.add_comment                          blog.tasks.spam_filter


                                                 comment.is_spam = True
      comment.save()
                                                 comment.save()
                               Comment
                                Model
blog/tasks.py
@task
def spam_filter(comment_id, remote_addr=None, **kwargs):
        logger = spam_filter.get_logger(**kwargs)
        logger.info("Running spam filter for comment %s" % comment_id)

        comment = Comment.objects.get(pk=comment_id)
        current_domain = Site.objects.get_current().domain
        akismet = Akismet(settings.AKISMET_KEY, "http://%s" % domain)
        if not akismet.verify_key():
            raise ImproperlyConfigured("Invalid AKISMET_KEY")


        is_spam = akismet.comment_check(user_ip=remote_addr,
                            comment_content=comment.comment,
                            comment_author=comment.name,
                            comment_author_email=comment.email_address)
        if is_spam:
            comment.is_spam = True
            comment.save()

        return is_spam
Django Task
    Konfiguration
      # settings.py
      INSTALLED_APPS += ("djcelery", )
      import djcelery
      djcelery.setup_loader()

      BROKER_HOST = "localhost"
      BROKER_PORT = 5672
      BROKER_USER = "myuser"
      BROKER_PASSWORD = "mypassword"
      BROKER_VHOST = "myvhost"



$ python manage.py syncdb
$ python manage.py celeryd -l info
Webhook
# POST
>>> from celery.task.http import URL
>>> res = URL("http://example.com/multiply").get_async(x=10, y=10)
>>> res.get() # {"status": "success", "retval": 100}
100

# GET
>>> from celery.task.http import HttpDispatchTask
>>> url = "http://example.com/multiply"
>>> res = HttpDispatchTask.delay(url, method="GET", x=10, y=10)
>>> res.get() # {"status": "success", "retval": 100}
100
Links

• http://celeryproject.org/
• http://github.com/ask/celery
• http://pypi.python.org/pypi/celery
• http://pypi.python.org/pypi/django-celery
• http://pypi.python.org/pypi/celerymon
Lizenz
Dieses Werk ist unter einem Creative Commons
  Namensnennung-Weitergabe unter gleichen
   Bedingungen 3.0 Unported Lizenzvertrag
                   lizenziert.
  Um die Lizenz anzusehen, gehen Sie bitte zu
 http://creativecommons.org/licenses/by-sa/3.0/
    oder schicken Sie einen Brief an Creative
  Commons, 171 Second Street, Suite 300, San
         Francisco, California 94105, USA.

Weitere ähnliche Inhalte

Andere mochten auch

Arbeiten mit distribute, pip und virtualenv
Arbeiten mit distribute, pip und virtualenvArbeiten mit distribute, pip und virtualenv
Arbeiten mit distribute, pip und virtualenvMarkus Zapke-Gründemann
 
Writing multi-language documentation using Sphinx
Writing multi-language documentation using SphinxWriting multi-language documentation using Sphinx
Writing multi-language documentation using SphinxMarkus Zapke-Gründemann
 
Arbeiten mit distribute, pip und virtualenv
Arbeiten mit distribute, pip und virtualenvArbeiten mit distribute, pip und virtualenv
Arbeiten mit distribute, pip und virtualenvMarkus Zapke-Gründemann
 
Sichere Web-Applikationen am Beispiel von Django
Sichere Web-Applikationen am Beispiel von DjangoSichere Web-Applikationen am Beispiel von Django
Sichere Web-Applikationen am Beispiel von DjangoMarkus Zapke-Gründemann
 
Django - The Web framework for perfectionists with deadlines
Django - The Web framework for perfectionists with deadlinesDjango - The Web framework for perfectionists with deadlines
Django - The Web framework for perfectionists with deadlinesMarkus Zapke-Gründemann
 
Distributed Version Control (DVCS) With Mercurial
Distributed Version Control (DVCS) With MercurialDistributed Version Control (DVCS) With Mercurial
Distributed Version Control (DVCS) With MercurialTed Naleid
 
Virtuelle Maschinen mit Packer, Vagrant und Salt bauen
Virtuelle Maschinen mit Packer, Vagrant und Salt bauenVirtuelle Maschinen mit Packer, Vagrant und Salt bauen
Virtuelle Maschinen mit Packer, Vagrant und Salt bauenMarkus Zapke-Gründemann
 

Andere mochten auch (8)

Arbeiten mit distribute, pip und virtualenv
Arbeiten mit distribute, pip und virtualenvArbeiten mit distribute, pip und virtualenv
Arbeiten mit distribute, pip und virtualenv
 
Writing multi-language documentation using Sphinx
Writing multi-language documentation using SphinxWriting multi-language documentation using Sphinx
Writing multi-language documentation using Sphinx
 
Arbeiten mit distribute, pip und virtualenv
Arbeiten mit distribute, pip und virtualenvArbeiten mit distribute, pip und virtualenv
Arbeiten mit distribute, pip und virtualenv
 
Sichere Web-Applikationen am Beispiel von Django
Sichere Web-Applikationen am Beispiel von DjangoSichere Web-Applikationen am Beispiel von Django
Sichere Web-Applikationen am Beispiel von Django
 
Django - The Web framework for perfectionists with deadlines
Django - The Web framework for perfectionists with deadlinesDjango - The Web framework for perfectionists with deadlines
Django - The Web framework for perfectionists with deadlines
 
Mercurial
MercurialMercurial
Mercurial
 
Distributed Version Control (DVCS) With Mercurial
Distributed Version Control (DVCS) With MercurialDistributed Version Control (DVCS) With Mercurial
Distributed Version Control (DVCS) With Mercurial
 
Virtuelle Maschinen mit Packer, Vagrant und Salt bauen
Virtuelle Maschinen mit Packer, Vagrant und Salt bauenVirtuelle Maschinen mit Packer, Vagrant und Salt bauen
Virtuelle Maschinen mit Packer, Vagrant und Salt bauen
 

Ähnlich wie Celery - eine asynchrone Task Queue (nicht nur) für Django

Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...GFU Cyrus AG
 
javaPersistenceInActionFeaturesJenseitsDesEntryLevels
javaPersistenceInActionFeaturesJenseitsDesEntryLevelsjavaPersistenceInActionFeaturesJenseitsDesEntryLevels
javaPersistenceInActionFeaturesJenseitsDesEntryLevelsgedoplan
 
Enterprise Java Batch mit Spring
Enterprise Java Batch mit SpringEnterprise Java Batch mit Spring
Enterprise Java Batch mit Springdenschu
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptSebastian Springer
 
Domain Driven Design in Rails
Domain Driven Design in RailsDomain Driven Design in Rails
Domain Driven Design in RailsAngelo Maron
 
Python builds mit ant
Python builds mit antPython builds mit ant
Python builds mit antroskakori
 
Angular von 0 auf 100
Angular von 0 auf 100Angular von 0 auf 100
Angular von 0 auf 100Yvette Teiken
 
Lightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPALightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPAmh0708
 
SOLID Prinzipien, Designgrundlagen objektorientierter Systeme
SOLID Prinzipien, Designgrundlagen objektorientierter SystemeSOLID Prinzipien, Designgrundlagen objektorientierter Systeme
SOLID Prinzipien, Designgrundlagen objektorientierter SystemeMario Rodler
 
Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010Dirk Ginader
 
dotnet Cologne 2013 - Windows Azure Mobile Services
dotnet Cologne 2013 - Windows Azure Mobile Servicesdotnet Cologne 2013 - Windows Azure Mobile Services
dotnet Cologne 2013 - Windows Azure Mobile ServicesSascha Dittmann
 
TYPO3 5.0 - Der aktuelle Stand der Zukunft
TYPO3 5.0 - Der aktuelle Stand der ZukunftTYPO3 5.0 - Der aktuelle Stand der Zukunft
TYPO3 5.0 - Der aktuelle Stand der ZukunftJochen Rau
 
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?Marc Müller
 
TYPO3 CMS 7.3 - Die Neuerungen - pluswerk
TYPO3 CMS 7.3 - Die Neuerungen - pluswerkTYPO3 CMS 7.3 - Die Neuerungen - pluswerk
TYPO3 CMS 7.3 - Die Neuerungen - pluswerkdie.agilen GmbH
 
DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?
DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?
DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?Marc Müller
 
Automatisierte GUI-Tests mit Selenium
Automatisierte GUI-Tests mit SeleniumAutomatisierte GUI-Tests mit Selenium
Automatisierte GUI-Tests mit SeleniumBenjamin Schmid
 
Prototype 1.7
Prototype 1.7Prototype 1.7
Prototype 1.7msebel
 
Legacy Code refaktorisieren
Legacy Code refaktorisierenLegacy Code refaktorisieren
Legacy Code refaktorisierenHendrik Lösch
 

Ähnlich wie Celery - eine asynchrone Task Queue (nicht nur) für Django (20)

Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
 
javaPersistenceInActionFeaturesJenseitsDesEntryLevels
javaPersistenceInActionFeaturesJenseitsDesEntryLevelsjavaPersistenceInActionFeaturesJenseitsDesEntryLevels
javaPersistenceInActionFeaturesJenseitsDesEntryLevels
 
Enterprise Java Batch mit Spring
Enterprise Java Batch mit SpringEnterprise Java Batch mit Spring
Enterprise Java Batch mit Spring
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScript
 
Domain Driven Design in Rails
Domain Driven Design in RailsDomain Driven Design in Rails
Domain Driven Design in Rails
 
Python builds mit ant
Python builds mit antPython builds mit ant
Python builds mit ant
 
Angular von 0 auf 100
Angular von 0 auf 100Angular von 0 auf 100
Angular von 0 auf 100
 
Lightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPALightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPA
 
SOLID Prinzipien, Designgrundlagen objektorientierter Systeme
SOLID Prinzipien, Designgrundlagen objektorientierter SystemeSOLID Prinzipien, Designgrundlagen objektorientierter Systeme
SOLID Prinzipien, Designgrundlagen objektorientierter Systeme
 
Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010
 
dotnet Cologne 2013 - Windows Azure Mobile Services
dotnet Cologne 2013 - Windows Azure Mobile Servicesdotnet Cologne 2013 - Windows Azure Mobile Services
dotnet Cologne 2013 - Windows Azure Mobile Services
 
MVVM mit WPF
MVVM mit WPFMVVM mit WPF
MVVM mit WPF
 
Codesmells
CodesmellsCodesmells
Codesmells
 
TYPO3 5.0 - Der aktuelle Stand der Zukunft
TYPO3 5.0 - Der aktuelle Stand der ZukunftTYPO3 5.0 - Der aktuelle Stand der Zukunft
TYPO3 5.0 - Der aktuelle Stand der Zukunft
 
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
Karlsruher Entwicklertag 2016 - Monitoring 2.0: Alles im Lot?
 
TYPO3 CMS 7.3 - Die Neuerungen - pluswerk
TYPO3 CMS 7.3 - Die Neuerungen - pluswerkTYPO3 CMS 7.3 - Die Neuerungen - pluswerk
TYPO3 CMS 7.3 - Die Neuerungen - pluswerk
 
DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?
DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?
DWX 2016 - Monitoring 2.0 - Monitoring 2.0: Alles im Lot?
 
Automatisierte GUI-Tests mit Selenium
Automatisierte GUI-Tests mit SeleniumAutomatisierte GUI-Tests mit Selenium
Automatisierte GUI-Tests mit Selenium
 
Prototype 1.7
Prototype 1.7Prototype 1.7
Prototype 1.7
 
Legacy Code refaktorisieren
Legacy Code refaktorisierenLegacy Code refaktorisieren
Legacy Code refaktorisieren
 

Celery - eine asynchrone Task Queue (nicht nur) für Django

  • 1. Celery Eine asynchrone Task Queue (nicht nur) für Django Markus Zapke-Gründemann FrOSCon 2010
  • 2. Markus Zapke-Gründemann • Softwareentwickler seit 2001 • Schwerpunkt: Web Application Development mit Python und PHP • Django, symfony & Zend Framework • Freier Softwareentwickler und Berater seit 2008 • www.keimlink.de
  • 3. Überblick • Warum eine Task Queue? • Celery • Python Task • Django Task • Zeitgesteuerter Task • Webhook
  • 4. Warum eine Task Queue? • Entkoppeln von Informationsproduzenten und -konsumenten • Asynchrone Verarbeitung • Skalierbarkeit
  • 5. Task Produzent Konsument Queue
  • 6. Produzent Konsument Task Produzent Konsument Queue Produzent Konsument
  • 7. Produzent Konsument Task Produzent Konsument Queue Produzent Konsument
  • 8. Produzent Konsument Task Produzent Konsument Queue Produzent Konsument
  • 9. Celery • Autor: Ask Solem • RabbitMQ, Stomp, Redis und Ghetto Queue • Clustering mit RabbitMQ • Parallele Ausführung • Zeitgesteuerte Ausführung
  • 10. Celery • Rückgabewert sofort oder später verarbeiten • Speichern der Rückgabe in „Result Stores“ • Webhooks • Serialisierung (Pickle, JSON,YAML) • Wiederholen abgebrochener Tasks
  • 11. Celery • Callbacks • Task Sets • Logging • Bei Fehler E-Mail versenden • Ausführliche Dokumentation • BSD Lizenz
  • 12. Celery Komponenten • celeryd • SQLAlchemy • celerybeat • carrot • celerymon • anyjson
  • 13. Celery Installation $ pip install celery $ easy_install celery
  • 14. Python Task # Task als Klasse from celery.task import Task from myproject.models import User class CreateUserTask(Task): def run(self, username, password): User.create(username, password) >>> from tasks import CreateUserTask >>> CreateUserTask().delay('john', 'secret') # Task als Funktion mit Decorator from celery.decorators import task from myproject.models import User @task def create_user(username, password): User.create(username, password) >>> from tasks import create_user >>> create_user.delay('john', 'secret')
  • 15. Python Task @task() # Benutzt pickle, um das Objekt zu serialisieren. def check_means(user): return user.has_means() >>> from tasks import check_means >>> result = check_means.delay(user) >>> result.ready() # Gibt True zurück wenn der Task beendet ist. False >>> result.result # Task ist noch nicht beendet, kein Ergebnis verfügbar. None >>> result.get() # Warten bis der Task fertig ist und Ergebnis zurückgeben. 93.27 >>> result.result # Jetzt ist ein Ergebnis da. 93.27 >>> result.successful() # War der Task erfolgreich? True
  • 16. Python Task Konfiguration # celeryconfig.py BROKER_HOST = "localhost" BROKER_PORT = 5672 BROKER_USER = "myuser" BROKER_PASSWORD = "mypassword" BROKER_VHOST = "myvhost" CELERY_RESULT_BACKEND = "database" CELERY_RESULT_DBURI = "mysql://user:password@host/dbname" CELERY_IMPORTS = ("tasks", ) $ celeryd --loglevel=INFO
  • 17. Zeitgesteuerter Task # Periodic task from celery.decorators import periodic_task from datetime import timedelta @periodic_task(run_every=timedelta(seconds=30)) def every_30_seconds(): print("Running periodic task!") # crontab from celery.task.schedules import crontab from celery.decorators import periodic_task @periodic_task(run_every=crontab(hour=7, minute=30, day_of_week=1)) def every_monday_morning(): print("Execute every Monday at 7:30AM.") $ celerybeat $ celeryd -B
  • 18. Django Task Installation $ pip install django-celery $ easy_install django-celery
  • 20. Django Task Spamfilter Produzent blog.views.add_comment
  • 21. Django Task Spamfilter Produzent blog.views.add_comment Comment Model
  • 22. Django Task Spamfilter Produzent blog.views.add_comment comment.save() Comment Model
  • 23. Django Task Spamfilter Task Produzent Queue blog.views.add_comment comment.save() Comment Model
  • 24. Django Task Spamfilter blog.tasks.spam_filter.delay(comment.id, remote_addr) Task Produzent Queue blog.views.add_comment comment.save() Comment Model
  • 25. Django Task Spamfilter blog.tasks.spam_filter.delay(comment.id, remote_addr) Task Produzent Konsument Queue blog.views.add_comment blog.tasks.spam_filter comment.save() Comment Model
  • 26. Django Task Spamfilter blog.tasks.spam_filter.delay(comment.id, remote_addr) Task Produzent Konsument Queue blog.views.add_comment blog.tasks.spam_filter comment.save() Comment Model
  • 27. Django Task Spamfilter blog.tasks.spam_filter.delay(comment.id, remote_addr) Task Produzent Konsument Queue blog.views.add_comment blog.tasks.spam_filter comment.is_spam = True comment.save() comment.save() Comment Model
  • 28. blog/tasks.py @task def spam_filter(comment_id, remote_addr=None, **kwargs): logger = spam_filter.get_logger(**kwargs) logger.info("Running spam filter for comment %s" % comment_id) comment = Comment.objects.get(pk=comment_id) current_domain = Site.objects.get_current().domain akismet = Akismet(settings.AKISMET_KEY, "http://%s" % domain) if not akismet.verify_key(): raise ImproperlyConfigured("Invalid AKISMET_KEY") is_spam = akismet.comment_check(user_ip=remote_addr, comment_content=comment.comment, comment_author=comment.name, comment_author_email=comment.email_address) if is_spam: comment.is_spam = True comment.save() return is_spam
  • 29. Django Task Konfiguration # settings.py INSTALLED_APPS += ("djcelery", ) import djcelery djcelery.setup_loader() BROKER_HOST = "localhost" BROKER_PORT = 5672 BROKER_USER = "myuser" BROKER_PASSWORD = "mypassword" BROKER_VHOST = "myvhost" $ python manage.py syncdb $ python manage.py celeryd -l info
  • 30. Webhook # POST >>> from celery.task.http import URL >>> res = URL("http://example.com/multiply").get_async(x=10, y=10) >>> res.get() # {"status": "success", "retval": 100} 100 # GET >>> from celery.task.http import HttpDispatchTask >>> url = "http://example.com/multiply" >>> res = HttpDispatchTask.delay(url, method="GET", x=10, y=10) >>> res.get() # {"status": "success", "retval": 100} 100
  • 31. Links • http://celeryproject.org/ • http://github.com/ask/celery • http://pypi.python.org/pypi/celery • http://pypi.python.org/pypi/django-celery • http://pypi.python.org/pypi/celerymon
  • 32. Lizenz Dieses Werk ist unter einem Creative Commons Namensnennung-Weitergabe unter gleichen Bedingungen 3.0 Unported Lizenzvertrag lizenziert. Um die Lizenz anzusehen, gehen Sie bitte zu http://creativecommons.org/licenses/by-sa/3.0/ oder schicken Sie einen Brief an Creative Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA.