2018年12月2日日曜日

【python】PyCharm CEでAWS Toolkits for PyCharmを使う

  • 公開日:2018年12月02日
  • 最終更新日:2018年12月05日

記事概要

PyCharm CEでAWS Toolkits for PyCharmを使ってAws lambdaをlocalで動かす方法を記載した記事です。

記事の対象者

  • Aws lambdaにpythonアプリをdeployしたことがある
  • PyCharmを使ってAws lambdaをアプリを実装したい

記事で学べること

  • PyCharmでAws lambdaの開発環境を構築する

環境

  • macOS Mojavve10.14
  • Python 3.6.3
  • aws lambda
  • Docker Desktop version2.0.0.0-mac81

PyCharmインストール

公式サイトからPyCharm Communityをダウンロード します。もちろん、Professionalでも問題ありません。

PyCharm CEを立ち上げて適当なプロジェクトを作成します。

Pluginインストール

PluginでAWS Toolkitをインストールします。操作手順は以下の通り。

  • Preference選択
  • Plugins選択
  • AWSで検索
  • AWS Toolkitをインストール

AWS Toolkitのインストールが完了したら、次の作業に進みます。

AWS SAM CLI を導入

AWS SAM CLIが必要になります。
公式サイトに記載してある手順を実行します。

AWS SAM CLIの導入ついでに、aws-cliも最新にしておくとさらに良いです。

terminal

// 現在バージョン確認
$ aws --version
aws-cli/1.16.47 Python/3.6.3 Darwin/18.0.0 botocore/1.12.37

// AWS CLI を最新バージョンに更新
pip install awscli --upgrade --user

// 更新後のバージョン確認
$ aws --version
aws-cli/1.16.67 Python/3.6.3 Darwin/18.0.0 botocore/1.12.57

// aws-sam-cli install
pip install aws-sam-cli

公式サイトだとbrewのコマンドが記載されていますが、brewでpythonを導入していない場合、brewだとインストールに失敗しました。
なので、私はpipで導入しました。
自分の環境に合わせてaws-sam-cliを導入してください。

プロジェクト作成

準備が完了したので、プロジェクトを作成しましょう。

NewProjectを選択すると、AWS Serverless Applicationが出現しています。

択しプロジェクト名、SAM Templateから「AWS SAM Hello World」を選んで作成します。

*注意点1.pythonをVirtualenv環境で利用している場合は、Virtualenv Environmentを選択するようにします。公式サイトに詳しい説明が記載されています。

*注意点2.aws-sam-cliをpipで入れた場合は、pathを自分で設定する必要があります。
pathはwhichコマンドで確認できます。

terminal

which sam

/Users/{username}/.pyenv/shims/sam

上記のpathをCIのpathに設定してください。

lambdaをdockerで動かす。

プロジェクト作成すると、デフォルトでlambdaプロジェクトが作成されています。

テスト環境で動かす場合はλマークをクリックします。[Run local app]でlambdaをdocker環境で動かすことができます。

terminal

2018-12-02 22:05:01 Found credentials in environment variables.
2018-12-02 22:05:01 Invoking app.lambda_handler (python3.6)
2018-12-02 22:05:01 Decompressing /var/folders/_k/82kvh_6s4bz0w8j8lhkp674c0000gn/T/2220729341239739084.zip

Fetching lambci/lambda:python3.6 Docker container image...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
2018-12-02 22:17:48 Mounting /private/var/folders/_k/82kvh_6s4bz0w8j8lhkp674c0000gn/T/tmpco54kn1p as /var/task:ro inside runtime container
START RequestId: c4106c2a-a762-4881-90c1-d3abf01a9a96 Version: $LATEST
END RequestId: c4106c2a-a762-4881-90c1-d3abf01a9a96
REPORT RequestId: c4106c2a-a762-4881-90c1-d3abf01a9a96 Duration: 1444 ms Billed Duration: 1500 ms Memory Size: 128 MB Max Memory Used: 26 MB

{"statusCode": 200, "body": "{\"message\": \"hello world\", \"location\": \"61.12.128.21\"}"}


