Flask과 Python 3를 사용하여 첫 번째 웹 应用程序 만들기

저자는 Write for DOnations 프로그램의 일환으로 Free and Open Source Fund에 기부금을 전달하기로 선택했습니다.

서론

Flask는 Python 언어로 웹 애플리케이션을 만들기 위한 유용한 도구와 기능을 제공하는 경량급 Python 웹 프레임워크입니다. 개발자에게 유연성을 제공하며, 단일 Python 파일만으로 빠르게 웹 애플리케이션을 구축할 수 있어 신규 개발자에게 접근하기 쉬운 프레임워크입니다. Flask는 확장 가능하며, 특정 디렉토리 구조를 강요하거나 시작하기 전에 복잡한 상용구 코드를 필요로 하지 않습니다.

Flask를 배우면 Python에서 빠르게 웹 애플리케이션을 만들 수 있습니다. Python 라이브러리를 활용하여 데이터를 데이터베이스에 저장하거나 웹 양식을 검증하는 등 고급 기능을 웹 애플리케이션에 추가할 수 있습니다.

이 튜토리얼에서는 브라우저에 HTML 텍스트를 렌더링하는 작은 웹 애플리케이션을 구축할 것입니다. Flask를 설치하고, Flask 애플리케이션을 작성하고 실행하며, 개발 모드에서 애플리케이션을 실행할 것입니다. 라우팅을 사용하여 웹 애플리케이션에서 다양한 목적을 가진 웹 페이지를 표시할 것입니다. 또한 뷰 함수를 사용하여 사용자가 동적 경로를 통해 애플리케이션과 상호 작용할 수 있도록 할 것입니다. 마지막으로 디버거를 사용하여 오류를 해결할 것입니다.

사전 준비

1단계 — Flask 설치

이 단계에서는 Python 환경을 활성화하고 pip 패키지 설치 프로그램을 사용하여 Flask를 설치합니다.

먼저, 아직 활성화하지 않았다면 프로그래밍 환경을 활성화하세요:

  1. source env/bin/activate

프로그래밍 환경을 활성화한 후, pip install 명령을 사용하여 Flask를 설치하세요:

  1. pip install flask

설치가 완료되면, 다음과 유사한 출력의 마지막 부분에 설치된 패키지 목록이 표시됩니다:

Output
... Installing collected packages: Werkzeug, MarkupSafe, Jinja2, itsdangerous, click, flask Successfully installed Jinja2-3.0.1 MarkupSafe-2.0.1 Werkzeug-2.0.1 click-8.0.1 flask-2.0.1 itsdangerous-2.0.1

이것은 Flask를 설치하면서 여러 다른 패키지도 함께 설치되었음을 의미합니다. 이 패키지들은 Flask가 다양한 기능을 수행하는 데 필요한 종속성입니다.

프로젝트 폴더, 가상 환경을 생성하고 Flask를 설치했습니다. 이제 간단한 애플리케이션을 설정할 수 있습니다.

2단계 — 간단한 애플리케이션 만들기

이제 프로그래밍 환경이 설정되었으니, Flask를 사용하기 시작할 것입니다. 이번 단계에서는 Python 파일 내에 작은 Flask 웹 애플리케이션을 만들어, 브라우저에 표시할 HTML 코드를 작성할 것입니다.

flask_app 디렉토리에서 app.py라는 파일을 편집하기 위해 여시기 바랍니다. nano 또는 원하는 텍스트 편집기를 사용하세요:

  1. nano app.py

다음 코드를 app.py 파일 안에 작성하세요:

flask_app/app.py

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return '<h1>Hello, World!</h1>'

파일을 저장하고 닫습니다.

위의 코드 블록에서, 먼저 flask 패키지로부터 Flask 객체를 가져옵니다. 그런 다음 이를 사용하여 app이라는 이름의 Flask 애플리케이션 인스턴스를 생성합니다. 특수 변수 __name__을 전달하는데, 이는 현재 Python 모듈의 이름을 담고 있습니다. 이 이름은 인스턴스가 위치한 곳을 알려줍니다; Flask가 배후에서 몇 가지 경로를 설정하기 때문에 이것이 필요합니다.

