Hope is a Dream. Dream is a Hope.

非公開ブログは再開しました。

2018年度版AWS CodeStarでFlask環境構築方法とハマリポイント

1. Python3の利用

(追記) 原因が分かった.CodeBuildの環境がpython2.7(デフォルト)になっている. CodeBuildの「プロジェクトの編集」にて,使用するイメージを変更できる!

=> デフォルトでは仮想環境にてPython3がインストールされている => しかし, cloud9ではaliasでpython=python27と設定されているため,python27が起動される => (対策) unalias python を実行することで,python=venv/bin/python3が起動される => (補足) デプロイされるサーバーにてaliasが設定されているかは分からないが,念のためインストールスクリプトにもunaliasを追加しておく

file : install_dependenceies

# Install Python 
virtualenvenvironment
source environment/bin/activate
pip install -r requirements.txt
pip install supervisor
python setup.py install

下に変更

# Install Python 
unalias python       // (追加) いらないかも
virtualenv -p python3.6 environment // (ヴァージョンの指定を追加) いらないかも
source environment/bin/activate
pip install -r requirements.txt
pip install supervisor
python setup.py install

デプロイ先でpytho2になっている可能性があるので,テストにヴァージョンを追加しておく

import json
import pytest

def test_python_version():
    import sys
    ver = sys.version_info;
    assert ver.major == 3

2. Flask + Python3の利用

2.1 プロジェクト名の変更

/scripts/supervisord.conf

[program:flaskapplication]
- command = /home/ec2-user/python-flask-service/environment/bin/python /home/ec2-user/python-flask-service/helloworld/application.py
+ command = /home/ec2-user/python-flask-service/environment/bin/python /home/ec2-user/python-flask-service/yourapp/application.py

buildspec.yml

version: 0.2

phases:
  pre_build:
    commands:
      # Discover and run unit tests. For more information, see <https://docs.pytest.org/en/latest/goodpractices.html>
      - python setup.py pytest

artifacts:
  type: zip
  files:
    - 'template.yml'
    - 'scripts/**/*'
-   - 'helloworld/**/*.py'
+   - 'yourapp/**/*.py'
    - 'appspec.yml'
    - 'requirements.txt'
    - 'setup.py'

setup.py

from setuptools import setup, find_packages

setup(
-   name='helloworld',
+   name='yourapp',
    packages=find_packages(),
    include_package_data=True,
    install_requires=[
        'flask',
    ],
    setup_requires=[
        'pytest-runner',
    ],
    tests_require=[
        'pytest',
    ],
)

3. Flask + Blueプリントで, APIとFrontを分ける

yourapplication/ app.py /backend/ init.py reset_api.py /frontend/ init.py views.py /static/ /templates/

いまさらながら Flask についてまとめる 〜Blueprint〜 - 適当おじさんの適当ブログ Modular Applications with Blueprints — Flask 1.0.2 documentation

  1. [CodeStar] でFlask(EC2)を立ち上げる
  2. [CodeBuild] プロジェクト設定を編集して,python3.6系ランタイムに変更
  3. [Cloud9] にてアプリの名前を変更

3.1 setup.py

from setuptools import setup, find_packages

setup(
-   name='helloworld',
+   name='hebel',
    packages=find_packages(),
    include_package_data=True,
    install_requires=[
        'flask',
    ],
    setup_requires=[
        'pytest-runner',
    ],
    tests_require=[
        'pytest',
    ],
)

3.2 buildspec.yml

version: 0.2

phases:
  pre_build:
    commands:
      # Discover and run unit tests. For more information, see <https://docs.pytest.org/en/latest/goodpractices.html>
      - python setup.py pytest

artifacts:
  type: zip
  files:
    - 'template.yml'
    - 'scripts/**/*'
-   - 'helloworld/**/*.py'
+   - 'hebel/**/*.py'
    - 'appspec.yml'
    - 'requirements.txt'
    - 'setup.py'

3.3 ./helloworld/ => ./hebel/

import json
import pytest
from hebel.application import application