jsonが取得できています。初回はdockerのイメージを取得してくるので、かなり時間がかかります。気長に待ちましょう。

virtualenvに対応

プロジェクト毎に使用パッケージをvirtualenvで隔離します。lambdaAPIは量を作るケースが多いので、virtualenvは必須です。

ターミナルで作業します。

terminal

// プロジェクトルートへ
cd project_root

// 仮想環境(virtualenv)の構築
$ virtualenv --python="`which python`" virtualenv

// virtualenvのactivate
source virtualenv/bin/activate

(virtualenv)$

コマンドをvirtualenv name のようにして名称をつけても問題ありません。

あとは、PyCharm → Preferences → Project Interpreterでaddボタンを押して作った仮想環境を設定すればOKです。

まとめ

AWS Toolkitを使うと、間違いなく生産性は上がります。
一日で設定可能なので、是非利用しましょう。 WEB開発者はもちろん、機械学習開発者にもおすすめです。

次は、testコードと本番deployと機械学習のmodel APIを試してみようと思います。

以上です。

参照サイト


この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2018年11月25日日曜日

【flask】Aws lambda上にflaskをdeployする

  • 公開日:2018年11月25日
  • 最終更新日:2018年11月25日

記事概要

Aws lambdaでflaskアプリをdeployする方法を記載した記事です。

記事の対象者

  • Aws lambdaでflaskをdeployしたい
  • flaskを使った実装を理解している

環境

  • flask
  • python3.6
  • aws lambda
  • zappa
  • doorkeeper 16.1.0

flaskアプリ作成の準備

アプリ構築用のフォルダを作成します。

terminal

mkdir flask-app

続いて仮想環境を構築します。Zappaを使ってbuildとdeployをするので、仮想環境の構築が必須になります。

仮想環境の構築には、virtualenvを使います。virtualenvはPythonの仮想的な環境を作ることができます。
Zappaがpyenvでdeployできるかどうかは確認していません。

virtualenvは、プロジェクトごとにPythonのバージョンを変えたり、必要なパッケージを分けてインストールして動かす事もできます。

terminal

cd flask-app/

$ virtualenv .env
Using base prefix '/Users/{user_name}/.pyenv/versions/3.6.3'
New python executable in /Users/{user_name}/workspace/flask-app/.env/bin/python3.6
Also creating executable in /Users/{user_name}/workspace/flask-app/.env/bin/python
Installing setuptools, pip, wheel...
done.

仮想環境に入ります。

terminal

source .env/bin/activate

(.env) 

terminalのプロンプトの最初が(.env)に変わってれば入れています。

確認のために仮想環境を出ます。

terminal

deactivate

terminalのプロンプトから(.env)が消えていれば、仮想環境を出ています。

flaskアプリの作成

アプリを作成します。requirements.txtを作成します。

terminal

// 仮想環境に入る
source .env/bin/activate

touch requirements.txt

requirements.txtに必要なパッケージを記載します。

flask-app/requirements.txt

flask
zappa

ライブラリをpipでinstallします。

terminal

pip install -r requirements.txt

Hello worldのアプリを作成します。

flask-app/app.py

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/')
def hello_world():
    return jsonify({"message": "Hello World!"})

if __name__ == '__main__':
 app.run()

ローカルで動作することを確認します。
http://localhost:5000/でブラウザにアクセスします。

ブラウザ

{"message":"Hello World!"}

問題ありませんね。

flaskアプリをlambdaにdeploy

ZAPPAを使います。

terminal

$ zappa init

// 全てデフォルト

zappa_settings.jsonが作成されていることを確認します。

terminal

$ ls -l
total 24
-rw-r--r--@ 1 edy  staff  178 11 24 21:57 app.py
-rw-r--r--  1 edy  staff   11 11 24 21:49 requirements.txt
-rw-r--r--  1 edy  staff  240 11 24 23:09 zappa_settings.json

内容を確認すると、色々と設定が記載されているはずです。

deployします。

terminal

zappa deploy dev

deployします。
The role defined for the function cannot be assumed by Lambdaというエラーが表示されて deployに失敗することがありますが、何回か叩くとうまくいくはずです。

