Google App Engine, запуск / остановка непрерывного сценария при нажатии кнопки

Я ищу руководство для достижения функции запуска / остановки функции, которая делает restAPI для restAPI извлечения данных в формате JSON, нажатием кнопки на отображаемой странице html через webapp2 и размещением на GAE?

Текущее поведение после завершения HTTP-запроса завершается функцией, которая была вызвана, конечно, останавливается (в while self._running == True ) (нормальное поведение в соответствии с документацией GAE).

main.py:

 #!/usr/bin/env python # import webapp2 from google.appengine.api import urlfetch from matplotlib.path import Path as mpPath import json import base64 import socket import logging from threading import Thread import jinja2 template_dir = os.path.join(os.path.dirname(__file__)) jinja_env = jinja2.Environment(loader = jinja2.FileSystemLoader(template_dir), extensions=['jinja2.ext.autoescape'], autoescape=True) # create a UDP socket for sending the commands sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # create the stop / start functionality of a thread that runs infinite until # thread is terminated class CMX: def __init__(self): self._running = True def terminate(self): self._running = False def run(self): storedCredentials = False username = None password = None ip_address = 'someip' # commands are send to the broadcast address for addressing the zones(bays) port = someport # use of port 50011 because no return packet is send back, could cause the # lights not to execute the command when using broadcast. # define the boundaries of the different zones zone = [[(106.03,141.19),(158.94,141.19),(158.94,194.50),(106.03,194.50)], [(103.76,168),(62.26,168),(62.26,77.86),(103.67,77.86)], [(106.38,77.86),(191.95,77.86),(191.95,106.52),(106.38,106.52)]] flag_zone_1 = False flag_zone_2 = False flag_zone_3 = False while self._running == True: restURL = 'http://someurl' print restURL if not storedCredentials: username = 'username' password = 'password' storedCredentials = True try: request = urlfetch.fetch(url = restURL, headers={"Authorization": "Basic %s" % base64.b64encode(username +':'+ password)}) <perform actions and other function calls> . . except urlfetch.Error: logging.exception('Caught exception fetching url') class Handler(webapp2.RequestHandler): def write(self, *a, **kw): self.response.out.write(*a, **kw) def render_str(self, template, **params): t = jinja_env.get_template(template) return t.render(params) def render(self, template, **kw): self.write(self.render_str(template, **kw)) class MainPage(Handler): def get(self): button = "Start Demo" running = False self.render('page.html', button = button, run = running) def post(self): startDemo = CMX() t = Thread(target=startDemo.run, args=()) t.daemon = True if self.request.get('button') == "Start Demo": button = "Stop Demo" running = True self.render('page.html', button = button, run = running) t.start() else: button = "Start Demo" running = False self.render('page.html', button = button, run = running) startDemo.terminate() def which_zone(xcoord, ycoord, zone): point = (xcoord, ycoord) in_zone_1 = mpPath(zone[0]).contains_point(point) in_zone_2 = mpPath(zone[1]).contains_point(point) in_zone_3 = mpPath(zone[2]).contains_point(point) if in_zone_1 == True: return "Zone 1" elif in_zone_2 == True: return "Zone 2" elif in_zone_3 == True: return "Zone 3" def dim_lights(ip_address, port, control_string, sock): control_string = control_string + 'S0F10' +'\r' #sock.sendto(control_string, (ip_address, port)) return control_string def norm_lights(ip_address, port, control_string, sock): control_string = control_string + 'S255F10' +'\r' #sock.sendto(control_string, (ip_address, port)) return control_string app = webapp2.WSGIApplication([('/', MainPage)], debug=True) 

page.html:

 {% extends "base.html" %} {% block comment %} {% autoescape true %} <form method="post"> <div> <input type="submit" name="button" value="{{button}}"> <input type="hidden" name="run" value="{{run}}"> </div> <!-- <div>macAddress: <input type="text" name="macAddress"><br> <input type="submit" value="Submit"> </div> --> </form> {% endautoescape %} {% endblock %} 

One Solution collect form web for “Google App Engine, запуск / остановка непрерывного сценария при нажатии кнопки”

Функция запуска / остановки проста – просто сделайте кнопку управления чем-то вроде флага operation_is_stopped сохраняется в запросах (например, в хранилище данных).

В случае, если вы этого не осознали, ваша трудность действительно связана с достижением непрерывной операции, которую вы хотите контролировать с помощью этой кнопки. Это то, что на самом деле не совместимо с GAE – все в GAE вращается вокруг ответа на запросы в течение ограниченного времени . Вы действительно не можете бесконечно запускать процессы / потоки в GAE.

Но во многих случаях можно реализовать длительную итеративную непрерывную операцию (например, ваш) как поток короткоживущих операций. В GAE, который может быть легко достигнут с помощью очередей задач – каждая итерация (в вашем случае тело while self._running == True loop) реализована как ответ на запрос очереди задач.

Поток запускается путем постановки на охрану соответствующей задачи при срабатывании «запуска». Поток поддерживается путем задания соответствующей задачи после обработки предыдущего запроса задачи. И он остановлен, не ставя в очередь новую задачу 🙂

Что-то в этом роде:

 def post(self): # handler for the "long running" task requests # need to rebuild/restore your request context every time ... try: request = urlfetch.fetch(...) <perform actions and other function calls> except: ... finally: if not operation_is_stopped: # enqueue another "long running" task task = taskqueue.add(...) 
  • Python не может найти модуль «clientsecrets» при попытке настроить oauth2 в Django с помощью API Google Python
  • Как избежать «Не удалось получить токен доступа: {« error »:« invalid_grant »} в автономных задачах CAE cron?
  • Django 1.3 в appengine
  • Двигатель приложения: разница между NDB и Datastore
  • Новая функция GAE NDB Datastore: объекты Access Datastore из другого приложения GAE
  • Недействительный аргумент сокета приложения Engine
  • Неполные ответы на запросы BigQuery Google по нечетным попыткам
  • Ошибка памяти GAE при записи в облачное хранилище, могу ли я передать поток?
  • импортировать модуль механизации в скрипт python
  • Как получить встроенный объект с повторяющимися свойствами с помощью datastore java client
  • После перехода в хранилище данных с высокой репликацией
  •  
    Interesting Posts for Van-Lav

    Обслуживание роли PyPI – Владельцы против Maintainers

    Предоставляет ли python официальную поддержку повторного использования переменной цикла после цикла?

    Присвоить строки идентификаторам в Python

    Почему этот скрипт Python работает на 4 раза медленнее на нескольких ядрах, чем на одном ядре

    Boto Ec2 и эластичные IP-адреса

    Установка тензорного потока на окна

    как скачать полную последовательность генома в biopython entrez.esearch

    Как node.js может быть быстрее c и java? Сравнительный пример: node.js, c, java и python

    Колба и пушки, несколько модулей: круговой импорт – не все маршруты доступны

    python: принудительно не относительный импорт?

    Какой идиоматический способ выполнить операцию агрегации и переименования в пандах

    Создание изображения в Python с использованием подушки (PIL)

    Каковы преимущества или различия в «assert False» и «self.assertFalse»,

    Python Logging setlevel

    Почему качество изображений JPEG, созданных PIL, настолько плохое?

    Python - лучший язык программирования в мире.