관리 메뉴

HAMA 블로그

Flask 웹어플리케이션 구축하기 본문

Flask

Flask 웹어플리케이션 구축하기

[하마] 이승현 (wowlsh93@gmail.com) 2017. 6. 28. 18:10


아래에 훌륭한 Flask 한글메뉴얼이 존재하며, Flask 를 배우기에 최고의 장소입니다.
링크 : http://flask-docs-kr.readthedocs.io/ko/latest/index.html


Applications Flask 웹어플리케이션 구축하기 


PostedJanuary 16, 2014

소개

파이썬 웹 애플리케이션을 구축하는 데는 여러 가지 방법과 관습이 있습니다. 특정 프레임 워크는 작업을 자동화하고 쉽게하기위한 도구(스캐폴딩용)와 함께 출하 되지만 코드세트가 관련 파일 및 폴더에 [논리적으로] 배포되면 거의 모든 솔루션이 패키지/모듈화 응용 프로그램에 의존합니다.

미니멀리스트 웹 애플리케이션 개발 프레임워크 인 Flask에는 자체 청사진(blueprints)이 있습니다.

본 DigitalOcean 기사에서는 응용 프로그램 디렉토리를 만드는 방법과 Flask의 청사진으로 만든 재사용 가능한 구성 요소로 작업하는 방법을 살펴 보겠습니다. 이 조각들로 응용 프로그램 구성 요소의 개발 및 유지보수를 (단순화 되고) 하게 됩니다.

Flask: 미니멀리즘 웹 어플리케이션 개발 프레임워크 

플라스크 (Flask)는 크리티컬 한 것들을 다루는 방식을 강요하는 것을 삼가는 미니멀리즘 (또는 마이크로) 프레임워크입니다. 대신, Flask는 개발자가 원하고 익숙한 도구를 선택해서 사용할 수 있게 합니다. 이를 위해 자체 확장 색인이 있으며  log-ins부터 logging에 이르기까지 모든 것을 처리 할 수 있는 도구는 이미 많이 있습니다.

엄격하게는 "전통적인" 프레임 워크가 아니며 구성 파일에 부분적으로 의존합니다. 구성 파일은 프로젝트를 시작하고 유지할 때 많은 것을 편하고 단순하게 하게 합니다. Flask 는 군더더기가 없습니다.

이 글을 위한 선택요소들 

이전 섹션에서 말했듯이, 플라스크 방식은 당신이 느끼는 가장 편한 도구를 사용하는 것과 관련이 있습니다. 이 글에서는 확장 기능 및 라이브러리 (즉, 데이터베이스 추출 레이어) 측면에서 가장 일반적인 (현명한) 선택 방법을 사용합니다. 이러한 선택은 다음을 포함합니다 :

  • SQLAlchemy (via Flask-SQLAlchemy)

  • WTForms (via Flask-WTF)

Flask-SQLAlchemy

Flask에 SQLAlchemy 지원을 추가합니다. 빠르고 쉽습니다.

승인 된 확장 프로그램입니다.