URLが返却されたらURLをブラウザで叩いてみてください。

ブラウザ

{"message":"Hello World!"}

上手くいきました。

flaskアプリをlambdaから削除

削除もコマンドで行えます。

terminal

zappa undeploy

これで削除されます。便利ですね。

まとめ

lambdaを使うと低コストでサーバーを利用することができます。
シンプルなAPIを作成するなら、これで十分です。機械学習のAPIとかなら、十分ですね。いやー、凄い時代になりました。

以上です。

参照サイト


この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2018年7月15日日曜日

【Compose and Rails】 新規プロジェクト構築でハマった箇所

  • 公開日:2018年07月15日
  • 最終更新日:2018年07月15日

記事概要

Compose and Railsを使った新規プロジェクトでdocker-composeとrailsを利用したら構築でハマりました。
なので以下にメモ。

環境

  • Engine: 18.03.1-ce
  • Rails5.2
  • ruby2.5.1

公式サイト通りにやったのに、色々と修正が必要になり無駄な時間がかかってしまいました。なので、修正点をまとめておきます。

GemfileとGemfile.lock

公式に通りにやると

terminal

docker-compose run web rails new . --force --database=postgresql

の後に、ローカルに生成されたGemfileとGemfile.lockを、webフォルダの中のGemfileとGemfile.lockと入れ替えることが書いてありません。 コードを読むまで気づきませんでした。なんのためのチュートリアルなのか。

DB作成

公式だとDBの作成が、docker-compose upの起動後になっています。
これだとDBがないので、当たり前ですが、railsが起動しません。

terminal

docker-compose logs

でも理由が出てないので焦りました。ちゃんと書いて欲しいですね。

pidの削除処理

docker-compose startでpumaを起動していると、docker-compose stopを実行しても、PIDファイルが残ってしまうことがあります。

PIDファイルは、長時間動作し続けるプロセス(例えば MySQL デーモンなど)を、自身のPIDをファイルに書いておき、他のプロセスが参照できるようにしているファイルです。

このPIDファイルを削除する処理を記載します。

docker-compose.yml

    command: bash -c 'rm -f tmp/pids/server.pid && bundle exec rails s -p 3001 -b "0.0.0.0"'

上記のようにすることで、docker-compose startのたびにserver.pidが削除されるようになります。

まとめ

公式の通りにやっても、railsの未経験者だと多分すんなりとは立ち上がりません。でも、某キー○の古い情報よりはマシかな。。。という感じです。
結局最後はコードとログを読むしかないという結論でした。AI時代 or 自動化時代はさらに原因究明が大変になるんだろうなあ。あーイヤダイヤダ。
あと、dockerのログは、もう少し詳細にして欲しいですね。

以上です。

PICK UP オススメ書籍

運営サイト


この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2018年5月17日木曜日

【ethereum】開発前の知識整理

  • 公開日:2018年05月17日

記事概要

2018年のGoogle I/Oが残念すぎた(もうスマホは進化しないのでしょうか。新しいライブラリで誤魔化しているだけですね。イノベーションゼロ)ので、コントラクト開発をしようと考えています。ということで、開発に最低限必要なethereumの用語をまとめた記事です。
gethでの環境構築や仮想通貨の技術的な仕組みは知っている前提です。まだメモ書きの段階です。徐々に増やしていきます。

環境

  • ubuntu-17.10
  • ethereum Geth/v1.7.3

DApps

「Decentralized Applications(非中央集権・分散型のアプリケーション)」の略です。

METAMASK

MetaMaskはChromeの拡張機能として使用するウォレットです。ICOに参加する時やDAppsのオンラインゲームで遊ぶ時、DEXの取引所を使う時に必要になります。git Hubでソースが公開されています。

DEX