app 인스턴스를 생성하면, 이를 사용하여 들어오는 웹 요청을 처리하고 사용자에게 응답을 보낼 수 있습니다. @app.route는 일반적인 Python 함수를 Flask의 view function으로 변환하는 decorator입니다. 이 함수는 함수의 반환 값을 HTTP 응답으로 변환하여 웹 브라우저와 같은 HTTP 클라이언트에 표시합니다. @app.route()'/' 값을 전달하여 이 함수가 메인 URL인 /에 대한 웹 요청에 응답할 것임을 나타냅니다.

hello() 뷰 함수는 HTTP 응답으로 '<h1>Hello, World!</h1>' 문자열을 반환합니다.

이제 app.py라는 Python 파일에 간단한 Flask 애플리케이션이 있습니다. 다음 단계에서는 이 애플리케이션을 실행하여 웹 브라우저에서 hello() 뷰 함수의 결과를 확인할 것입니다.

3단계 — 애플리케이션 실행

Flask 애플리케이션을 포함하는 파일을 생성한 후, Flask 명령줄 인터페이스를 사용하여 개발 서버를 시작하고 이전 단계에서 hello() 뷰 함수의 반환 값으로 작성한 HTML 코드를 브라우저에 렌더링할 것입니다.

먼저, 가상 환경이 활성화된 flask_app 디렉토리에 있는 동안, 다음 명령어를 사용하여 Flask에게 애플리케이션(app.py를 사용하는 경우)을 찾을 위치를 알려줍니다(Windows에서는 export 대신 set을 사용합니다):

  1. export FLASK_APP=app

그런 다음 FLASK_ENV 환경 변수를 사용하여 개발 모드로 애플리케이션을 실행하려는 것을 지정합니다(디버거를 사용하여 오류를 잡을 수 있음):

  1. export FLASK_ENV=development

마지막으로 flask run 명령어를 사용하여 애플리케이션을 실행합니다:

  1. flask run

애플리케이션이 실행되면 다음과 같은 출력이 표시됩니다:

Output
* Serving Flask app "app" (lazy loading) * Environment: development * Debug mode: on * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 296-353-699

앞의 출력에는 다음과 같은 여러 정보가 포함되어 있습니다:

  • 실행 중인 애플리케이션의 이름("app").
  • 애플리케이션이 실행되고 있는 환경(development).
  • Debug mode: on은 Flask 디버거가 실행 중임을 의미합니다. 개발 중에 이는 자세한 오류 메시지를 제공하여 문제 해결을 쉽게 만들기 때문에 유용합니다.
  • 애플리케이션은 로컬 URL http://127.0.0.1:5000/에서 실행되고 있습니다. 127.0.0.1은 사용자 컴퓨터의 localhost를 나타내는 IP이며, :5000은 포트 번호입니다.

브라우저를 열고 URL http://127.0.0.1:5000/을 입력하세요. 응답으로 Hello, World!라는 텍스트가 <h1> 제목으로 표시됩니다. 이는 애플리케이션이 성공적으로 실행되고 있음을 확인해 줍니다.

개발 서버를 중지하려면 CTRL+C를 누르세요.

경고: Flask는 개발 환경에서 애플리케이션을 제공하기 위해 간단한 웹 서버를 사용하며, 이는 Flask 디버거가 오류 포착을 쉽게 하기 위해 실행되고 있음을 의미합니다. 이 개발 서버를 프로덕션 배포에 사용해서는 안 됩니다. 자세한 내용은 Flask 문서의 배포 옵션 페이지를 참조하십시오. Gunicorn을 사용한 Flask 배포 튜토리얼이나 uWSGI를 사용한 튜토리얼을 확인하거나 DigitalOcean App Platform을 사용하여 Gunicorn을 사용하여 Flask 앱을 App Platform에 배포하는 방법 튜토리얼을 따라 Flask 애플리케이션을 배포할 수도 있습니다.

app.py 애플리케이션 개발을 계속하려면 개발 서버를 계속 실행하고 다른 터미널 창을 여십시오. flask_app 디렉토리로 이동하여 가상 환경을 활성화하고 환경 변수 FLASK_ENVFLASK_APP을 설정한 후 다음 단계를 계속하십시오. (이 명령어들은 이 단계의 앞부분에 나열되어 있습니다.)

