序章


PythonWebアプリケーションを構造化するための多くの方法と規則があります。 特定のフレームワークには、タスク(および頭痛の種)を自動化および緩和するためのツール(スキャフォールディング用)が付属していますが、コードベースが関連するファイルやフォルダーに[論理的に]分散されるため、ほとんどすべてのソリューションはアプリケーションのパッケージ化/モジュール化に依存しています。

ミニマリストのWebアプリケーション開発フレームワークFlaskには、独自のblueprintsがあります。

このDigitalOceanの記事では、アプリケーションディレクトリを作成し、Flaskのブループリントで作成された再利用可能なコンポーネントで動作するようにアプリケーションディレクトリを構造化する方法を説明します。 これらの要素により、アプリケーションコンポーネントの保守と開発が大幅に可能になります(そして簡素化されます)。

用語集


1. フラスコ:ミニマリストアプリケーション開発フレームワーク


2. この記事での私たちの選択


3. フラスコ用のシステムの準備


  1. オペレーティングシステムを準備する
  2. Python、pip、virtualenvのセットアップ

4. アプリケーションディレクトリの構造化


  1. アプリケーションフォルダの作成
  2. 仮想環境の作成
  3. アプリケーションファイルの作成
  4. Flaskのインストール

5. モジュールとブループリント(コンポーネント)の操作


  1. モジュールの基本
  2. モジュールテンプレート

6. アプリケーションの作成( run.py init .pyなど)


  1. nanoを使用してrun.pyを編集します
  2. nanoを使用してconfig.pyを編集します

7. モジュール/コンポーネントの作成


  1. ステップ1:モジュールの構造化
  2. ステップ2:モジュールデータモデルを定義する
  3. ステップ3:モジュールフォームを定義する
  4. ステップ4:アプリケーションコントローラー(ビュー)を定義する
  5. 手順5:「app / init.py」でアプリケーションを設定する
  6. ステップ6:テンプレートを作成する
  7. ステップ7:モジュールの動作を確認する

フラスコ:ミニマリストアプリケーション開発フレームワーク


Flaskは、重要なものの処理方法を課すことを控えるミニマリスト(またはマイクロ)フレームワークです。 代わりに、Flaskを使用すると、開発者は必要に応じて使い慣れたツールを使用できます。 この目的のために、独自の拡張インデックスが付属しており、ログインからロギングまでのほとんどすべてを処理するためのツールがすでに多数存在します。

これは厳密に「従来の」フレームワークではなく、構成ファイルに部分的に依存しています。これにより、開始とチェックの維持に関して、率直に言って多くのことが容易になります。

この記事での私たちの選択


前のセクションで終わったばかりなので、Flask-物事を行う方法には、最も使いやすいツールを使用することが含まれます。 私たちの記事では、拡張機能とライブラリ(つまり、 データベース抽出レイヤー)。 これらの選択には以下が含まれます。

  • SQLAlchemy(Flask経由-SQLAlchemy)

  • WTForms(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)

フラスコ-WTF


Flask-WTFは、WTFormsとの簡単な統合を提供します。 この統合には、セキュリティを強化するためのオプションの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ディストリビューションをダウンロード(およびインストール)しましょう。

注:利用可能なオペレーティングシステムの最新バージョン(つまり、 Ubuntu 13)。 特にクライアントに積極的にサービスを提供している場合は、新しいシステムでもすべてをテストすることを強くお勧めします。

オペレーティングシステムを準備する


安定したサーバーを使用するには、関連するすべてのツールとライブラリを最新の状態に保ち、適切に保守する必要があります。

デフォルトアプリケーションの利用可能な最新バージョンを確実に入手するために、更新から始めましょう。

Debianベースのシステムに対して以下を実行します(すなわち Ubuntu、Debian):

aptitude    update
aptitude -y upgrade

必要な開発ツールを入手するには、次のコマンドを使用して「build-essential」をインストールします。

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

Python、pip、virtualenvのセットアップ