DEXは分散型取引所のことです。分散型取引所とは、中央管理者がいなくても仮想通貨の取引が可能な取引所の事です。逆に、中央集権型取引所は、日本ではcoincheckやbitFlyer、海外ではpoloniexやbittrexのような中央管理者に仮想通貨を預けて取引を行う取引所のことです。しかし、中央集権型取引所では、秘密鍵の管理を取引所に委任している形になっているため、取引所の内部の人間が顧客の資金を不正に引き出すことが出来てしまう上、秘密鍵を持っている中央管理者へのハッキングリスクがあります。なので、特定の仮想通貨を購入した後は取引所から対応したウォレットに移すことが推奨されています。

ERC20

イーサリアムベースのトークンです。トークンに対する技術的に統一された仕様になります。また、ERC20トークンはERC20トークン対応のウォレットでないと管理できません。
ERC とは「Ethereum RFC (Request for Comment)」の意味で、その20番目だったために「ERC20」と呼ばれているそうです。

Solidityの学習

SolidityはEthereum(イーサリアム)上で動くスマートコントラクト開発の言語です。
まずはローカルに環境を整える前に、CryptoZombiesで実装するとスマートコントラクトの理解ができるでしょう。
また、開発前にMETAMASKをChromeにインストールしましょう。章を進めると、Rewardがもらえます。

Contracts

コントラクトをイーサリアム上にデプロイすると、イミュータブルになる。つまり編集も更新もできなくなる。コントラクトに何か欠陥があっても、それをあとで修正する方法はない。

solidity

msg.value

msg.valueは、コントラクトにどのくらいEtherが送られたかを見る。external payable修飾詞を使う

ECDSA

デジタル署名アルゴリズム。楕円曲線暗号を使った公開鍵のアルゴリズムで、RSAよりも短い鍵長で安全性を担保できる。
openSSLのバージョンを確認する。


$ openssl version
OpenSSL 1.0.2g  1 Mar 2016

まとめ

まだ未完成です。

続きます。

運営サイト


参考記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2018年4月15日日曜日

【Rails】きれいなRubyコードは好きですか? Rubocop. Clean Code

  • 公開日:2018年04月15日
  • 最終更新日:2018年04月21日

記事概要

プロジェクトへRubocopを導入する記事です。

環境

  • centos6.5
  • Rails5.2
  • ruby2.5.1
  • rbenv

Rubocop

Rubocopはコード解析ツールです。
デフォルトでは Ruby Style Guideで示されているガイドラインが適用されます。

実績

Ruby on RailsでもRubocopでコードチェックを実行しています。

Gemfile修正

Gemfileにrubocopを追記します。

{project_folder}/Gemfile

group :development do
  gem 'rubocop', require: false
end

インストールします。

terminal

cd {project_root}
bundle install

Fetching rainbow 3.0.0
Installing rainbow 3.0.0
Fetching parallel 1.12.1
Installing parallel 1.12.1
Fetching parser 2.5.1.0
Installing parser 2.5.1.0
Fetching powerpack 0.1.1
Installing powerpack 0.1.1
Fetching ruby-progressbar 1.9.0
Installing ruby-progressbar 1.9.0
Fetching unicode-display_width 1.3.0
Installing unicode-display_width 1.3.0
Fetching rubocop 0.54.0
Installing rubocop 0.54.0

.rubocop.yml

プロジェクト直下に.rubocop.ymlファイルを作成します。 .rubocop.ymlはRuboCopの挙動をコントロールできます。

terminal

cd ${project_root}

$ touch .rubocop.yml

作成した.rubocop.ymlは空なので、railsの.rubocop.ymlの内容をコピーして貼り付けます。
特別な理由がない限り、基本はRailsと同じ設定にすると良いでしょう。

.rubocop.ymlはRuby2.5.1とRails5.2の環境に合わせます。

{project_folder}/.rubocop.yml

// .ruby-version ファイルからRubyのバージョンは読み込む。
#TargetRubyVersion: 2.5 → 削除

