HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //usr/share/doc/python3-django-q/html/examples.html
<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="./">
<head>
  <meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Examples &mdash; Django Q2 1.6.1 documentation</title>
      <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b76e3c8a" />
      <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" />

  
    <link rel="shortcut icon" href="_static/favicon.ico"/>
  
        <script src="_static/jquery.js?v=8dae8fb0"></script>
        <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
        <script src="_static/documentation_options.js?v=d6a008b6"></script>
        <script src="_static/doctools.js?v=888ff710"></script>
        <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
    <script src="_static/js/theme.js"></script>
    <link rel="index" title="Index" href="genindex.html" />
    <link rel="search" title="Search" href="search.html" />
    <link rel="prev" title="Architecture" href="architecture.html" /> 
</head>

<body class="wy-body-for-nav"> 
  <div class="wy-grid-for-nav">
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >

          
          
          <a href="index.html" class="icon icon-home">
            Django Q2
          </a>
              <div class="version">
                1.6
              </div>
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
              <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="install.html"> Installation</a></li>
<li class="toctree-l1"><a class="reference internal" href="configure.html"> Configuration</a></li>
<li class="toctree-l1"><a class="reference internal" href="brokers.html"> Brokers</a></li>
<li class="toctree-l1"><a class="reference internal" href="tasks.html"> Tasks</a></li>
<li class="toctree-l1"><a class="reference internal" href="group.html"> Groups</a></li>
<li class="toctree-l1"><a class="reference internal" href="iterable.html"> Iterable</a></li>
<li class="toctree-l1"><a class="reference internal" href="chain.html"> Chains</a></li>
<li class="toctree-l1"><a class="reference internal" href="schedules.html"> Schedules</a></li>
<li class="toctree-l1"><a class="reference internal" href="cluster.html"> Cluster</a></li>
<li class="toctree-l1"><a class="reference internal" href="monitor.html"> Monitor</a></li>
<li class="toctree-l1"><a class="reference internal" href="admin.html"> Admin</a></li>
<li class="toctree-l1"><a class="reference internal" href="errors.html"> Errors</a></li>
<li class="toctree-l1"><a class="reference internal" href="signals.html"> Signals</a></li>
<li class="toctree-l1"><a class="reference internal" href="architecture.html"> Architecture</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#"> Examples</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#emails">Emails</a></li>
<li class="toctree-l2"><a class="reference internal" href="#signals">Signals</a></li>
<li class="toctree-l2"><a class="reference internal" href="#reports">Reports</a></li>
<li class="toctree-l2"><a class="reference internal" href="#haystack">Haystack</a></li>
<li class="toctree-l2"><a class="reference internal" href="#shell">Shell</a></li>
<li class="toctree-l2"><a class="reference internal" href="#groups">Groups</a></li>
<li class="toctree-l2"><a class="reference internal" href="#http-health-check">Http Health Check</a></li>
</ul>
</li>
</ul>

        </div>
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="index.html">Django Q2</a>
      </nav>

      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="index.html" class="icon icon-home" aria-label="Home"></a></li>
      <li class="breadcrumb-item active">Examples</li>
      <li class="wy-breadcrumbs-aside">
            <a href="_sources/examples.rst.txt" rel="nofollow"> View page source</a>
      </li>
  </ul>
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
             
  <section id="examples">
<h1>Examples<a class="headerlink" href="#examples" title="Link to this heading"></a></h1>
<section id="emails">
<h2>Emails<a class="headerlink" href="#emails" title="Link to this heading"></a></h2>
<p>Sending an email can take a while so why not queue it:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Welcome mail with follow up example</span>
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">timedelta</span>
<span class="kn">from</span> <span class="nn">django.utils</span> <span class="kn">import</span> <span class="n">timezone</span>
<span class="kn">from</span> <span class="nn">django_q.tasks</span> <span class="kn">import</span> <span class="n">async_task</span><span class="p">,</span> <span class="n">schedule</span>
<span class="kn">from</span> <span class="nn">django_q.models</span> <span class="kn">import</span> <span class="n">Schedule</span>