Author: Armin Ronacher
PyPI Page: Flask-SQLAlchemy
Documentation: Read docs @ packages.python.org
On Github: [mitsuhiko/flask-sqlalchemy](https://github.com/mitsuhiko/flask-sqlalchemy)

Flask-WTF

Flask-WTF는 WTForm과의 간단한 통합을 제공합니다. 이 통합에는보다 강력한 보안을 위해 선택적 CSRF 처리가 포함됩니다.

승인 된 확장 프로그램입니다.

Author: Anthony Ford (created by Dan Jacob)
PyPI Page: Flask-WTF
Documentation: Read docs @ packages.python.org
On Github: [ajford/flask-wtf](https://github.com/mitsuhiko/flask-wtf)


Flask 를 위한 시스템 준비

Flask 응용 프로그램을 구성하기 전에 시스템을 준비하고 Flask 배포본을 다운로드(및 설치)합시다.

참고 : 우리는 최신 버전의 사용 가능한 운영 체제 (예 : Ubuntu 13)를 실행하는 새로 인스턴스화 된 드롭 릿에 대해 작업 할 것입니다. 새로운 시스템에서도 모든 것을 테스트하는 것이 좋습니다. 특히 고객에게 적극적으로 서비스하는 경우 더욱 그렇습니다.

OS 준비

안정적인 서버를 갖추려면 모든 관련 도구와 라이브러리를 최신 상태로 유지 관리해야합니다.
사용 가능한 최신 버전의 기본 응용 프로그램을 확보하려면 업데이트부터 시작합시다.
데비안 기반 시스템 (즉, 우분투, 데비안)에서 다음을 실행하십시오 :

aptitude    update
aptitude -y upgrade

필요한 개발 도구를 얻으려면 다음 명령을 사용하여 "build-essential"을 설치하십시오.

aptitude install -y build-essential python-dev python2.7-dev

Setting up Python, pip and virtualenv

Ubuntu와 Debian에는 기본적으로 사용할 수있는 Python 인터프리터의 최신 버전이 있습니다. 제한된 수의 패키지만 설치하면됩니다.

  • python-dev (development tools)

  • pip (to manage packages)

  • virtualenv (to create isolated, virtual

참고 : 여기에 제공된 지침은 간략하게 유지됩니다. 자세한 내용은 일반적인 Python 도구 : virtualenv 사용, Pip와 함께 설치 및 패키지 관리의 pip 및 virtualenv에 대한 방법 문서를 참조하십시오.

pip

pip는 우리가 필요로하는 응용 프로그램 패키지를 설치하는 데 도움이되는 패키지 관리자입니다.
pip를 설치하려면 다음 명령을 실행하십시오.

curl https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py | python -
curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python -
export PATH="/usr/local/bin:$PATH"

virtualenv

모든 의존성과 함께 자체 환경 내에서 Python 응용 프로그램을 포함하는 것이 가장 좋습니다. 환경은 모든 것이 상주하는 격리 된 위치 (디렉토리)로 (간단한 용어로) 가장 잘 설명 될 수 있습니다. 이를 위해 virtualenv라는 도구가 사용됩니다.

pip를 사용하여 virtualenv를 설치하려면 다음을 실행하십시오.

sudo pip install virtualenv


어플리케이션 디렉토리 구성 


LargeApp 같은 명백한 이름을 응용 프로그램 폴더로 사용합니다. 내부에서 우리는 애플리케이션 패키지 (예 : 앱)와 테스트 환경 (개발) 서버를 실행하기위한 "run.py"와 같은 다른 가상 환경 (예 : env)을 유지하려고합니다. 

아래 예제처럼 제공되는 구조는 매우 확장 성이 뛰어나며 Flask 및 기타 라이브러리에서 제공하는 유용한 도구를 모두 사용할 수 있도록 제작되었습니다. 우리는 모든 것을 모든 것을 구성함으로써 단계적으로 설명합니다.

목표 예제 구조 :

~/LargeApp
    |-- run.py
    |-- config.py
    |__ /env             # Virtual Environment
    |__ /app             # Our Application Module
         |-- __init__.py
         |-- /module_one
             |-- __init__.py
             |-- controllers.py
             |-- models.py                
         |__ /templates
             |__ /module_one
                 |-- hello.html
         |__ /static
         |__ ..
         |__ .
    |__ ..
    |__ .

어플리케이션 폴더 생성

우리가 필요로하는 메인 폴더를 만드는 것으로 시작합시다.작업을 수행하려면 다음 명령을 연속적으로 실행하십시오.

mkdir ~/LargeApp
mkdir ~/LargeApp/app
mkdir ~/LargeApp/app/templates
mkdir ~/LargeApp/app/static    

현재구조는 이렇습니다.

~/LargeApp
    |__ /app             # Our Application Module
         |__ /templates
         |__ /static

가상환경 생성하기

가상 환경을 사용하면 많은 이점을 얻을 수 있습니다. 각 응용 프로그램에 대해 새 가상 환경을 사용하는 것이 좋습니다. 응용 프로그램 내부에 virtualenv 폴더를 유지하면 순서대로 정리할 수있는 좋은 방법입니다.

다음을 실행하여 pip가 설치된 새 가상 환경을 만듭니다.

cd         ~/LargeApp
virtualenv env

어플리케이션 파일들 생성하기

이 단계에서는 모듈 및 청사진으로 작업하기 전에 기본 응용 프로그램 파일을 구성합니다.
기본 응용 프로그램 파일을 만들려면 다음을 실행하십시오.

touch ~/LargeApp/run.py
touch ~/LargeApp/config.py
touch ~/LargeApp/app/__init__.py

현재까지의 구조는 이렇습니다.

~/LargeApp
    |-- run.py
    |-- config.py
    |__ /env             # Virtual Environment
    |__ /app             # Our Application Module
         |-- __init__.py
         |__ /templates
         |__ /static

플라스크 인스톨링 과 어플리케이션 디펜던시 

일단 우리가 모든 것을 갖추었다면, Flask로 개발을 시작하기 위해 pip를 사용하여 다운로드하고 설치합시다. Flask를 가상 환경 env에 설치하려면 다음을 실행하십시오.

cd ~/LargeApp
env/bin/pip install flask
env/bin/pip install flask-sqlalchemy
env/bin/pip install flask-wtf

참고 : 여기에서는 가상 환경을 활성화하지 않고 Flask를 다운로드하고 설치합니다. 그러나 우리는 가상환경 자체에서의 pip 을 사용하고 있기 때문에 동일한 작업을 수행합니다. 활성화 된 환경에서 작업하는 경우 대신 그냥 pip를 사용할 수 있습니다.

이제 청사진을 사용하여 모듈화 된 더 큰 Flask 응용 프로그램을 만들 준비가되었습니다.


모듈 & 블루프린트(컴포넌트)와 작업하기 

모듈 기본

이 시점에서 우리는 응용 프로그램 구조를 설정하고 종속성을 다운로드하여 준비했습니다.우리의 목표는 논리적으로 그룹화 할 수있는 모든 관련 모듈을 모듈화 (즉, Flask의 청사진으로 재사용 가능한 구성 요소 생성)하는 것입니다.

이에 대한 예는 인증 시스템이 될 수 있습니다. 모든 뷰, 컨트롤러, 모델 및 헬퍼를 한 곳에서 사용하는 것은 재사용을 허용하는 방식으로 설정되므로 이러한 종류의 구조화는 생산성을 높이는 동시에 응용 프로그램을 유지 관리하는 좋은 방법입니다.

대상 예제 모듈 (구성 요소) 구조 (inside / app) :

# Our module example here is called *mod_auth*
# You can name them as you like as long as conventions are followed

/mod_auth
    |-- __init__.py
    |-- controllers.py
    |-- models.py
    |-- ..
    |-- .

모듈 템플릿

to-the-Max로 모듈화를 지원하기 위해 위의 규칙을 따르고 템플릿 파일을 포함 할 새 폴더 (모듈과 관련되거나 같음)를 포함하도록 "templates"폴더를 구성합니다.

대상 예제 템플릿 디렉토리 구조 (LargeApp 내부) :

/templates
    |-- 404.html
    |__ /auth
         |-- signin.html
         |-- signup.html
         |-- forgot.html
         |-- ..
         |-- .


어플리케이션 만들기 

이 섹션에서는 이전 단계를 계속 진행하고 응용 프로그램의 실제 코딩부터 시작하여 첫 번째 모듈화 된 구성 요소 (청사진 사용)로 이동합니다. 모든 인증 관련 절차 (예 : 서명, 서명 등)를 처리하는 mod_auth).

“run.py” 을 편집합니다.

nano ~/LargeApp/run.py

다음을 추가하세요

# Run a test server.
from app import app
app.run(host='0.0.0.0', port=8080, debug=True)


“config.py” 를 편집합니다.

nano ~/LargeApp/config.py

다음 내용을 추가하세요.

# Statement for enabling the development environment
DEBUG = True

# Define the application directory
import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))  