@pytest.fixture
def client():
    return application.test_client()

def test_response(client):
    result = client.get()
    response_body = json.loads(result.get_data())
    assert result.status_code == 200
    assert result.headers['Content-Type'] == 'application/json'
    assert response_body['Output'] == 'Hello World'

3.4 tests/test_application.py

import json
import pytest
from helloworld.application import application

@pytest.fixture
def client():
    return application.test_client()

def test_response(client):
    result = client.get()
    response_body = json.loads(result.get_data())
    assert result.status_code == 200
    assert result.headers['Content-Type'] == 'application/json'
    assert response_body['Output'] == 'Hello World'

    ```



4. .gitignoreを追加
デフォルトでは.gitignoreが無いので. gitに色々コミットされていやなので.
.egg, .venv, ....

curl https://www.gitignore.io/api/python > .gitignore


4. 仮想環境の構築

cd flask-blueprint virtualenv -p python3 .venv source .venv/bin/activate python -V #3.6系であることを確認する

もし2.7系であれば unalias python

$ which python ~/environment/flask-blueprint/.venv/bin/python

$ python -V Python 3.6.5

5. ひとまずテスト

tests/test_applicaiton.py

import json import pytest from hebel.application import application

@pytest.fixture def client(): return application.test_client()

def test_response(client): result = client.get() response_body = json.loads(result.get_data()) assert result.status_code == 200 assert result.headers['Content-Type'] == 'application/json' assert response_body['Output'] == 'Hello World'

念のために追加しておく

def test_python_version(): import sys ver = sys.version_info; assert ver.major == 3

テストの実行

python setup.py pytest

~省略~

=========================================================================================================================== test session starts =========================================================================================================================== platform linux -- Python 3.6.5, pytest-3.8.1, py-1.6.0, pluggy-0.7.1 rootdir: /home/ec2-user/environment/flask-blueprint, inifile: collected 1 item

tests/test_application.py . [100%]

======================================================================================================================== 1 passed in 0.11 seconds =========================================================================================================================





# Cloud9でのpython alias

もし, pythonが2.7の場合にはaliasがされているかもしれないので,念のためにaliasを消しておく

unalias python

Cloud9でVirtualenvを使ってPython3が使えない

nohara:~/environment/tmp $ virtualenv -p 3.6 venv36 The path 3.6 (from --python=3.6) does not exist nohara:~/environment/tmp $ virtualenv -p python3.6 venv36 Already using interpreter /usr/bin/python3.6 Using base prefix '/usr' New python executable in /home/ec2-user/environment/tmp/venv36/bin/python3.6 Not overwriting existing python script /home/ec2-user/environment/tmp/venv36/bin/python (you must use /home/ec2-user/environment/tmp/venv36/bin/python3.6) Installing setuptools, pip, wheel...done. nohara:~/environment/tmp $ which python /usr/bin/python nohara:~/environment/tmp $ python -V Python 2.7.14 nohara:~/environment/tmp $ source venv36/bin/activate (venv36) nohara:~/environment/tmp $ vhich python bash: vhich: command not found (venv36) nohara:~/environment/tmp $ which python
~/environment/tmp/venv36/bin/python (venv36) nohara:~/environment/tmp $ python -V Python 3.6.5 (venv36) nohara:~/environment/tmp $




## おまけ

git-commit.sh
debug用

cd /home/ec2-user/environment/python3-test git config --global user.name "T.Nohara" git config --global user.email nohara@example.com git add . git commit -m "auto commit" git push

1. Create a Python virtual environment for your Django project. This virtual
        $ unalias python
        $ virtualenv -p python3 .venv

2. Activate the virtual environment:

        $ source .venv/bin/activate

3. Install Python dependencies for this project:

        $ pip install -r requirements.txt

4. Install the sample application code into your virtual environment:

        $ python setup.py install

5. Start the Flask development server:

        $ python helloworld/application.py --port 8000

C#でバックグラウンド処理をするためのテンプレート

C#でバックグラウンド処理をするためのテンプレート

時間のかかる処理をバックグラウンドで実行するには?[2.0のみ、C#、VB] - @IT

バックグラウンド処理を途中でキャンセルするには?[2.0のみ、C#、VB] - @IT

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    /// <summary>
    /// ユーザ定義のBackgroundWorkerクラス
    /// 処理中のデータを保持させたりしたい
    /// </summary>
    public class MyBackgroundWorker : BackgroundWorker
    {
        public int id;
        public int count;
        public MyBackgroundWorker(int id)
        {
            this.id = id;
            this.count = 0;
        }

    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();


            // 増産方法
            List<BackgroundWorker> workers = new List<BackgroundWorker>();
            int workers_number = 10;
            for (int i = 0; i < workers_number; i++)
            {
                BackgroundWorker new_worker = new MyBackgroundWorker(i);
                new_worker.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
                new_worker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
                new_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
                workers.Add(new_worker);
            }

        }


        /// <summary>
        /// ワーカーの起動
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync(100); // 引数を渡している
        }

        /// <summary>
        /// キャンセル操作
        /// </summary>
        private void button_Cancel_Click(object sender, EventArgs e)
        {
            backgroundWorker1.CancelAsync();
        }

        /// <summary>
        /// バックグラウンド処理
        /// </summary>
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {

            int bgWorkerArg = (int)e.Argument;

            BackgroundWorker worker = (BackgroundWorker)sender;

            for (int i = 0; i < bgWorkerArg; i++)
            {
                if (backgroundWorker1.CancellationPending)
                {
                    e.Cancel = true;
                    return;

                }

                System.Threading.Thread.Sleep(100);

                int percentage = (int)(100.0 * i / (bgWorkerArg - 1));
                worker.ReportProgress(percentage);

            }
            e.Result = "All Collect!";
        }

        /// <summary>
        /// 定期監視
        /// </summary>
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }

        /// <summary>
        /// 完了イベント
        /// </summary>
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            BackgroundWorker worker = (BackgroundWorker)sender;

            if (e.Cancelled)
            {
                this.textBox1.Text = "キャンセルされました";
            }
            else
            {
                this.textBox1.Text = e.Result.ToString();
            }

            progressBar1.Value = 0;

        }


    }
}

awsでflaskを立てる方法3つ

2018年9月19日現在, AWSにてFlask(python web フレームワーク)を立ち上げる方法は3つある

いつもどれがなにか忘れるので備忘録を残す

    1. CodeStar - EC2
    1. CodeStar - ElasticBeansTalk
    1. Cloud9

1. CodeStar - EC2

1.1 セキュリティグループにてポート開放 EC2のコンソールを立ち上げて、「Cloud9」のインバウンドのHTTPの80番とHTTPSの443番ポートを開放 これで開発用環境のサーバーに外からWEBサーバーにアクセスことが出来る

1.2 サーバーの起動 READMEにしたがって、virtualenvを使ってflaskのみインストールされたpython環境をつくる flaskrun.pyを起動する

1.3 Previewの設定 「Preview>Configure Preview URL...」にて、Cloud9 EC2のパブリックIPを指定する

その他 CodeStarで環境を構築した場合は2つのアクセスポイントが存在する

    1. 本番サーバ(EC2)のアクセスポイント
    1. 開発サーバー(Cloud9 EC2)のアクセスポイント

双方ともセキュリティグループにてポートを開放する必要がある.

2. CodeStar - ElasticBeansTalk

(↑と同じ)

3. Cloud9

3.1 セキュリティグループにてポート開放 EC2のコンソールを立ち上げて、インバウンドのHTTPの80番とHTTPSの443番ポートを開放 これで外からWEBサーバーにアクセスことが出来る

f:id:hope_is_dream:20180919214337p:plain

3.2 WEBサーバーを立ち上げる デフォルトでApacheWebサーバーがインストールされている。

sudo service httpd restart            # webサーバーの起動
curl localhost              # ウェブページの確認

しかしApacheではFlaskはそのままは使えない。