5 Fri
[HEAD FIRST PYTHON] 5강 웹앱 만들기
Flask 설치
pip install flask
가상환경에서 설치
이 때 flask가 의존성을 갖는 네 개의 모듈이 함께 설치된다.
Successfully installed Jinja2-2.11.3 MarkupSafe-1.1.1 Werkzeug-1.0.1 click-7.1.2 flask-1.1.2 itsdangerous-1.1.0
Flask
마이크로 웹 프레임워크
태스크에 필요한 최소한의 기술집합을 제공
경쟁자인 장고는 모든 기능을 포함한다
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello() -> str:
return "Hello world from Flask!"
app.run()
1 : f가 소문자인 flask는 모듈명이며 F가 대문자인 Flask는 클래스명이다.
import flask.Flask도 가능하지만 가독성을 위해 from - import 를 사용한다.
2 : Flask 클래스의 인스턴트를 만들고 이를 app이라고 정의했다. Flask 클래스는 객체를 만들 때 현재 버전의 __name__을 인자로 받아야 한다.
__name__은 현재 활성 모듈의 이름
__name__과 같은 변수는 두 개의 언더스코어가 양옆에 존재하여 더블 언더스코어라고 한다. 이는 줄여서 던더 네임, dunder name 이라고도 한다.
4 : 장식자를 사용했다.
장식자, decorator는 기존 코드에 새로운 동작을 추가한다. 이 때 함수의 코드를 바꾸지 않고도 동작을 조절할 수 있다. 함수뿐 아니라 클래스에도 장식자를 적용할 수 있다. 주로 함수에 적용하기 때문에 함수 장식자라고 많이 한다.
@ 기호로 시작한다.
이 때 URL '/' 는 다음 행에 있는 함수와 이어진다. URL 요청이 들어왔을 때 어떤 함수를 호출할 것인지 조정한다. 이 때 장식자는 함수에서 결과를 반환할 때 까지 대기하다가 결과가 반환되면 대기 중인 웹 브라우저로 결과를 반환한다.
'/' URL로 들어오는 모든 서버 요청에는 함수를 반환하며 그 외에 URL로 들어오는 요청에는 404
Resource not found
에러 메시지를 보낸다.
8 : 웹앱 실행 요청

프로그램이 실행되면 플라스크 웹 서버가 실행되며 플라스크의 테스트 웹 주소(127.0.0.1)와 프로토콜 포트 번호(5000)로 서비스 웹 요청을 기다린다는 메시지가 나타난다.

웹에 기능 추가하기
4장에서 만들었던 vsearch 모듈을 이용해 기능을 추가한다.
from flask import Flask
from vsearch import search4letters
app = Flask(__name__)
@app.route('/')
def hello() -> str:
return "Hello world from Flask!"
@app.route('/search4')
def do_search() -> str:
return str(search4letters('lif, the universe, and everything', 'eiru'))
app.run()
이 때
app.run(debug=True)
로 설정하게 되면, 코드를 고칠 때마다 재실행 하지 않아도 웹 서버가 알아서 리로드 된다.

127.0.0.1
은 localhost라 알려진 인터넷의 루프백 주소를 의미한다. 이 주소는 IP와 관계없이 내 컴퓨터를 지목할 수 있는 방법이다.5000
은 웹 서버가 실행 중인 프로토콜 포트 번호를 의미한다. 보통 웹서버는80
이라는 포트 번호에서 실행되며, 웹앱을 개발하는 동안에는80
번을 쓰지 않는 것이 관례이다.8080
번 포트가 개발 시 자주 사용하는 포트 중 하나이다. 플라스크는 테스트 프로토콜 포트로5000
번을 사용한다.
템플릿 엔진
HTML을 코드에 작성하는 것은 작동하는 데 문제가 없지만 확장성은 떨어진다. 웹앱이 더 커질수록 관리하기가 어려워지며 이를 웹 디자이너에게 넘겨서 개선하기도 어렵다
따라서 템플릿 엔진을 사용한다
프로그래머가 웹 페이지 같은 텍스트 기반 데이터 결과물에 객체 지향 개념을 적용할 수 있도록 한다.
다음과 같은 최상위 템플릿을 작성한다. 이후 여러 하위 템플릿이 추가된다.
<!doctype html>
<html>
<head>
<title>{{ the_title }}</title>
<link rel="stylesheet" href="static/hf.css" />
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
5 : css는 html의 스타일을 결정하는 텍스트로 여기서는 hf.css를 사용할 것으로 명시하고 있다.
8, 10 : block body 과 endblock 를 사용하므로 템플릿을 확장할 것을 명시하고 있다.
다음은 기본 베이스 템플릿
bast.html
의 block body와 endblock 사이에 들어갈 수 있는entry.html
과results.html
이다.
{% extends 'base.html' %}
{% block body %}
<h2>{{ the_title }}</h2>
<p>You submitted the following data:</p>
<table>
<tr><td>Phrase:</td><td>{{ the_phrase }}</td></tr>
<tr><td>Letters:</td><td>{{ the_letters }}</td></tr>
</table>
<p>When "{{the_phrase }}" is search for "{{ the_letters }}", the following
results are returned:</p>
<h3>{{ the_results }}</h3>
{% endblock %}
{% extends 'base.html' %}
{% block body %}
<h2>{{ the_title }}</h2>
<form method='POST' action='/search4'>
<table>
<p>Use this form to submit a search request:</p>
<tr><td>Phrase:</td><td><input name='phrase' type='TEXT' width='60'></td></tr>
<tr><td>Letters:</td><td><input name='letters' type='TEXT' value='aeiou'></td></tr>
</table>
<p>When you're ready, click this button:</p>
<p><input value='Do it!' type='SUBMIT'></p>
</form>
{% endblock %}

HTTP 상태 코드
GET 메서드
브라우저가 웹 서버로 리소스를 요청하는 메서드
POST 메서드
브라우저가 HTTP를 통해 서버로 데이터를 보내는 메서드
Render_Template
다른 템플릿으로 동적 변수를 전달할 떄 사용할 수 있다
마지막에
,
를 명시해줘야한다.
return render_template('results.html', the_phrase = phrase, the_letters =letters, the_title=title, the_results=results,)
Redirect
redirect를 이용해서 URL('/') 을 URL('/entry')로 redirect한 모습
@app.route('/')
def hello() -> '302':
return redirect('/entry')
이는 아래와 같이 바꿔서 쓸 수 있다.
@app.route('/')
@app.route('/search4', methods=['POST'])
최종 코드
vsearch4web.py
from flask import Flask, render_template, request, redirect
from vsearch import search4letters
app = Flask(__name__)
@app.route('/')
@app.route('/search4', methods=['POST'])
def do_search() -> str:
phrase = request.form['phrase']
letters = request.form['letters']
title = 'Here are your results'
results = str(search4letters(phrase, letters))
return render_template('results.html', the_phrase = phrase, the_letters =letters, the_title=title, the_results=results,)
@app.route('/entry')
def entry_page() -> 'html':
return render_template('entry.html', the_title='Welcome to search4letters on the web!')
app.run(debug=True)
app.run()
배포시에는
app.run()
을 실행할 경우 웹앱 실행이 거절된다. 이는 파이썬애니웨어에서 지원하지 않기 때문.그러나 디버깅 및 개발시에는
app.run()
을 사용하게 된다. 따라서 다음과 같이 코드를 작성하면 개발시에만 실행하게 된다.
if __name__ = '__main__':
app.run(debug=True)
Last updated
Was this helpful?