# Define the database - we are working with
# SQLite for this example
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR, 'app.db')
DATABASE_CONNECT_OPTIONS = {}

# Application threads. A common general assumption is
# using 2 per available processor cores - to handle
# incoming requests using one and performing background
# operations using the other.
THREADS_PER_PAGE = 2

# Enable protection agains *Cross-site Request Forgery (CSRF)*
CSRF_ENABLED     = True

# Use a secure, unique and absolutely secret key for
# signing the data. 
CSRF_SESSION_KEY = "secret"

# Secret key for signing cookies
SECRET_KEY = "secret"


모듈과 컴포넌트 만들기

이 섹션은이 기사의 핵심을 정의하는 첫 번째 주요 단계입니다. 여기서는 Flask의 청사진을 사용하여 모듈 (즉, 구성 요소)을 만드는 방법을 살펴 보겠습니다.

이것에 대해 훌륭한 점은 제공되는 이식성과 코드의 재사용 성을 유지 보수 용이성과 함께 제공한다는 것입니다. 앞으로 남겨질 때 상황을 되돌아보고 이해하는 것이 어려울 때가 많기 때문에 앞으로 감사 할 것입니다.

Step 1: Structuring The Module

앞서 살펴본 것처럼 mod_auth의 첫 번째 모듈 (mod_auth) 디렉토리와 파일을 만들어 작업을 시작하십시오.