<span class="k">def</span> <span class="nf">welcome_mail</span><span class="p">(</span><span class="n">user</span><span class="p">):</span>
    <span class="n">msg</span> <span class="o">=</span> <span class="s1">&#39;Welcome to our website&#39;</span>
    <span class="c1"># send this message right away</span>
    <span class="n">async_task</span><span class="p">(</span><span class="s1">&#39;django.core.mail.send_mail&#39;</span><span class="p">,</span>
            <span class="s1">&#39;Welcome&#39;</span><span class="p">,</span>
            <span class="n">msg</span><span class="p">,</span>
            <span class="s1">&#39;from@example.com&#39;</span><span class="p">,</span>
            <span class="p">[</span><span class="n">user</span><span class="o">.</span><span class="n">email</span><span class="p">])</span>
    <span class="c1"># and this follow up email in one hour</span>
    <span class="n">msg</span> <span class="o">=</span> <span class="s1">&#39;Here are some tips to get you started...&#39;</span>
    <span class="n">schedule</span><span class="p">(</span><span class="s1">&#39;django.core.mail.send_mail&#39;</span><span class="p">,</span>
             <span class="s1">&#39;Follow up&#39;</span><span class="p">,</span>
             <span class="n">msg</span><span class="p">,</span>
             <span class="s1">&#39;from@example.com&#39;</span><span class="p">,</span>
             <span class="p">[</span><span class="n">user</span><span class="o">.</span><span class="n">email</span><span class="p">],</span>
             <span class="n">schedule_type</span><span class="o">=</span><span class="n">Schedule</span><span class="o">.</span><span class="n">ONCE</span><span class="p">,</span>
             <span class="n">next_run</span><span class="o">=</span><span class="n">timezone</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">+</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">hours</span><span class="o">=</span><span class="mi">1</span><span class="p">))</span>

    <span class="c1"># since the `repeats` defaults to -1</span>
    <span class="c1"># this schedule will erase itself after having run</span>
</pre></div>
</div>
<p>Since you’re only telling Django Q2 to take care of the emails, you can quickly move on to serving web pages to your user.</p>
</section>
<section id="signals">
<h2>Signals<a class="headerlink" href="#signals" title="Link to this heading"></a></h2>
<p>A good place to use async tasks are Django’s model signals. You don’t want to delay the saving or creation of objects, but sometimes you want to trigger a lot of actions:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Message on object change</span>
<span class="kn">from</span> <span class="nn">django.contrib.auth.models</span> <span class="kn">import</span> <span class="n">User</span>
<span class="kn">from</span> <span class="nn">django.db.models.signals</span> <span class="kn">import</span> <span class="n">pre_save</span>
<span class="kn">from</span> <span class="nn">django.dispatch</span> <span class="kn">import</span> <span class="n">receiver</span>
<span class="kn">from</span> <span class="nn">django_q.tasks</span> <span class="kn">import</span> <span class="n">async_task</span>

