Django - 如何以固定间隔进行API调用

时间:2018-05-09 12:15:17

标签: ajax django

我想做什么: 我已经构建了一个仪表板,显示了我从Zendesk.com的API获得的关键性能指标。它需要定期更新(我正在尝试使用time.sleep()来完成此操作)但它不能太频繁,因为我每分钟有700个请求限制。我使用Django所以我可以创建一个界面来显示数据。它永远不会被用作网站。

问题: 我使用jquery" get"调用从我的脚本中获取数据。如果我使用" python manage.py runserver"它最终创造了我猜的是许多工人,并且经常调用我的脚本,并且使用Zendesk超过我的700请求限制。如果我使用" python manage.py runserver --nothreading"无论如何,当我点击导航栏中的按钮或尝试刷新页面时,我必须等待我的脚本在完成任务之前完全运行。

我的计划的相关代码:

例如,在html代码中,我从json调用数据:

     <script type="text/javascript">
         $(document).ready(function() {
           function pollSiteData () {
           $.get('/nb_new/', function(resp) {
             $('#nb_new').text(resp['nb_new']);
           });
           window.setTimeout(pollSiteData,10000);
           }
           pollSiteData();
           });
     </script>

哪些调用基于类的视图:

url(r'^nb_new/',views.SiteNumberView.as_view())

视图如下(xxxxxx是我的登录信息,用于测试目的):

class SiteNumberView(views.APIView):
    def get(self, request, *args, **kwargs):
        data = engine.main("xxxxx","xxxxxx","xxxxxx")
        return JsonResponse(data)

上面基于类的视图调用函数&#34; main&#34;来自我制作的文件engine.py。

功能是:

def main(*args):
    client = ZenClient(args)
    time.sleep(45)
    print("Next iteration")
    return get_infos(client, "open", "pending", "new")

Main函数调用get_infos,它返回一个我转换为json的dictonary。

def get_infos(client, status, status2, status3):

    #Script that downloads stats from Zendesk

    return {"nb_new": str(len(filtered_new_tickets))}

当我运行&#34; python manage.py runserver&#34;我们可以看到它经常使用我的脚本:

Next iteration
Next iteration
Next iteration
[09/May/2018 08:01:21] "GET /nb_new/ HTTP/1.1" 200 86
Next iteration
[09/May/2018 08:01:30] "GET /nb_new/ HTTP/1.1" 200 86
Next iteration
[09/May/2018 08:01:35] "GET /nb_new/ HTTP/1.1" 200 86
Next iteration
[09/May/2018 08:01:51] "GET /nb_new/ HTTP/1.1" 200 86
[09/May/2018 08:02:04] "GET /nb_new/ HTTP/1.1" 200 86
Next iteration

当我使用&#34; python manage.py runserver --nothreading&#34;它以良好的间隔进行调用,但界面上的按钮无响应。 (我想,因为它必须先完成脚本才能确认按下按钮。)

以下是我的界面图片(&#34; nb_new&#34;更新&#34旁边的门票数量;支持需求响应&#34;)

Interface

结论/问题:如何确保我的脚本只运行,让我们说每分钟15秒,但仍然让界面响应按钮按下或刷新页面?请尽量避免提供需要我使用完全不同的框架的解决方案。不幸的是,时间是一种非常稀缺的资源。

1 个答案:

答案 0 :(得分:1)

这是一个简单的解决方案:

  1. 创建一个单独的Python脚本,专门用于定期ping Zendesk API。当新数据到达时,它会将数据放入队列或数据库中。
  2. 创建一个响应jQuery调用的Django视图。它将从数据库或队列中读取数据并将其返回给jQuery请求。它实际上不会向Zendesk API本身发出请求。
  3. 存储新更新的更简单方法是为此数据创建专用模型。创建此模型的一个实例,并在新数据到达时不断更新其状态(字段值),而不是每次都创建单独的对象。然后从您的角度来看,无论何时获得jQuery调用,都可以返回此对象。

    如果您不喜欢使用此模型和数据库方法,则可以使用基于内存的数据库(队列)来存储脚本中的数据,然后从Django视图访问它。我推荐Redis。

    示例脚本:

    # start_server.py
    
    import subprocess
    import threading
    import time
    
    
    def ping():
        while True:
            print("Pinging ...") # do actual API pinging stuff here
            time.sleep(10)
    
    t = threading.Thread(target=ping)
    t.start() # this will run the `ping` function in a separate thread
    
    # now start the django server
    subprocess.call(['python', 'manage.py', 'runserver'])
    

    现在,您所要做的就是运行python start_server.py,它将自动运行Django服务器以及API ping功能。