플라스크 CLI가 Flask.run보다 권장되는 이유는 무엇입니까?


13

Flask 0.11에는 flaskCLI가 도입되었습니다. 문서와 변경 로그 상태가 모두 권장됩니다.

개발 서버 문서 :

Flask 0.11부터는 개발 서버를 실행하는 여러 가지 기본 제공 방법이 있습니다. 가장 좋은 방법은 플라스크 명령 줄 유틸리티이지만이 Flask.run()방법을 계속 사용할 수도 있습니다 .

커맨드 라인

플라스크 는 우수한 다시로드 경험을 제공하기 때문에 명령 줄 스크립트 (명령 줄 인터페이스)를 강하게 그것으로 인해 응용 프로그램을로드하는 방법을 개발하는 것이 좋습니다. 기본 사용법은 다음과 같습니다.

$ export FLASK_APP=my_application
$ export FLASK_DEBUG=1
$ flask run

변경 내역 :

  • click CLI 시스템을 통해 로컬 디버그 서버를 시작 flask하는 flask.cli모듈이 추가되었습니다 . flask.run()다른 디자인으로 인해 더 빠르고 안정적으로 작동하고 교체 되므로 이전 방법 보다 권장 Flask-Script됩니다.

지금까지 나는이 "우수한 재 장전 경험"을 보지 못했습니다. 사용자 지정 스크립트를 통해 CLI를 사용하는 시점을 알 수 없습니다.

를 사용하는 경우 Flask.run간단히 파이썬 파일을 작성합니다.

#!/usr/bin/env python3
from my_app import app


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

CLI를 사용하는 경우 환경 변수를 지정해야합니다. CLI 문서 activate에는 virtualenvwrapper 스크립트에 통합 될 수 있다고 언급되어 있습니다 . 개인적으로 나는 이것이 응용 프로그램의 일부라고 생각하고 버전 관리하에 있어야한다고 생각합니다. 아아, 쉘 스크립트가 필요합니다 :

#!/usr/bin/env bash
export FLASK_APP=my_app:app
export FLASK_DEBUG=1

flask run

물론 Windows 사용자가 공동 작업을 시작하자마자 추가 bat 스크립트가 함께 제공됩니다.

또한 첫 번째 옵션은 실제 앱을 시작하기 전에 Python으로 작성된 설정을 허용합니다.

예를 들어

  • 파이썬에서 명령 줄 인수를 구문 분석하는 방법
  • 앱을 실행하기 전에 로깅을 설정하는 방법

그들은 사용자 정의 명령을 추가 할 수 있다고 홍보하는 것 같습니다. 선택 사항으로 진입 점을 통해 노출되는 간단한 Python 스크립트를 작성하는 것보다 이것이 왜 더 나은지 알 수 없습니다.

Python 실행 스크립트를 사용하여 구성된 로거를 사용할 때 로깅 출력 예 :

$ ./run.py 
   DEBUG 21:51:22 main.py:95) Configured logging
    INFO 21:51:22 _internal.py:87)  * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
    INFO 21:51:22 _internal.py:87)  * Restarting with inotify reloader
   DEBUG 21:51:22 main.py:95) Configured logging
 WARNING 21:51:22 _internal.py:87)  * Debugger is active!
    INFO 21:51:22 _internal.py:87)  * Debugger pin code: 263-225-431
   DEBUG 21:51:25 inotify_buffer.py:61) in-event <InotifyEvent: src_path=b'my_app/main.py', wd=272, mask=IN_MODIFY, cookie=0, name=b'main.py'>
   DEBUG 21:51:25 inotify_buffer.py:61) in-event <InotifyEvent: src_path=b'my_app/main.py', wd=272, mask=IN_MODIFY, cookie=0, name=b'main.py'>
    INFO 21:51:25 _internal.py:87)  * Detected change in 'my_app/main.py', reloading
    INFO 21:51:26 _internal.py:87)  * Restarting with inotify reloader
   DEBUG 21:51:26 main.py:95) Configured logging
 WARNING 21:51:26 _internal.py:87)  * Debugger is active!
    INFO 21:51:26 _internal.py:87)  * Debugger pin code: 263-225-431

CLI :를 사용하여 구성된 로거를 사용할 때의 로깅 출력 예 : 프로세스에서 루트 로거를 초기에 충분히 설정할 수 없습니다.

$ ./run.sh 
 * Serving Flask app "appsemble.api.main:app"
 * Forcing debug mode on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with inotify reloader
   DEBUG 21:51:33 main.py:95) Configured logging
 * Debugger is active!
 * Debugger pin code: 187-758-498
   DEBUG 21:51:34 main.py:95) Configured logging
   DEBUG 21:51:37 inotify_buffer.py:61) in-event <InotifyEvent: src_path=b'my_app/main.py', wd=272, mask=IN_MODIFY, cookie=0, name=b'main.py'>
   DEBUG 21:51:37 inotify_buffer.py:61) in-event <InotifyEvent: src_path=b'my_app/main.py', wd=272, mask=IN_MODIFY, cookie=0, name=b'main.py'>
 * Detected change in 'my_app/main.py', reloading
    INFO 21:51:37 _internal.py:87)  * Detected change in 'my_app/main.py', reloading
 * Restarting with inotify reloader
    INFO 21:51:38 _internal.py:87)  * Restarting with inotify reloader
 * Debugger is active!
 * Debugger pin code: 187-758-498
   DEBUG 21:51:38 main.py:95) Configured logging