Layout/** → Style/**に置換

Style/SpaceBeforeFirstArg: → Lint/SpaceBeforeFirstArg:

// コメントアウト
#CustomCops/RefuteNot 

// コメントアウト
#Style/EmptyLineAfterMagicComment:
#  Enabled: true

// コメントアウト
#Style/SpaceAroundKeyword
#  Enabled: true

// コメントアウト
#Style/FrozenStringLiteralComment

// コメントアウト
// http://www.rubydoc.info/github/bbatsov/RuboCop/RuboCop/Cop/Lint/BlockAlignment
#EnforcedStyleAlignWith

rubocopコマンドの実行で出力されたエラーを修正します。
シングルクォーテーションをダブルクォーテーションへ変換する必要があるので、以下のコマンドを実行します。

terminal

$ rubocop -a

上記のコマンドを実行すると他のエラーも修正されるので、実行前にgitで状態を保存しておきましょう。

速度改善

上記で設定したrailsの.rubocop.ymlの設定だと、rubocopコマンドの実行に時間がかかるので改善します。
.rubocop.ymlのExcludeの設定を変更します。

{project_folder}/.rubocop.yml

  DisabledByDefault: true
  Exclude:
    - 'tmp/**/*'
    - 'public/**/*'
    - 'vendor/**/*'
    - 'log/**/*'
    - 'actionpack/lib/action_dispatch/journey/parser.rb'

rubocopで検査非対象フォルダの配下を/**/*と設定するのがポイントです。
実行して確認します。

{project_folder}/.rubocop.yml

$ rubocop
warning: parser/current is loading parser/ruby21, which recognizes
warning: 2.1.7-compliant syntax, but you are running 2.1.6.
warning: please see https://github.com/whitequark/parser#compatibility-with-ruby-mri.
Inspecting 48 files
................................................

48 files inspected, no offenses detected

完了です。

まとめ

Railsは開発速度に優れたフレームワークですが、ソースコードがカオスになりやすい欠点があります。プロジェクト立ち上げ時は良いのですが、プロジェクトが長くなればなるほどコードを読むのがきつくなります。Rubocopを導入して、ソースコードの可読性を保つようにしましょう。
長い目で見ると、Rubocopを使った方が開発速度は上がるはずです。

以上です。

PICK UP オススメ書籍

運営サイト


この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2018年2月24日土曜日

【Android】ViewPager

  • 公開日:2018年02月23日

記事概要

java-programming向けの詳細な記事を書く時間が取れないので、ざっくりとこちらに情報を載せます。
ViewPagerアニメーションの学習と研究をしていたので、そのまとめ記事です。

環境

  • Android Studio 3.0.1

概要

ViewPagerはよく使いますが、きちんと内部コードを追って学習したことはほとんどありませんでした。
記事の内容は、この公式ドキュメントがベースです。さらに深掘りしています。

ViewPagerとPageTransformer

ViewPagerのアニメーション方法を変更するには、ViewPager.PageTransformerを使います。ViewPager.PageTransformerはtransformPageが宣言されているInterfaceです。

ViewPager.java

    public interface PageTransformer {
        /**
         * Apply a property transformation to the given page.
         *
         * @param page Apply the transformation to this page
         * @param position Position of page relative to the current front-and-center
         *                 position of the pager. 0 is front and center. 1 is one full
         *                 page position to the right, and -1 is one page position to the left.
         */
        void transformPage(@NonNull View page, float position);
    }

画面切り替え時にtransformPageメソッドが呼び出されます。

PageTransformerで実装した内容を有効にするには、setPageTransformerメソッドを使います。

ViewPager.java

mPager.setPageTransformer(true, new SamplePageTransformer());

上記のように設定すると、実装した具体的なPageTransformerクラスがmPageTransformer変数に設定され、onPageScrolledメソッドで呼び出されます。

ViewPager.java

        if (mPageTransformer != null) {
            final int scrollX = getScrollX();
            final int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = getChildAt(i);
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();

                if (lp.isDecor) continue;
                final float transformPos = (float) (child.getLeft() - scrollX) / getClientWidth();
                mPageTransformer.transformPage(child, transformPos);
            }
        }

PageTransformerクラスの実装

具体的なPageTransformerクラスは、PageTransformerをimplementsして実装します。サンプルとしてZoomOutPageTransformerクラスを実装してみます。

{project_folder}/ZoomOutPageTransformer.java