참고: 새 터미널을 열거나, 개발 서버를 실행하고 있는 터미널을 닫고 다시 실행하려는 경우, 가상 환경을 활성화하고 환경 변수 FLASK_ENVFLASK_APP을 설정하는 것을 기억해야 합니다. 이는 flask run 명령이 제대로 작동하기 위해 필요합니다.

서버는 한 터미널 창에서 한 번만 실행하면 됩니다.

Flask 애플리케이션의 개발 서버가 이미 실행 중인 경우, 동일한 flask run 명령으로 다른 Flask 애플리케이션을 실행할 수 없습니다. 이는 flask run이 기본적으로 포트 번호 5000을 사용하기 때문에, 이 포트가 사용 중이면 다른 애플리케이션을 실행할 수 없어 다음과 같은 오류가 발생합니다:

Output
OSError: [Errno 98] Address already in use

이 문제를 해결하려면, 현재 실행 중인 서버를 CTRL+C로 중지한 후 flask run을 다시 실행하거나, 두 애플리케이션을 동시에 실행하려면 -p 인수에 다른 포트 번호를 전달하면 됩니다. 예를 들어, 포트 5001에서 다른 애플리케이션을 실행하려면 다음 명령을 사용하세요:

  1. flask run -p 5001

이렇게 하면 한 애플리케이션은 http://127.0.0.1:5000/에서, 다른 애플리케이션은 http://127.0.0.1:5001/에서 실행할 수 있습니다.

이제 작은 Flask 웹 애플리케이션을 갖게 되었습니다. 애플리케이션을 실행하고 웹 브라우저에 정보를 표시했습니다. 다음으로, 라우트에 대해 배우고 여러 웹 페이지를 제공하는 방법을 알아보겠습니다.

4단계 – 경로 및 뷰 함수

이 단계에서는 애플리케이션에 몇 가지 경로를 추가하여 요청된 URL에 따라 다른 페이지를 표시합니다. 또한 뷰 함수에 대해 배우고 사용 방법을 알아봅니다.

경로는 사용자가 브라우저에서 웹 애플리케이션을 방문할 때 받는 내용을 결정하는 데 사용할 수 있는 URL입니다. 예를 들어, http://127.0.0.1:5000/은 인덱스 페이지를 표시하는 데 사용될 수 있는 기본 경로입니다. URL http://127.0.0.1:5000/about는 웹 애플리케이션에 대한 일부 정보를 방문자에게 제공하는 데 사용되는 또 다른 경로일 수 있습니다. 마찬가지로, 사용자가 http://127.0.0.1:5000/login에서 애플리케이션에 로그인할 수 있는 경로를 만들 수 있습니다.