UbuntuとDebianでは、Pythonインタープリターの最新バージョン(使用可能)がデフォルトで付属しています。 インストールする追加パッケージの数は限られています。

  • python-dev (開発ツール)

  • pip (パッケージを管理するため)

  • virtualenv (分離された仮想を作成するため

注:ここに記載されている手順は簡潔にしています。 詳細については、pipとvirtualenvに関するハウツー記事をご覧ください:一般的なPythonツール: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の模範的な名前を使用します。 内部には、仮想環境(つまり、 env)アプリケーションパッケージと一緒に(すなわち app)と、テスト(開発)サーバーを実行するための「 run.py 」や、Flask構成を維持するための「config.py」などの他のファイル。

以下に例として示されている構造は非常に拡張性が高く、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とアプリケーションの依存関係のインストール


すべてが整ったら、Flaskで開発を開始するために、pipを使用してダウンロードしてインストールしましょう。

以下を実行して、仮想環境env内にFlaskをインストールします。

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

注:ここでは、仮想環境をアクティブ化せずにを使用してFlaskをダウンロードしてインストールしています。 ただし、環境自体からのピップを使用していることを考えると、同じタスクを実行します。 アクティブ化された環境で作業している場合は、代わりにpipを使用できます。

以上です! これで、ブループリントを使用してモジュール化された、より大きなFlaskアプリケーションを構築する準備が整いました。

モジュールとブループリント(コンポーネント)の操作


モジュールの基本


この時点で、アプリケーション構造がセットアップされ、その依存関係がダウンロードされて準備が整いました。

私たちの目標はモジュール化することです(すなわち Flaskの青写真を使用して再利用可能なコンポーネントを作成します)論理的にグループ化できるすべての関連モジュール。

この例として、認証システムがあります。 すべてのビュー、コントローラー、モデル、およびヘルパーを1つの場所に配置し、再利用を可能にするように設定することで、この種の構造化は、生産性を向上させながらアプリケーションを維持するための優れた方法になります。

ターゲットのサンプルモジュール(コンポーネント)構造(内部 /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
    |-- ..
    |-- .

モジュールテンプレート


モジュール化を最大限にサポートするために、上記の規則に従って「templates」フォルダーを構成し、モジュールと同じまたは類似の関連する名前の新しいフォルダーを含めて、そのテンプレートファイルを格納します。

ターゲットサンプルテンプレートのディレクトリ構造(内部 LargeApp):

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

アプリケーションの作成


このセクションでは、前の手順を続行し、アプリケーションの実際のコーディングから始めて、最初のモジュール化されたコンポーネントの作成に移ります(ブループリントを使用)。 mod_auth すべての認証関連の手順を処理するため(すなわち サインイン、サインアップなど)。

nanoを使用して「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)

保存してCTRL+Xを使用して終了し、Yで確定します。

nanoを使用して「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"

保存してCTRL+Xを使用して終了し、Yで確定します。

モジュール/コンポーネントの作成


このセクションは、この記事のコアを定義する最初の主要なステップです。 ここでは、Flaskのブループリントを使用してモジュールを作成する方法を説明します(つまり、 コンポーネント)。

これについて素晴らしいのは、コードの提供された移植性再利用性が、メンテナンスの容易さと組み合わされていることです。戻ってきて、残されたものを理解するために。

ステップ1:モジュールの構造化


始めたように、最初のモジュールを作成しましょう(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

ステップ2:モジュールデータモデルを定義する


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)                        

保存してCTRL+Xを使用して終了し、Yで確定します。

ステップ3:モジュールフォームを定義する


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. ;-)')])

保存してCTRL+Xを使用して終了し、Yで確定します。

ステップ4:アプリケーションコントローラー(ビュー)を定義する


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)

保存して終了します CTRL+X で確認します Y.

手順5:「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()

保存してCTRL+Xを使用して終了し、Yで確定します。

ステップ6:テンプレートを作成する


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>

保存してCTRL+Xを使用して終了し、Yで確定します。

注:このテンプレートファイルは、デモンストレーション目的で作成されたばかりの非常に単純で不完全な例です。 Jinja2ドキュメントを読み、ベースファイルを使用してWebサイトのテンプレートを作成することを強くお勧めします。

ステップ7:モジュールの動作を確認する


最初のモジュールを作成したら、すべての動作を確認します。

を使用して開発サーバーを実行します run.py:

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

これにより、開発が開始されます(つまり、 テスト)ポート8080でホストされているサーバー。

次のURLにアクセスして、モジュールにアクセスします。

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

ログインすることはできませんが、いくつかの模範的なデータを入力するか、そのバリデーターをテストすることで、実際の動作を確認できます。

投稿者: https ://twitter.com/ostezer ”> OS Tezer