내 실제 질문은 간단합니다.

플라스크 CLI가 권장되는 이유는 무엇 Flask.run입니까?

답변:


11

개발 서버 문서에서 run () 호출 및 자동으로 코드 다시로드에 문제가 있음을 나타냅니다.

이것은 일반적인 경우에는 잘 작동하지만 개발에는 잘 작동하지 않으므로 Flask 0.11부터 플라스크 방법이 권장됩니다. 재로드 메커니즘의 작동 방식으로 인해 특정 코드를 두 번 실행하거나 때로는 메시지없이 충돌하거나 구문 또는 가져 오기 오류가 발생하면 죽는 등의 기묘한 부작용이 발생하기 때문입니다.

그들은 CLI 가이 문제로 고통받지 않는다고 주장합니다.

(가) 먼저이 문제에 터치 보인다 커밋은 이것이다 : https://github.com/pallets/flask/commit/3bdb90f06b9d3167320180d4a5055dcd949bf72f

그리고 Armin Ronacher는 다음과 같이 썼습니다.

지원되지 않는 자동 리로딩으로 개발할 때는이 기능을 사용하지 않는 것이 좋습니다. 대신 flask명령 행 스크립트의 runserver지원 을 사용해야합니다 .

Aaron Hall이 언급했듯이 교체 된 모듈에 정의 된 클래스의 인스턴스 인 모든 객체는 인스턴스화되지 않으며 모듈을 다시로드 할 때마다 run () 사용이 문제가 될 수 있습니다. 가져 오는 모듈도 다시로드되지 않습니다.

이에 대한 자세한 내용은 Python 3의 https://docs.python.org/3/library/importlib.html?highlight=importlib#module-importlib 에서 확인할 수 있습니다.

상태는 다음과 같습니다.

파이썬의 다른 모든 객체와 마찬가지로 이전 객체는 참조 횟수가 0으로 떨어진 후에 만 ​​재생됩니다.

이전 객체에 대한 다른 참조 (예 : 모듈 외부의 이름)는 새 객체를 참조하기 위해 리 바인드되지 않으며 원하는 경우 각 네임 스페이스에서 업데이트되어야합니다.

모듈을 다시로드하면 해당 사전 (모듈의 전역 변수 포함)이 유지됩니다. 이름을 재정의하면 이전 정의가 재정의되므로 일반적으로 문제가되지 않습니다. 새 버전의 모듈이 이전 버전으로 정의 된 이름을 정의하지 않으면 이전 정의가 그대로 유지됩니다.

따라서 새로운 프로세스를 작성하고 이전 프로세스를 종료하면 사용되지 않는 모든 참조가 자연스럽게 제거됩니다.

또한 Flask의 CLI는 '클릭'모듈을 사용하여 사용자 정의 명령을 매우 쉽게 추가 할 수 있지만, 가장 중요한 것은 재로드 버그 수정 외에도 응용 프로그램을 실행하고 사용자 정의 명령을 추가하는 표준화 된 방법을 제공합니다. 여러 가지 방법으로 동일한 작업을 수행하는 것이 아니라 여러 팀과 응용 프로그램간에 Flask를 더 친숙하게 만들 수 있기 때문에 이것은 매우 좋은 것 같습니다.

파이썬의 선에 따라 플라스크를 더 많이 만드는 진정한 방법처럼 보입니다.

그것을하는 명백한 방법이 있어야합니다.


2
다음은 Armin이 "나쁜 지원"을 의미한다고 생각하는 것입니다. Python에서 모듈을 다시로드해도 해당 모듈이 가져 오는 모듈을 다시로드하지 않으며 다른 모듈의 이름을 기존 객체를 가리키는 새 모듈의 이름으로 다시 연결하지 않습니다. 새 모듈을 동일한 프로세스로 핫 스왑하는 것은 문제가됩니다. 코드를 변경하려고 할 때 새로운 프로세스를 시작하는 것이 훨씬 좋습니다.
Aaron Hall

당신이 그것을 언급 했으므로, 나는 당신이 묘사 한 행동을 기억합니다. 명백해 주셔서 감사합니다! 그에 따라 답변을 편집하겠습니다.
Martin Jungblut Schreiner

좋아요, 더하기 1은 플러스입니다. :)
Aaron Hall

Aaron Hall의 추가로 나를 위해 그것을 명확하게했습니다. 감사. :)
Remco Haszing

7
왜 환경 변수를 사용해야 FLASK_APP합니까? 이것이 작동하는 방식에 내재되어 있습니까? 왜 flask run새로운 이민자를 쉽게 가입시킬 수있는 논쟁과 같은 것을 받아들이지 않는지 궁금 합니다. 감사합니다.
John Wheeler
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.