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.htmlresults.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?