현재 Flask 애플리케이션에는 기본 URL(http://127.0.0.1:5000/)을 요청하는 사용자에게 서비스를 제공하는 하나의 경로가 있습니다. 애플리케이션에 새로운 웹 페이지를 추가하는 방법을 시연하기 위해 애플리케이션 파일을 편집하여 http://127.0.0.1:5000/about에서 웹 애플리케이션에 대한 정보를 제공하는 또 다른 경로를 추가합니다.

먼저, app.py 파일을 편집하기 위해 엽니다:

  1. nano app.py

파일 끝에 다음과 같은 강조 표시된 코드를 추가하여 파일을 편집합니다:

flask_app/app.py
from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return '<h1>Hello, World!</h1>'


@app.route('/about/')
def about():
    return '<h3>This is a Flask web application.</h3>'

파일을 저장하고 닫습니다.

새로운 기능인 about()을 추가했습니다. 이 함수는 @app.route() 데코레이터로 장식되어 뷰 함수로 변환되어 http://127.0.0.1:5000/about 엔드포인트에 대한 요청을 처리합니다.

개발 서버가 실행 중인 상태에서 브라우저를 사용하여 다음 URL을 방문하세요:

http://127.0.0.1:5000/about

그러면 <h3> HTML 제목에 This is a Flask web application. 텍스트가 렌더링됩니다.

하나의 뷰 함수에 여러 경로를 사용할 수도 있습니다. 예를 들어, 인덱스 페이지를 //index/ 모두에서 제공할 수 있습니다. 이를 위해 app.py 파일을 편집용으로 엽니다:

  1. nano app.py

hello() 뷰 함수에 다른 데코레이터를 추가하여 파일을 편집합니다:

flask_app/app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
@app.route('/index/')
def hello():
    return '<h1>Hello, World!</h1>'

@app.route('/about/')
def about():
    return '<h3>This is a Flask web application.</h3>'

파일을 저장하고 닫습니다.

이 새로운 데코레이터를 추가한 후에는 http://127.0.0.1:5000/http://127.0.0.1:5000/index 모두에서 인덱스 페이지에 접근할 수 있습니다.

이제 라우트가 무엇인지, 어떻게 뷰 함수를 만들기 위해 사용하는지, 그리고 애플리케이션에 새로운 라우트를 추가하는 방법을 이해했습니다. 다음으로, 동적 라우트를 사용하여 사용자가 애플리케이션의 응답을 제어할 수 있도록 할 것입니다.

5단계 — 동적 라우트

이 단계에서는 동적 라우트를 사용하여 사용자가 애플리케이션과 상호 작용할 수 있도록 할 것입니다. URL을 통해 전달된 단어를 대문자로 변환하는 라우트와 두 숫자를 더하고 결과를 표시하는 라우트를 만들 것입니다.

일반적으로 사용자는 URL을 수동으로 편집하여 웹 애플리케이션과 상호 작용하지 않습니다. 대신, 사용자는 페이지의 요소와 상호 작용하여 사용자의 입력과 동작에 따라 다른 URL로 이동하지만, 이 튜토리얼의 목적상 URL을 편집하여 다른 URL에 따라 애플리케이션이 어떻게 다르게 반응하는지 보여줄 것입니다.

먼저, 편집을 위해 app.py 파일을 여세요:

  1. nano app.py

사용자가 웹 애플리케이션에 무언가를 제출하도록 허용할 경우, 예를 들어 다음 편집에서처럼 URL에 값을 제출하는 경우, 항상 앱이 신뢰할 수 없는 데이터(사용자가 제출한 데이터)를 직접 표시하지 않아야 한다는 점을 염두에 두어야 합니다. 사용자 데이터를 안전하게 표시하려면 Flask와 함께 설치된 markupsafe 패키지에 포함된 escape() 함수를 사용하세요.

app.py를 편집하고 Flask 가져오기 위에 다음 줄을 파일 맨 위에 추가하세요:

flask_app/app.py
from markupsafe import escape
from flask import Flask

# ...

그런 다음, 파일 끝에 다음 라우트를 추가하세요:

flask_app/app.py
# ...

@app.route('/capitalize/<word>/')
def capitalize(word):
    return '<h1>{}</h1>'.format(escape(word.capitalize()))

파일을 저장하고 닫으세요.

이 새로운 경로에는 변수 섹션 <word>가 있습니다. 이는 Flask에게 URL에서 값을 가져와 뷰 함수로 전달하도록 지시합니다. URL 변수 <word>는 키워드 인자를 capitalize() 뷰 함수에 전달합니다. 인자는 URL 변수와 동일한 이름을 가지고 있습니다(word 경우). 이를 통해 URL을 통해 전달된 단어에 접근하고 Python의 capitalize() 메소드를 사용하여 대문자 버전으로 응답할 수 있습니다.

이전에 가져온 escape() 함수를 사용하여 word 문자열을 텍스트로 렌더링합니다. 이는 Cross Site Scripting (XSS) 공격을 피하기 위해 중요합니다. 사용자가 단어 대신 악의적인 JavaScript를 제출하면 escape()는 이를 텍스트로 렌더링하고 브라우저는 이를 실행하지 않아 웹 애플리케이션을 안전하게 유지합니다.

<h1> HTML 제목 내에 대문자 단어를 표시하려면 format() Python 메소드를 사용합니다. 이 메소드에 대한 자세한 내용은 Python 3에서 문자열 포맷터 사용 방법을 참조하세요.

개발 서버를 실행하고 브라우저를 열어 다음 URL을 방문하세요. 강조 표시된 단어를 원하는 단어로 대체할 수 있습니다.

http://127.0.0.1:5000/capitalize/hello
http://127.0.0.1:5000/capitalize/flask
http://127.0.0.1:5000/capitalize/python

페이지의 <h1> 태그에서 URL의 단어가 대문자로 표시되는 것을 볼 수 있습니다.

또한 경로에 여러 변수를 사용할 수도 있습니다. 이를 시연하기 위해 두 개의 양의 정수를 더하고 결과를 표시하는 경로를 추가할 것입니다.

app.py 파일을 편집하기 위해 엽니다:

  1. nano app.py

파일 끝에 다음 경로를 추가하세요:

flask_app/app.py
# ...

@app.route('/add/<int:n1>/<int:n2>/')
def add(n1, n2):
    return '<h1>{}</h1>'.format(n1 + n2)

파일을 저장하고 닫습니다.

이 경로에서는 URL 변수(/add/<int:n1>/<int:n2>/)와 함께 특수 변환기 int를 사용하여 양의 정수만 허용합니다. 기본적으로 URL 변수는 문자열로 간주되어 그렇게 처리됩니다.

개발 서버가 실행 중인 상태에서 브라우저를 열고 다음 URL을 방문하세요:

http://127.0.0.1:5000/add/5/5/

결과는 두 숫자의 합(10이 이 경우입니다)이 될 것입니다.

이제 요청된 URL에 따라 단일 경로에서 다양한 응답을 표시하는 동적 경로를 사용하는 방법을 이해했습니다. 다음으로, 오류가 발생할 경우 Flask 애플리케이션을 디버깅하고 문제를 해결하는 방법을 배우게 될 것입니다.

6단계 — Flask 애플리케이션 디버깅

웹 애플리케이션을 개발할 때 예상한 동작 대신 오류가 표시되는 상황을 자주 마주하게 됩니다. 변수를 잘못 입력하거나 함수를 정의하거나 가져오는 것을 잊어버릴 수 있습니다. 이러한 문제를 쉽게 해결하기 위해 Flask는 개발 모드에서 애플리케이션을 실행할 때 디버거를 제공합니다. 이번 단계에서는 Flask 디버거를 사용하여 애플리케이션의 오류를 수정하는 방법을 배웁니다.

오류 처리 방법을 시연하기 위해 사용자 이름 목록에서 사용자에게 인사하는 경로를 만들어 보겠습니다.

app.py 파일을 편집하기 위해 엽니다:

  1. nano app.py

파일의 끝에 다음 경로를 추가하세요:

flask_app/app.py
# ...

@app.route('/users/<int:user_id>/')
def greet_user(user_id):
    users = ['Bob', 'Jane', 'Adam']
    return '<h2>Hi {}</h2>'.format(users[user_id])

파일을 저장하고 닫습니다.

위의 경로에서 greet_user() 뷰 함수는 user_id URL 변수로부터 user_id 인수를 받습니다. int 변환기를 사용하여 양의 정수를 허용합니다. 함수 내부에는 사용자 이름을 나타내는 세 개의 문자열을 포함하는 users라는 Python 리스트가 있습니다. 뷰 함수는 제공된 user_id에 따라 구성된 문자열을 반환합니다. user_id0이면 응답은 users[0]의 값인 Bob이 첫 번째 항목이므로 <h2> 태그에 Hi Bob이 됩니다.

개발 서버가 실행 중인 상태에서 브라우저를 열고 다음 URL을 방문하세요:

http://127.0.0.1:5000/users/0
http://127.0.0.1:5000/users/1
http://127.0.0.1:5000/users/2

다음과 같은 응답을 받게 됩니다:

Output
Hi Bob Hi Jane Hi Adam

지금까지 잘 작동하지만, 존재하지 않는 사용자에게 인사말을 요청할 때 문제가 발생할 수 있습니다. Flask 디버거가 어떻게 작동하는지 보여주기 위해 다음 URL을 방문하세요:

http://127.0.0.1:5000/users/3

다음과 같은 페이지가 나타납니다:

페이지 상단에는 Python 예외의 이름이 표시되는데, 이는 IndexError로, 리스트 인덱스(3인 경우)가 리스트 범위(리스트에 세 개의 항목만 있으므로 0에서 2까지임)를 벗어났음을 나타냅니다. 디버거에서 이 예외를 발생시킨 코드 줄을 알려주는 트레이스백을 볼 수 있습니다.

트레이스백의 마지막 두 줄은 보통 오류의 원인을 알려줍니다. 당신의 경우 다음과 같은 줄일 수 있습니다:

File "/home/USER/flask_app/app.py", line 28, in greet_user
    return '<h2>Hi {}</h2>'.format(users[user_id])

이는 오류가 app.py 파일 내의 greet_user() 함수에서, 특히 return 줄에서 발생했음을 알려줍니다.

예외를 발생시킨 원래 줄을 알면 코드에서 무엇이 잘못되었는지 파악하고, 이를 고치기 위해 무엇을 해야 할지 결정하는 데 도움이 됩니다.

이 경우 간단한 try...except 절을 사용하여 이 오류를 수정할 수 있습니다. 요청된 URL의 인덱스가 리스트 범위를 벗어나면 사용자에게 404 Not Found 오류가 표시되며, 이는 사용자가 찾고 있는 페이지가 존재하지 않음을 알려주는 HTTP 오류입니다.

app.py 파일을 편집하기 위해 엽니다:

  1. nano app.py

HTTP 404 오류에 응답하려면 Flask의 abort() 함수가 필요합니다. 이 함수는 HTTP 오류 응답을 생성하는 데 사용할 수 있습니다. 파일의 두 번째 줄을 변경하여 이 함수도 가져오십시오:

flask_app/app.py
from markupsafe import escape
from flask import Flask, abort

그런 다음 greet_user() 뷰 함수를 다음과 같이 편집하십시오:

flask_app/app.py
# ...

@app.route('/users/<int:user_id>/')
def greet_user(user_id):
    users = ['Bob', 'Jane', 'Adam']
    try:
        return '<h2>Hi {}</h2>'.format(users[user_id])
    except IndexError:
        abort(404)

try를 사용하여 return 표현식에 대한 오류를 테스트합니다. 오류가 없는 경우, 즉 user_idusers 목록의 인덱스와 일치하는 값을 가지고 있는 경우 애플리케이션은 적절한 인사말로 응답합니다. user_id의 값이 목록의 범위를 벗어나면 IndexError 예외가 발생하고, except를 사용하여 오류를 잡고 abort() Flask 헬퍼 함수를 사용하여 HTTP 404 오류로 응답합니다.

이제 개발 서버가 실행 중인 상태에서 다시 URL을 방문하십시오:

http://127.0.0.1:5000/users/3

이번에는 페이지가 존재하지 않는다는 사실을 사용자에게 알리는 표준 404 오류 페이지가 표시됩니다.

이 튜토리얼이 끝날 때 app.py 파일은 다음과 같습니다:

flask_app/app.py
from markupsafe import escape
from flask import Flask, abort

app = Flask(__name__)


@app.route('/')
@app.route('/index/')
def hello():
    return '<h1>Hello, World!</h1>'


@app.route('/about/')
def about():
    return '<h3>This is a Flask web application.</h3>'

@app.route('/capitalize/<word>/')
def capitalize(word):
    return '<h1>{}</h1>'.format(escape(word.capitalize()))

@app.route('/add/<int:n1>/<int:n2>/')
def add(n1, n2):
    return '<h1>{}</h1>'.format(n1 + n2)

@app.route('/users/<int:user_id>/')
def greet_user(user_id):
    users = ['Bob', 'Jane', 'Adam']
    try:
        return '<h2>Hi {}</h2>'.format(users[user_id])
    except IndexError:
        abort(404)

이제 Flask 디버거를 사용하여 오류를 해결하고 이를 수정하기 위한 적절한 조치를 결정하는 방법에 대한 일반적인 이해를 갖게 되었습니다.

결론

이제 Flask가 무엇인지, 어떻게 설치하는지, 그리고 웹 애플리케이션을 작성하고 개발 서버를 실행하는 방법, 그리고 경로와 뷰 함수를 사용하여 특정 목적을 위한 다른 웹 페이지를 표시하는 방법에 대한 일반적인 이해를 갖게 되었습니다. 또한 동적 경로를 사용하여 사용자가 URL을 통해 웹 애플리케이션과 상호 작용할 수 있게 하는 방법과 디버거를 사용하여 오류를 해결하는 방법도 배웠습니다.

Flask에 대해 더 읽어보고 싶다면 Flask 토픽 페이지를 확인해 보세요.

Source:
https://www.digitalocean.com/community/tutorials/how-to-create-your-first-web-application-using-flask-and-python-3