public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
    private static final float MIN_SCALE = 0.85f;
    private static final float MIN_ALPHA = 0.5f;

    @Override
    public void transformPage(@NonNull View page, float position) {
        int pageWidth = page.getWidth();
        int pageHeight = page.getHeight();

        Log.d("ZoomOutPage", "position :" + position + ", view id : " + page.getId());
        Log.d("ZoomOutPage", "pageWidth :" + pageWidth + ", view id : " + page.getId());
        Log.d("ZoomOutPage", "pageWidth :" + pageHeight + ", view id : " + page.getId());

        if (position  < -1) {
            // 透明にする
            page.setAlpha(0.0f);
        } else if (position <= 1) {
            // -1 < posiiton < 1
            // 多分、徐々に小さくするため
            float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
            // margin 黒枠のところ
            // 縦 top bottomやな
            float vertMargin = pageHeight * (1 - scaleFactor) / 2;
            // 水平 名前が left rightだと
            float horzMargin = pageWidth * (1 - scaleFactor) / 2;
//            if (position < 0) {
//                // 相対的に動かす。これが無いと画像が動かないのでおかしくなるはず。
//                page.setTranslationX(horzMargin - vertMargin / 2);
//            } else {
//                page.setTranslationX(-horzMargin + vertMargin / 2);
//            }

            // Scale the page down (between MIN_SCALE and 1)
            page.setScaleX(scaleFactor);
            page.setScaleY(scaleFactor);

            // Fade the page relative to its size.
            page.setAlpha(MIN_ALPHA +
                    (scaleFactor - MIN_SCALE) /
                            (1 - MIN_SCALE) * (1 - MIN_ALPHA));

        } else {
            // 透明にする
            page.setAlpha(0.0f);
        }


    }
}

positionはページ数でなく、引数のページの相対的な位置です。-1 < x < 1までの範囲の値をとり、0が中央, -1が左, 1が右となります。

vertMarginとhorzMarginはページ切り替え時に、ページ間のviewの距離を詰めるための計算に使っています。setTranslationXでviewの位置をずらすことで、ページ移動のアニメーションをスムーズに見せています。名称がわかりにくいので、topBottomMarginとleftRightMarginで実装した方がわかりやすいと思います。

続いて、DepthPageTransformerを実装してみます。

{project_folder}/DepthPageTransformer.java

public class DepthPageTransformer implements ViewPager.PageTransformer {
    private static final float MIN_SCALE = 0.75f;
    @Override
    public void transformPage(@NonNull View page, float position) {
        int pageWidth = page.getWidth();

        if (position < -1) {
            // 透明にする
            page.setAlpha(0.0f);
        } else if (position <= 0) {
            // [-1 : 0]
            // Use the default slide transition when moving to the left page
            page.setAlpha(1);
            page.setTranslationX(0);
            page.setScaleX(1);
            page.setScaleY(1);

        } else if (position <= 1) {
            // [0 : 1]
            // Fade the page out.
            page.setAlpha(1 - position);

            // Counteract the default slide transition
            page.setTranslationX(pageWidth * -position);

            // Scale the page down (between MIN_SCALE and 1)
            float scaleFactor = MIN_SCALE
                    + (1 - MIN_SCALE) * (1 - Math.abs(position));
            page.setScaleX(scaleFactor);
            page.setScaleY(scaleFactor);
        } else {
            // 透明にする
            page.setAlpha(0.0f);
        }
    }
}

こちらの方が理解しやすですね。左と右で綺麗に処理が分割されています。position <= 0, つまり左側はただスライドするだけです。

page.setAlphaで透過状態を管理しています。徐々に薄くなったり、濃くなったりしています。
ズームも同じで、大から小, 小から大へとviewを変化させています。setScaleX, setScaleYで拡大縮小をしています。

page.setTranslationX(pageWidth * -position);で画面が停止しているように見えるようにしています。

結論

ViewPager.PageTransformerを使うことで、アニメーションを実装できます。色々とやってみようと思います。

PICK UP

運営サイト


参考


この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加
Related Posts Plugin for WordPress, Blogger...