# Create the module directory inside the *app* module
mkdir ~/LargeApp/app/mod_auth

# Create where module's templates will reside
mkdir ~/LargeApp/app/templates/auth

# Create __init__.py to set the directory as a Python module
touch ~/LargeApp/app/mod_auth/__init__.py

# Create module's controllers and models etc.
touch ~/LargeApp/app/mod_auth/controllers.py
touch ~/LargeApp/app/mod_auth/models.py
touch ~/LargeApp/app/mod_auth/forms.py

# Create module's templates
touch ~/LargeApp/app/templates/auth/signin.html

# Create a HTTP 404 Error page
touch ~/LargeApp/app/templates/404.html

이 작업이 끝나면 폴더 구조가 다음과 같이 표시됩니다.

~/LargeApp
    |-- run.py
    |-- config.py
    |__ /env             # Virtual Environment
    |__ /app             # Our Application Module
         |-- __init__.py
         |-- /mod_auth   # Our first module, mod_auth
             |-- __init__.py
             |-- controllers.py
             |-- models.py
             |-- forms.py
         |__ /templates
             |-- 404.html
             |__ /auth
                 |-- signin.html
         |__ /static

Step 2: Define The Module Data Model(s)

nano ~/LargeApp/app/mod_auth/models.py

아래에 설명을 추가하십시오 - 모범적 인 내용 :

# Import the database object (db) from the main application module
# We will define this inside /app/__init__.py in the next sections.
from app import db

# Define a base model for other database tables to inherit
class Base(db.Model):

    __abstract__  = True

    id            = db.Column(db.Integer, primary_key=True)
    date_created  = db.Column(db.DateTime,  default=db.func.current_timestamp())
    date_modified = db.Column(db.DateTime,  default=db.func.current_timestamp(),
                                           onupdate=db.func.current_timestamp())

# Define a User model
class User(Base):

    __tablename__ = 'auth_user'

    # User Name
    name    = db.Column(db.String(128),  nullable=False)

    # Identification Data: email & password
    email    = db.Column(db.String(128),  nullable=False,
                                            unique=True)
    password = db.Column(db.String(192),  nullable=False)

    # Authorisation Data: role & status
    role     = db.Column(db.SmallInteger, nullable=False)
    status   = db.Column(db.SmallInteger, nullable=False)

    # New instance instantiation procedure
    def __init__(self, name, email, password):

        self.name     = name
        self.email    = email
        self.password = password

    def __repr__(self):
        return '<User %r>' % (self.name)                        

Step 3: Define Module Forms

nano ~/LargeApp/app/mod_auth/forms.py

아래에 설명을 추가하십시오

# Import Form and RecaptchaField (optional)
from flask.ext.wtf import Form # , RecaptchaField

# Import Form elements such as TextField and BooleanField (optional)
from wtforms import TextField, PasswordField # BooleanField

# Import Form validators
from wtforms.validators import Required, Email, EqualTo


# Define the login form (WTForms)

class LoginForm(Form):
    email    = TextField('Email Address', [Email(),
                Required(message='Forgot your email address?')])
    password = PasswordField('Password', [
                Required(message='Must provide a password. ;-)')])

Step 4: Define Application Controllers (Views)

nano ~/LargeApp/app/mod_auth/controllers.py

아래에 설명을 추가하십시오

# Import flask dependencies
from flask import Blueprint, request, render_template, \
                  flash, g, session, redirect, url_for

# Import password / encryption helper tools
from werkzeug import check_password_hash, generate_password_hash

