где разместить планировщик внутри кода моего веб-приложения? - PullRequest
0 голосов
/ 10 апреля 2020

У меня есть веб-приложение, которое сначала получает аутентификацию пользователя для токена API, затем я хочу запускать последнюю часть кода каждый час, используя модуль APScheduler. Я не хочу запускать все приложение с самого начала, потому что первая часть требует взаимодействия с пользователем для повторной авторизации приложения, что не нужно после первого запуска, потому что у нас есть токен, плюс я, очевидно, не могу там нажимать кнопку авторизации каждый раз час. Куда я помещаю часть кода sched.start ()? Я получаю сообщение об ошибке RuntimeError: Работа вне контекста запроса.

import requests
import json
from flask import Flask, render_template, request, redirect, session, url_for
from flask.json import jsonify
import os
from requests_oauthlib import OAuth2Session
from apscheduler.schedulers.background import BackgroundScheduler
import atexit
from datetime import datetime

app = Flask(__name__)

client_id = "x"
client_secret = "x"
scope = 'read_station'
password = 'x'
#grant_type = 'authorization_code'
grant_type = 'password'
username='x'
authurl = 'https://api.netatmo.com/oauth2/authorize?'
token_url = 'https://api.netatmo.com/oauth2/token'
redirect_uri = 'x'
response_type = 'code'
code = None
payload= {'grant_type':grant_type,'client_id':client_id,'client_secret':client_secret,
'username':username,'password':password,'scope':scope}

rip={}
CITIES = {'bolzano' : 'lat_ne=46.30&lon_ne=11.23&lat_sw=46.28&lon_sw=11.14',
'florence' : 'lat_ne=43.51&lon_ne=11.21&lat_sw=43.44&lon_sw=11.02',
'manchester' : 'lat_ne=53.35&lon_ne=-2.0011.21&lat_sw=53.21&lon_sw=-2.36',
}
dicty = {}
def dooby(CITIES, Header):
    for city in CITIES.keys():
        i = requests.get('https://api.netatmo.com/api/getpublicdata?'+CITIES[city]+'&filter=false', headers = Header).json()
        dicty[str(city)]=i
    return dicty

@app.route('/')
def auth():
    redirect_uri = url_for('.redir', _external = True)
    oauth = OAuth2Session(client_id, redirect_uri = redirect_uri,
                          scope = scope)
    authorization_url, state = oauth.authorization_url(authurl)
    session['oauth_state'] = state
    return redirect(authorization_url)

@app.route('/redir', methods = ["GET","POST"])
def redir():
    code = request.args.get('code')
    payload['code']=code
    rip = requests.post(token_url, data=payload)
    rs = rip.content.decode()
    response = json.loads(rs)
    session['oauth_token'] = response['access_token']
    session['expiry'] = response['expires_in']
    session['refresh_token'] = response['refresh_token']

    return redirect(url_for('.profile'))

@app.route('/profile', methods = ["GET","POST"])

def profile():
    Header = {'Authorization':'Bearer '+session['oauth_token']}
    def repeat():
        return dooby(CITIES, Header)
    i = repeat()
    job = json.dumps(i)
    dt = datetime.now().strftime("%Y_%m_%d %H_%M_%S")
    f = open(r'C:\Users\freak\OneDrive\Documents\UHIpaper\{}.json'.format(dt),"w")
    f.write(job)
    f.close()
    sched = BackgroundScheduler(daemon=True)
    sched.add_job(func = profile,trigger='interval',minutes=2)
    sched.start()
    return jsonify(i)

if __name__ == "__main__":
    os.environ['DEBUG'] = "1"
    os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = "1"
    app.secret_key = os.urandom(24)
    app.run(debug=True)
...