<span class="c1"># set up the pre_save signal for our user</span>
<span class="nd">@receiver</span><span class="p">(</span><span class="n">pre_save</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="n">User</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">email_changed</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">user</span> <span class="o">=</span> <span class="n">sender</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="n">instance</span><span class="o">.</span><span class="n">pk</span><span class="p">)</span>
    <span class="k">except</span> <span class="n">sender</span><span class="o">.</span><span class="n">DoesNotExist</span><span class="p">:</span>
        <span class="k">pass</span>  <span class="c1"># new user</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="c1"># has his email changed?</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="o">.</span><span class="n">email</span> <span class="o">==</span> <span class="n">instance</span><span class="o">.</span><span class="n">email</span><span class="p">:</span>
            <span class="c1"># tell everyone</span>
            <span class="n">async_task</span><span class="p">(</span><span class="s1">&#39;tasks.inform_everyone&#39;</span><span class="p">,</span> <span class="n">instance</span><span class="p">)</span>
</pre></div>
</div>
<p>The task will send a message to everyone else informing them that the users email address has changed. Note that this adds almost no overhead to the save action:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># tasks.py</span>
<span class="k">def</span> <span class="nf">inform_everyone</span><span class="p">(</span><span class="n">user</span><span class="p">):</span>
    <span class="n">mails</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">u</span> <span class="ow">in</span> <span class="n">User</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="n">user</span><span class="o">.</span><span class="n">pk</span><span class="p">):</span>
        <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Dear </span><span class="si">{</span><span class="n">u</span><span class="o">.</span><span class="n">username</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">user</span><span class="o">.</span><span class="n">username</span><span class="si">}</span><span class="s2"> has a new email address: </span><span class="si">{</span><span class="n">user</span><span class="o">.</span><span class="n">email</span><span class="si">}</span><span class="s2">&quot;</span>
        <span class="n">mails</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="s1">&#39;New email&#39;</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span>
                      <span class="s1">&#39;from@example.com&#39;</span><span class="p">,</span> <span class="p">[</span><span class="n">u</span><span class="o">.</span><span class="n">email</span><span class="p">]))</span>
    <span class="k">return</span> <span class="n">send_mass_mail</span><span class="p">(</span><span class="n">mails</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># or do it async again</span>
<span class="k">def</span> <span class="nf">inform_everyone_async</span><span class="p">(</span><span class="n">user</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">u</span> <span class="ow">in</span> <span class="n">User</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="n">user</span><span class="o">.</span><span class="n">pk</span><span class="p">):</span>
        <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Dear </span><span class="si">{</span><span class="n">u</span><span class="o">.</span><span class="n">username</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">user</span><span class="o">.</span><span class="n">username</span><span class="si">}</span><span class="s2"> has a new email address: </span><span class="si">{</span><span class="n">user</span><span class="o">.</span><span class="n">email</span><span class="si">}</span><span class="s2">&quot;</span>
        <span class="n">async_task</span><span class="p">(</span><span class="s1">&#39;django.core.mail.send_mail&#39;</span><span class="p">,</span>
                <span class="s1">&#39;New email&#39;</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="s1">&#39;from@example.com&#39;</span><span class="p">,</span> <span class="p">[</span><span class="n">u</span><span class="o">.</span><span class="n">email</span><span class="p">])</span>
</pre></div>
</div>
<p>Of course you can do other things beside sending emails. These are just generic examples. You can use signals with async to update fields in other objects too.
Let’s say this users email address is not just on the User object, but you stored it in some other places too without a reference.
By attaching an async action to the save signal, you can now update that email address in those other places without impacting the the time it takes to return your views.</p>
</section>
<section id="reports">
<h2>Reports<a class="headerlink" href="#reports" title="Link to this heading"></a></h2>
<p>In this example the user requests a report and we let the cluster do the generating, while handling the result with a hook.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Report generation with hook example</span>
<span class="kn">from</span> <span class="nn">django_q.tasks</span> <span class="kn">import</span> <span class="n">async_task</span>

<span class="c1"># views.py</span>
<span class="c1"># user requests a report.</span>
<span class="k">def</span> <span class="nf">create_report</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">async_task</span><span class="p">(</span><span class="s1">&#39;tasks.create_html_report&#39;</span><span class="p">,</span>
            <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="p">,</span>
            <span class="n">hook</span><span class="o">=</span><span class="s1">&#39;tasks.email_report&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># tasks.py</span>
<span class="kn">from</span> <span class="nn">django_q.tasks</span> <span class="kn">import</span> <span class="n">async_task</span>

<span class="c1"># report generator</span>
<span class="k">def</span> <span class="nf">create_html_report</span><span class="p">(</span><span class="n">user</span><span class="p">):</span>
    <span class="n">html_report</span> <span class="o">=</span> <span class="s1">&#39;We had a great quarter!&#39;</span>
    <span class="k">return</span> <span class="n">html_report</span>

<span class="c1"># report mailer</span>
<span class="k">def</span> <span class="nf">email_report</span><span class="p">(</span><span class="n">task</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">task</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
        <span class="c1"># Email the report</span>
        <span class="n">async_task</span><span class="p">(</span><span class="s1">&#39;django.core.mail.send_mail&#39;</span><span class="p">,</span>
                <span class="s1">&#39;The report you requested&#39;</span><span class="p">,</span>
                <span class="n">task</span><span class="o">.</span><span class="n">result</span><span class="p">,</span>
                <span class="s1">&#39;from@example.com&#39;</span><span class="p">,</span>
                <span class="n">task</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">email</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="c1"># Tell the admins something went wrong</span>
        <span class="n">async_task</span><span class="p">(</span><span class="s1">&#39;django.core.mail.mail_admins&#39;</span><span class="p">,</span>
                <span class="s1">&#39;Report generation failed&#39;</span><span class="p">,</span>
                <span class="n">task</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</pre></div>
</div>
<p>The hook is practical here, because it allows us to detach the sending task from the report generation function and to report on possible failures.</p>
</section>
<section id="haystack">
<h2>Haystack<a class="headerlink" href="#haystack" title="Link to this heading"></a></h2>
<p>If you use <a class="reference external" href="http://haystacksearch.org/">Haystack</a> as your projects search engine,
here’s an example of how you can have Django Q2 take care of your indexes in real time using model signals:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Real time Haystack indexing</span>
<span class="kn">from</span> <span class="nn">.models</span> <span class="kn">import</span> <span class="n">Document</span>
<span class="kn">from</span> <span class="nn">django.db.models.signals</span> <span class="kn">import</span> <span class="n">post_save</span>
<span class="kn">from</span> <span class="nn">django.dispatch</span> <span class="kn">import</span> <span class="n">receiver</span>
<span class="kn">from</span> <span class="nn">django_q.tasks</span> <span class="kn">import</span> <span class="n">async_task</span>

<span class="c1"># hook up the post save handler</span>
<span class="nd">@receiver</span><span class="p">(</span><span class="n">post_save</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="n">Document</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">document_changed</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="n">async_task</span><span class="p">(</span><span class="s1">&#39;tasks.index_object&#39;</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">save</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
    <span class="c1"># turn off result saving to not flood your database</span>
</pre></div>
</div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># tasks.py</span>
<span class="kn">from</span> <span class="nn">haystack</span> <span class="kn">import</span> <span class="n">connection_router</span><span class="p">,</span> <span class="n">connections</span>

<span class="k">def</span> <span class="nf">index_object</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span>
    <span class="c1"># get possible backends</span>
    <span class="n">backends</span> <span class="o">=</span> <span class="n">connection_router</span><span class="o">.</span><span class="n">for_write</span><span class="p">(</span><span class="n">instance</span><span class="o">=</span><span class="n">instance</span><span class="p">)</span>

    <span class="k">for</span> <span class="n">backend</span> <span class="ow">in</span> <span class="n">backends</span><span class="p">:</span>
        <span class="c1"># get the index for this model</span>
        <span class="n">index</span> <span class="o">=</span> <span class="n">connections</span><span class="p">[</span><span class="n">backend</span><span class="p">]</span><span class="o">.</span><span class="n">get_unified_index</span><span class="p">()</span>\
            <span class="o">.</span><span class="n">get_index</span><span class="p">(</span><span class="n">sender</span><span class="p">)</span>
        <span class="c1"># update it</span>
        <span class="n">index</span><span class="o">.</span><span class="n">update_object</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="n">using</span><span class="o">=</span><span class="n">backend</span><span class="p">)</span>
</pre></div>
</div>
<p>Now every time a Document is saved, your indexes will be updated without causing a delay in your save action.
You could expand this to dealing with deletes, by adding a <code class="docutils literal notranslate"><span class="pre">post_delete</span></code> signal and calling <code class="docutils literal notranslate"><span class="pre">index.remove_object</span></code> in the async_task function.</p>
</section>
<section id="shell">
<span id="id1"></span><h2>Shell<a class="headerlink" href="#shell" title="Link to this heading"></a></h2>
<p>You can execute or schedule shell commands using Pythons <code class="xref py py-mod docutils literal notranslate"><span class="pre">subprocess</span></code> module:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django_q.tasks</span> <span class="kn">import</span> <span class="n">async_task</span><span class="p">,</span> <span class="n">result</span>

<span class="c1"># make a backup copy of setup.py</span>
<span class="n">async_task</span><span class="p">(</span><span class="s1">&#39;subprocess.call&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;cp&#39;</span><span class="p">,</span> <span class="s1">&#39;setup.py&#39;</span><span class="p">,</span> <span class="s1">&#39;setup.py.bak&#39;</span><span class="p">])</span>

<span class="c1"># call ls -l and dump the output</span>
<span class="n">task_id</span><span class="o">=</span><span class="n">async_task</span><span class="p">(</span><span class="s1">&#39;subprocess.check_output&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;ls&#39;</span><span class="p">,</span> <span class="s1">&#39;-l&#39;</span><span class="p">])</span>

<span class="c1"># get the result</span>
<span class="n">dir_list</span> <span class="o">=</span> <span class="n">result</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
</pre></div>
</div>
<p>In Python 3.5 the subprocess module has changed quite a bit and returns a <code class="xref py py-class docutils literal notranslate"><span class="pre">subprocess.CompletedProcess</span></code> object instead:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django_q.tasks</span> <span class="kn">import</span> <span class="n">async_task</span><span class="p">,</span> <span class="n">result</span>

<span class="c1"># make a backup copy of setup.py</span>
<span class="n">tid</span> <span class="o">=</span> <span class="n">async_task</span><span class="p">(</span><span class="s1">&#39;subprocess.run&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;cp&#39;</span><span class="p">,</span> <span class="s1">&#39;setup.py&#39;</span><span class="p">,</span> <span class="s1">&#39;setup.py.bak&#39;</span><span class="p">])</span>

<span class="c1"># get the result</span>
<span class="n">r</span><span class="o">=</span><span class="n">result</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="mi">500</span><span class="p">)</span>
<span class="c1"># we can now look at the original arguments</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">r</span><span class="o">.</span><span class="n">args</span>
<span class="p">[</span><span class="s1">&#39;cp&#39;</span><span class="p">,</span> <span class="s1">&#39;setup.py&#39;</span><span class="p">,</span> <span class="s1">&#39;setup.py.bak&#39;</span><span class="p">]</span>
<span class="c1"># and the returncode</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">r</span><span class="o">.</span><span class="n">returncode</span>
<span class="mi">0</span>

<span class="c1"># to capture the output we&#39;ll need a pipe</span>
<span class="kn">from</span> <span class="nn">subprocess</span> <span class="kn">import</span> <span class="n">PIPE</span>

<span class="c1"># call ls -l and pipe the output</span>
<span class="n">tid</span> <span class="o">=</span> <span class="n">async_task</span><span class="p">(</span><span class="s1">&#39;subprocess.run&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;ls&#39;</span><span class="p">,</span> <span class="s1">&#39;-l&#39;</span><span class="p">],</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">)</span>
<span class="c1"># get the result</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">result</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="mi">500</span><span class="p">)</span>
<span class="c1"># print the output</span>
<span class="nb">print</span><span class="p">(</span><span class="n">res</span><span class="o">.</span><span class="n">stdout</span><span class="p">)</span>
</pre></div>
</div>
<p>Instead of <a class="reference internal" href="tasks.html#django_q.async_task" title="django_q.async_task"><code class="xref py py-func docutils literal notranslate"><span class="pre">async_task()</span></code></a> you can of course also use <a class="reference internal" href="schedules.html#django_q.schedule" title="django_q.schedule"><code class="xref py py-func docutils literal notranslate"><span class="pre">schedule()</span></code></a> to schedule commands.</p>
<p>For regular Django management commands, it is easier to call them directly:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django_q.tasks</span> <span class="kn">import</span> <span class="n">async_task</span><span class="p">,</span> <span class="n">schedule</span>

<span class="n">async_task</span><span class="p">(</span><span class="s1">&#39;django.core.management.call_command&#39;</span><span class="p">,</span><span class="s1">&#39;clearsessions&#39;</span><span class="p">)</span>

<span class="c1"># or clear those sessions every hour</span>

<span class="n">schedule</span><span class="p">(</span><span class="s1">&#39;django.core.management.call_command&#39;</span><span class="p">,</span>
     <span class="s1">&#39;clearsessions&#39;</span><span class="p">,</span>
     <span class="n">schedule_type</span><span class="o">=</span><span class="s1">&#39;H&#39;</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="groups">
<h2>Groups<a class="headerlink" href="#groups" title="Link to this heading"></a></h2>
<p>A group example with Kernel density estimation for probability density functions using the Parzen-window technique.
Adapted from <a class="reference external" href="http://sebastianraschka.com/Articles/2014_multiprocessing_intro.html">Sebastian Raschka’s blog</a></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Group example with Parzen-window estimation</span>
<span class="kn">import</span> <span class="nn">numpy</span>

<span class="kn">from</span> <span class="nn">django_q.tasks</span> <span class="kn">import</span> <span class="n">async_task</span><span class="p">,</span> <span class="n">result_group</span><span class="p">,</span> <span class="n">delete_group</span>

<span class="c1"># the estimation function</span>
<span class="k">def</span> <span class="nf">parzen_estimation</span><span class="p">(</span><span class="n">x_samples</span><span class="p">,</span> <span class="n">point_x</span><span class="p">,</span> <span class="n">h</span><span class="p">):</span>
    <span class="n">k_n</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">x_samples</span><span class="p">:</span>
        <span class="n">x_i</span> <span class="o">=</span> <span class="p">(</span><span class="n">point_x</span> <span class="o">-</span> <span class="n">row</span><span class="p">[:,</span> <span class="n">numpy</span><span class="o">.</span><span class="n">newaxis</span><span class="p">])</span> <span class="o">/</span> <span class="n">h</span>
        <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">x_i</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">numpy</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">row</span><span class="p">)</span> <span class="o">&gt;</span> <span class="p">(</span><span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span><span class="p">):</span>
                <span class="k">break</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">k_n</span> <span class="o">+=</span> <span class="mi">1</span>
    <span class="k">return</span> <span class="n">h</span><span class="p">,</span> <span class="p">(</span><span class="n">k_n</span> <span class="o">/</span> <span class="nb">len</span><span class="p">(</span><span class="n">x_samples</span><span class="p">))</span> <span class="o">/</span> <span class="p">(</span><span class="n">h</span> <span class="o">**</span> <span class="n">point_x</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>

<span class="c1"># create 100 calculations and return the collated result</span>
<span class="k">def</span> <span class="nf">parzen_async</span><span class="p">():</span>
    <span class="c1"># clear the previous results</span>
    <span class="n">delete_group</span><span class="p">(</span><span class="s1">&#39;parzen&#39;</span><span class="p">,</span> <span class="n">cached</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
    <span class="n">mu_vec</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">])</span>
    <span class="n">cov_mat</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">([[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">]])</span>
    <span class="n">sample</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">random</span><span class="o">.</span> \
        <span class="n">multivariate_normal</span><span class="p">(</span><span class="n">mu_vec</span><span class="p">,</span> <span class="n">cov_mat</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span>
    <span class="n">widths</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mf">1.0</span><span class="p">,</span> <span class="mf">1.2</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
    <span class="n">x</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">([[</span><span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">]])</span>
    <span class="c1"># async_task them with a group label to the cache backend</span>
    <span class="k">for</span> <span class="n">w</span> <span class="ow">in</span> <span class="n">widths</span><span class="p">:</span>
        <span class="n">async_task</span><span class="p">(</span><span class="n">parzen_estimation</span><span class="p">,</span> <span class="n">sample</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">w</span><span class="p">,</span>
                <span class="n">group</span><span class="o">=</span><span class="s1">&#39;parzen&#39;</span><span class="p">,</span> <span class="n">cached</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
    <span class="c1"># return after 100 results</span>
    <span class="k">return</span> <span class="n">result_group</span><span class="p">(</span><span class="s1">&#39;parzen&#39;</span><span class="p">,</span> <span class="n">count</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">cached</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>Django Q2 is not optimized for distributed computing, but this example will give you an idea of what you can do with task <a class="reference internal" href="group.html"><span class="doc">Groups</span></a>.</p>
<p>Alternatively the <code class="docutils literal notranslate"><span class="pre">parzen_async()</span></code> function can also be written with <a class="reference internal" href="iterable.html#django_q.async_iter" title="django_q.async_iter"><code class="xref py py-func docutils literal notranslate"><span class="pre">async_iter()</span></code></a>, which automatically utilizes the cache backend and groups to return a single result from an iterable:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># create 100 calculations and return the collated result</span>
<span class="k">def</span> <span class="nf">parzen_async</span><span class="p">():</span>
    <span class="n">mu_vec</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">])</span>
    <span class="n">cov_mat</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">([[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">]])</span>
    <span class="n">sample</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">random</span><span class="o">.</span> \
        <span class="n">multivariate_normal</span><span class="p">(</span><span class="n">mu_vec</span><span class="p">,</span> <span class="n">cov_mat</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span>
    <span class="n">widths</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mf">1.0</span><span class="p">,</span> <span class="mf">1.2</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
    <span class="n">x</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">([[</span><span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">]])</span>
    <span class="c1"># async_task them with async_task iterable</span>
    <span class="n">args</span> <span class="o">=</span> <span class="p">[(</span><span class="n">sample</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">w</span><span class="p">)</span> <span class="k">for</span> <span class="n">w</span> <span class="ow">in</span> <span class="n">widths</span><span class="p">]</span>
    <span class="n">result_id</span> <span class="o">=</span> <span class="n">async_iter</span><span class="p">(</span><span class="n">parzen_estimation</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">cached</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
    <span class="c1"># return the cached result or timeout after 10 seconds</span>
    <span class="k">return</span> <span class="n">result</span><span class="p">(</span><span class="n">result_id</span><span class="p">,</span> <span class="n">wait</span><span class="o">=</span><span class="mi">10000</span><span class="p">,</span> <span class="n">cached</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="http-health-check">
<h2>Http Health Check<a class="headerlink" href="#http-health-check" title="Link to this heading"></a></h2>
<p>An example of a python http server you can use (localhost:8080) to validate the health status of all the clusters in your environment.  Example is http only.</p>
<p>Requires cache to be enabled. Save file in your Django project’s root directory and run with command: <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">worker_hc.py</span></code> in your container or other environment.  Can be customized to show whatever you’d like from the Stat class or modified as needed.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">http.server</span> <span class="kn">import</span> <span class="n">BaseHTTPRequestHandler</span><span class="p">,</span> <span class="n">HTTPServer</span>
<span class="kn">from</span> <span class="nn">mtt_app.settings.base</span> <span class="kn">import</span> <span class="n">EMAIL_USE_TLS</span>

<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">django</span>

<span class="c1">#  Set the correct path to you settings module</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;DJANGO_SETTINGS_MODULE&quot;</span><span class="p">,</span> <span class="s2">&quot;my.settings.path&quot;</span><span class="p">)</span>

<span class="c1"># All django stuff has to come after the setup:</span>
<span class="n">django</span><span class="o">.</span><span class="n">setup</span><span class="p">()</span>

<span class="kn">from</span> <span class="nn">django_q.status</span> <span class="kn">import</span> <span class="n">Stat</span>
<span class="kn">from</span> <span class="nn">django_q.conf</span> <span class="kn">import</span> <span class="n">Conf</span>

<span class="c1"># Set host and port settings</span>
<span class="n">hostName</span> <span class="o">=</span> <span class="s2">&quot;localhost&quot;</span>
<span class="n">serverPort</span> <span class="o">=</span> <span class="mi">8080</span>


<span class="k">class</span> <span class="nc">HealthCheckServer</span><span class="p">(</span><span class="n">BaseHTTPRequestHandler</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">do_GET</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>

        <span class="c1"># Count the clusters and their status</span>
        <span class="n">happy_clusters</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="n">total_clusters</span> <span class="o">=</span> <span class="mi">0</span>

        <span class="k">for</span> <span class="n">stat</span> <span class="ow">in</span> <span class="n">Stat</span><span class="o">.</span><span class="n">get_all</span><span class="p">():</span>
            <span class="n">total_clusters</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="k">if</span> <span class="n">stat</span><span class="o">.</span><span class="n">status</span> <span class="ow">in</span> <span class="p">[</span><span class="n">Conf</span><span class="o">.</span><span class="n">IDLE</span><span class="p">,</span> <span class="n">Conf</span><span class="o">.</span><span class="n">WORKING</span><span class="p">]:</span>
                <span class="n">happy_clusters</span> <span class="o">+=</span> <span class="mi">1</span>

        <span class="c1"># Return 200 response if there is at least 1 cluster running,</span>
        <span class="c1"># and make sure all running clusters are happy</span>
        <span class="k">if</span> <span class="n">total_clusters</span> <span class="ow">and</span> <span class="n">happy_clusters</span> <span class="o">==</span> <span class="n">total_clusters</span><span class="p">:</span>
            <span class="n">response_code</span> <span class="o">=</span> <span class="mi">200</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">response_code</span> <span class="o">=</span> <span class="mi">500</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">send_response</span><span class="p">(</span><span class="n">response_code</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">send_header</span><span class="p">(</span><span class="s2">&quot;Content-type&quot;</span><span class="p">,</span> <span class="s2">&quot;text/html&quot;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">end_headers</span><span class="p">()</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">wfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span>
            <span class="nb">bytes</span><span class="p">(</span><span class="s2">&quot;&lt;html&gt;&lt;head&gt;&lt;title&gt;Django-Q Heath Check&lt;/title&gt;&lt;/head&gt;&quot;</span><span class="p">,</span> <span class="s2">&quot;utf-8&quot;</span><span class="p">)</span>
        <span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">wfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span>
            <span class="nb">bytes</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;&lt;p&gt;Health check returned </span><span class="si">{</span><span class="n">response_code</span><span class="si">}</span><span class="s2"> response&lt;/p&gt;&quot;</span><span class="p">,</span> <span class="s2">&quot;utf-8&quot;</span><span class="p">)</span>
        <span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">wfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span>
            <span class="nb">bytes</span><span class="p">(</span>
                <span class="sa">f</span><span class="s2">&quot;&lt;p&gt;</span><span class="si">{</span><span class="n">happy_clusters</span><span class="si">}</span><span class="s2"> of </span><span class="si">{</span><span class="n">total_clusters</span><span class="si">}</span><span class="s2"> cluster(s) are happy&lt;/p&gt;&lt;/html&gt;&quot;</span><span class="p">,</span>
                <span class="s2">&quot;utf-8&quot;</span><span class="p">,</span>
            <span class="p">)</span>
        <span class="p">)</span>


<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="n">webServer</span> <span class="o">=</span> <span class="n">HTTPServer</span><span class="p">((</span><span class="n">hostName</span><span class="p">,</span> <span class="n">serverPort</span><span class="p">),</span> <span class="n">HealthCheckServer</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Server started at http://</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">hostName</span><span class="p">,</span> <span class="n">serverPort</span><span class="p">))</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="n">webServer</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
    <span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span class="p">:</span>
        <span class="k">pass</span>

    <span class="n">webServer</span><span class="o">.</span><span class="n">server_close</span><span class="p">()</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Server stopped.&quot;</span><span class="p">)</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>If you have an example you want to share, please submit a pull request on <a class="reference external" href="https://github.com/GDay/django-q2/">github</a>.</p>
</div>
</section>
</section>


           </div>
          </div>
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
        <a href="architecture.html" class="btn btn-neutral float-left" title="Architecture" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>&#169; Copyright 2015-2023, Ilan Steemers - 2022, Stan Triepels.</p>
  </div>

  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
   

</footer>
        </div>
      </div>
    </section>
  </div>
  <script>
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script> 

</body>
</html>