# Import the database object from the main app module
from app import db

# Import module forms
from app.mod_auth.forms import LoginForm

# Import module models (i.e. User)
from app.mod_auth.models import User

# Define the blueprint: 'auth', set its url prefix: app.url/auth
mod_auth = Blueprint('auth', __name__, url_prefix='/auth')

# Set the route and accepted methods
@mod_auth.route('/signin/', methods=['GET', 'POST'])
def signin():

    # If sign in form is submitted
    form = LoginForm(request.form)

    # Verify the sign in form
    if form.validate_on_submit():

        user = User.query.filter_by(email=form.email.data).first()

        if user and check_password_hash(user.password, form.password.data):

            session['user_id'] = user.id

            flash('Welcome %s' % user.name)

            return redirect(url_for('auth.home'))

        flash('Wrong email or password', 'error-message')

    return render_template("auth/signin.html", form=form)

Step 5: Set Up The Application in “app/init.py”

nano ~/LargeApp/app/__init__.py

아래에 설명을 추가하십시오

# Import flask and template operators
from flask import Flask, render_template

# Import SQLAlchemy
from flask.ext.sqlalchemy import SQLAlchemy

# Define the WSGI application object
app = Flask(__name__)

# Configurations
app.config.from_object('config')

# Define the database object which is imported
# by modules and controllers
db = SQLAlchemy(app)

# Sample HTTP error handling
@app.errorhandler(404)
def not_found(error):
    return render_template('404.html'), 404

# Import a module / component using its blueprint handler variable (mod_auth)
from app.mod_auth.controllers import mod_auth as auth_module

# Register blueprint(s)
app.register_blueprint(auth_module)
# app.register_blueprint(xyz_module)
# ..

# Build the database:
# This will create the database file using SQLAlchemy
db.create_all()

Step 6: Create The Templates

nano ~/LargeApp/app/templates/auth/signin.html

아래에 설명을 추가하십시오

{% macro render_field(field, placeholder=None) %}
{% if field.errors %}
<div>
{% elif field.flags.error %}
<div>
{% else %}
<div>
{% endif %}
    {% set css_class = 'form-control ' + kwargs.pop('class', '') %}
    {{ field(class=css_class, placeholder=placeholder, **kwargs) }}
</div>
{% endmacro %}

<div>
  <div>
    <legend>Sign in</legend>
    {% with errors = get_flashed_messages(category_filter=["error"]) %}
    {% if errors %}
    <div>
    {% for error in errors %}
    {{ error }}<br>
    {% endfor %}
    </div>
    {% endif %}
    {% endwith %}

    {% if form.errors %}
    <div>
    {% for field, error in form.errors.items() %}
    {% for e in error %}
    {{ e }}<br>
    {% endfor %}
    {% endfor %}
    </div>
    {% endif %}
    <form method="POST" action="." accept-charset="UTF-8" role="form">
      {{ form.csrf_token }}
      {{ render_field(form.email, placeholder="Your Email Address",
                                  autofocus="") }}
      {{ render_field(form.password, placeholder="Password") }}
      <div>
      <label>
        <input type="checkbox" name="remember" value="1"> Remember Me
      </label>
      <a role="button" href="">Forgot your password?</a><span class="clearfix"></span>
      </div>
      <button type="submit" name="submit">Sign in</button>
    </form>  
  </div>
</div>

참고 :이 템플릿 파일은 데모 용으로 작성된 매우 간단하고 불완전한 예제입니다. Jinja2 문서를 읽고 기본 파일을 사용하여 웹 사이트 서식 파일을 작성하는 것이 좋습니다.

Step 7: See Your Module In Action

첫 번째 모듈을 만든 후에 모든 것을 실제로 볼 시간입니다.
run.py를 사용하여 개발 서버를 실행합니다.

cd ~/LargeApp
env/bin/python run.py

그러면 포트 8080에서 호스팅되는 개발 (즉, 테스트) 서버가 시작됩니다.
다음 URL로 이동하여 모듈을 방문하십시오.

http://[your droplet's IP]/auth/signin

로그인 할 수는 없지만 테스트를 위한 데이터를 입력하거나 유효성 검사기를 테스트하여 실제로 로그인 할 수 있습니다.


Comments