developer tip

플라스크 응용 프로그램에서 전역 상태 유지

optionbox 2021. 1. 8. 08:07
반응형

플라스크 응용 프로그램에서 전역 상태 유지


flask응용 프로그램에 캐시 사전을 저장하려고 합니다.

내가 이해하는 한 Application Context , 특히 flask.g 객체를 사용해야합니다.

설정:

import flask as f

app = f.Flask(__name__)

이제 내가하면 :

with app.app_context():
    f.g.foo = "bar"
    print f.g.foo

그것은 인쇄합니다 bar.

다음으로 계속 :

with app.app_context():
    print f.g.foo

AttributeError: '_AppCtxGlobals' object has no attribute 'foo'

나는 그것을 이해하지 못하고 문서는 전혀 도움이되지 않습니다. 올바르게 읽으면 상태가 보존되어야합니다.

내가 가진 또 다른 아이디어 는 단순히 모듈 전체 변수를 사용하는 것입니다.

cache = {}

def some_function():
    cache['foo'] = "bar"

그러나 모든 요청에 ​​따라 재설정되는 것처럼 보입니다.

올바르게 수행하는 방법은 무엇입니까?

편집 : Flask 10.1


귀하의 질문에 따르면 "글로벌"의 정의에 대해 혼란 스럽습니다.

스톡 Flask 설정에는 여러 스레드와 잠재적으로 여러 프로세스가 요청을 처리하는 Flask 서버가 있습니다. "itemlist = []"와 같은 스톡 전역 변수가 있고 모든 요청에서 계속 추가하고 싶다고 가정합니다 (예 : 누군가가 엔드 포인트에 POST 요청을 할 때마다). 이것은 이론과 실제에서 완전히 가능합니다. 그것은 또한 정말 나쁜 생각입니다.

문제는 어떤 스레드와 프로세스가 "승리"할지 쉽게 제어 할 수 없다는 것입니다. 목록이 정말 불안정한 순서로 올라가거나 완전히 손상 될 수 있습니다. 이제 잠금, 뮤텍스 및 기타 기본 요소에 대해 이야기해야합니다. 이것은 어렵고 성가신 일입니다.

웹 서버 자체를 가능한 한 상태 비 저장으로 유지해야합니다. 각 요청은 완전히 독립적이어야하며 서버에서 어떤 상태도 공유하지 않아야합니다. 대신 상태를 처리 할 데이터베이스 또는 캐싱 계층을 사용하십시오. 이것은 더 복잡해 보이지만 실제로는 더 간단합니다. 예를 들어 SQLite를 확인하십시오. 매우 간단합니다.

'flask.g'객체를 처리하기 위해 요청별로 전역 객체입니다 .

http://flask.pocoo.org/docs/api/#flask.g

요청 사이에 "깨끗한"상태이며 요청간에 상태를 공유하는 데 사용할 수 없습니다.


이 라인

with app.app_context():
    f.g.foo = "bar"

"with"키워드 __exit__를 사용하고 있으므로이 루프가 실행되면 AppContext 클래스 메서드를 호출합니다 . 참조 . 따라서 'foo'는 일단 완료되면 튀어 나옵니다. 그래서 다시 사용할 수 없습니다. 대신 시도해 볼 수 있습니다.

ctx = app.app_context()
f.g.foo = 'bar'
ctx.push()

다음을 호출 할 때까지 g.foo를 사용할 수 있어야합니다.

ctx.pop()

캐싱 목적으로 이것을 사용하고 싶은지 확실하지 않습니다.


두 개의 소프트웨어를 통합하는 데 사용하는 플라스크 서버에서 사용하는 "모듈 전체 변수"아이디어와 유사한 작업을 수행했습니다. 여기서는 한 명의 동시 "사용자"(발신자 소프트웨어) 만 가질 수 있습니다. .

내 app.py는 다음과 같습니다.

from flask import Flask
from flask.json import jsonify
app = Flask(__name__)

cache = {}

@app.route("/create")
def create():
    cache['foo'] = 0
    return jsonify(cache['foo'])

@app.route("/increment")
def increment():
    cache['foo'] = cache['foo'] + 1
    return jsonify(cache['foo'])

@app.route("/read")
def read():
    return jsonify(cache['foo'])

if __name__ == '__main__':
    app.run()

다음과 같이 테스트 할 수 있습니다.

import requests

print(requests.get('http://127.0.0.1:5000/create').json())
print(requests.get('http://127.0.0.1:5000/increment').json())
print(requests.get('http://127.0.0.1:5000/increment').json())
print(requests.get('http://127.0.0.1:5000/read').json())
print(requests.get('http://127.0.0.1:5000/increment').json())
print(requests.get('http://127.0.0.1:5000/create').json())
print(requests.get('http://127.0.0.1:5000/read').json())

출력 :

0
1
2
2
3
0
0

적절한 다중 사용자 웹 서버 환경에서 작동하지 않을 것으로 예상하므로주의해서 사용하십시오.

ReferenceURL : https://stackoverflow.com/questions/19277280/preserving-global-state-in-a-flask-application

반응형