@Satoh_D no blog

大分にUターンしたので記念に。調べたこととか作ったこととか食べたこととか

【AWS】RDS(MySQL)で発生したIPブロックを解消する

今やっている案件で、急にRDSへの接続ができず以下のエラーを吐くようになりました。

Host 'xxx.xxx.xxx.xxx' is blocked because of many connection errors;
〜以下続く

調べたところ、MySQLのシステム変数であるmax_connect_errorsで設定した値以上接続失敗をするとIPブロックされてしまうようです。
解消方法は以下の通り。

  1. IPブロックされていないホストからMySQLに接続
$ mysql -u [username] -p -h [hostname]
  1. MySQLにログイン後、以下コマンドを実施
mysql> FLUSH HOSTS;
Query OK, 0 rows affected (0.01 sec)

これで解消できます。 解消したのはいいのですが、何故起きたのかを突き止めないとですね...(ヽ´ω`)

3ステップでしっかり学ぶ MySQL入門 [改訂2版]

3ステップでしっかり学ぶ MySQL入門 [改訂2版]

【Python】Pythonを使ってGoogle Spread Sheetを操作してみる

社内でやっているIoT案件にて、PythonからGoogle Spreadsheetにデータを送信する必要があったので試してみた。

環境

手順

1. Google Spread SheetのAPIキーを取得する

Google API コンソールのページに遷移する

「アプリケーションを登録するプロジェクトの選択」から任意のプロジェクトを選択する
プロジェクトが存在しない場合、「プロジェクトの作成」をクリックし、プロジェクトを作成する。

プロジェクトを作成した場合、認証用の鍵がダウンロードされる。
ダウンロードした認証用の鍵は「client_secret.json」というファイル名にリネームし、実行ファイルと同じ場所に置いておく。

2. Google API用のPythonパッケージをダウンロードする

pipを利用してgoogle-api-python-client, oauth2clientをダウンロードする
サンプルコードgoogle-api-python-clientだけでいいっぽいけど、うちの環境ではoauth2clientも必要だった。

$ pip install --upgrade google-api-python-client
$ pip install --upgrade oauth2client

3. サンプルコードを写経する

サンプルコードのコードをエディタに書き、動かしてみる。

from __future__ import print_function
import httplib2
import os

from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage

try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/sheets.googleapis.com-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/spreadsheets.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Google Sheets API Python Quickstart'


def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   'sheets.googleapis.com-python-quickstart.json')

    store = Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatibility with Python 2.6
            credentials = tools.run(flow, store)
        print('Storing credentials to ' + credential_path)
    return credentials

def main():
    """Shows basic usage of the Sheets API.

    Creates a Sheets API service object and prints the names and majors of
    students in a sample spreadsheet:
    https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
    """
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    discoveryUrl = ('https://sheets.googleapis.com/$discovery/rest?'
                    'version=v4')
    service = discovery.build('sheets', 'v4', http=http,
                              discoveryServiceUrl=discoveryUrl)

    spreadsheetId = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms'
    rangeName = 'Class Data!A2:E'
    result = service.spreadsheets().values().get(
        spreadsheetId=spreadsheetId, range=rangeName).execute()
    values = result.get('values', [])

    if not values:
        print('No data found.')
    else:
        print('Name, Major:')
        for row in values:
            # Print columns A and E, which correspond to indices 0 and 4.
            print('%s, %s' % (row[0], row[4]))


if __name__ == '__main__':
    main()

ソースの流れを見る感じ、get_credentials()でOAuthの認証情報を取得し、ローカルにjson形式で保存。
json形式で保存することで、2回目以降の認証をスキップできるみたい。

credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
discoveryUrl = ('https://sheets.googleapis.com/$discovery/rest?'
                'version=v4')
service = discovery.build('sheets', 'v4', http=http,
                          discoveryServiceUrl=discoveryUrl)

このあたりでGoogle SpreadsheetへアクセスするためのServiceを作成している。 Spreadsheetの内容を取得するのは以下コード部分。

spreadsheetId = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms'
rangeName = 'Class Data!A2:E'
result = service.spreadsheets().values().get(
    spreadsheetId=spreadsheetId, range=rangeName).execute()
values = result.get('values', [])

spreadsheetIdでアクセス先のSpreadsheetを設定し、rangeNameで取得する位置を設定している。
データの取得自体はservice.spreadsheets().values().get()を利用する。

ちなみにデータの書き込みは上記サンプルコードのうち、以下の部分を書き換える。

# SCOPES = 'https://www.googleapis.com/auth/spreadsheets.readonly'
SCOPES = 'https://www.googleapis.com/auth/spreadsheets'

# result = service.spreadsheets().values().get(...).execure()
ValueInputOption = 'USER_ENTERED'
body = {
  'values': [[1, 2, 3]]
}
# データの書き込みは service.spreadsheets().values().update() を利用する
# データの追記は service.spreadsheets().values().append() を利用する
# valueInputOption='USER_ENTERED`オプションを利用すると、「書式設定」が自動になり、通常入力と同じ状態になる
#   → 入力時に書式を自動判別してくれる
result = service.spreadsheets().values().update(
    spreadsheetId=spreadsheetId, range=rangeName,
    valueInputOption=ValueInputOption, body=body).execute()

参考サイト

入門 Python 3

入門 Python 3

MacにRaspberry Piの仮想環境を作成する

概要

  • Virtualboxを利用してRaspbeery Pi(stretch)の環境を作成した際のメモ

環境

前提

作成手順

1. 仮想環境を作成する

  • [新規アイコン]をクリック
  • 各種設定内容を入力する
    • 名前: 任意の名称を入力
    • タイプ: Linux
    • バージョン: Debian(64-bit)
    • モリーサイズ: 1024MB
    • ハードディスク: 仮想ハードディスクを作成する
    • ファイルの場所: デフォルト
    • ファイルサイズ: 8.00GB
    • ハードディスクのファイルタイプ: VDI(Virtualbox Disk Image)
    • 物理ハードディスクにあるストレージ: 可変サイズ

2. 作成した仮想環境にOSを設定する

  • 1.で作成した仮想環境を選択し、[設定]をクリック
  • [システム] > [プロセッサー] > プロセッサー数を2に変更
  • [ストレージ] > [コントローラー: IDE] > [空]を選択
    • ディスクアイコンをクリックし、予めダウンロードしていたIOSファイルを選択
  • 右下の[OK]を選択

3. OSのセットアップを行う

  • 2.で設定した仮想環境を選択し、[起動]をクリック
  • OSのインストール画面が表示される
    • [Graphical Install]を選択し、[Enter]を押す
  • キーボードの選択画面が表示される
    • [Japanese]を選択し、[Enter]
  • パーティションの設定画面が表示される
    • パーティションを分ける必要はないため、[Guided - use entrie disk]を選択し、[Enter]
    • [SCSI3(0,0,0) (sda) - 2.1 GB HARDDISK]を選択し、[Enter]
    • [All files in one partition(recommended for new users]を選択し、[Enter]
    • [Finish partitioning and write changes to disk]を選択し、[Enter]
    • [Yes]を選択し、[Enter]
  • ブートローダーの設定画面が表示される
    • [Yes]を選択し、[Enter]
    • [dev/sda]を選択し、[Enter]
  • インストール完了画面が表示される
    • 画面右下[Continue]を[Enter]
    • Raspbianのデスクトップ画面が表示されればインストール完了

これでMac上にRaspberry Piの環境が作成できました。 最低限の設定しかしていないので、あとは案件やら要件に合わせてセットアップをどうぞ。

【Python】 Pyenvを利用してPython3.5.xをインストールしようとしたらエラーが出る件

pyenvを利用してPython3.5.3を入れようとしたら次のようなエラーががが。

$ CFLAGS="-I$(brew --prefix openssl)/include" LDFLAGS="-L$(brew --prefix openssl)/lib" pyenv install -v 3.5.3

BUILD FAILED (OS X 10.13.1 using python-build 20160602)

Inspect or clean up the working tree at /var/folders/4m/cg10dgps2_j5f6_0pqpbcfc40000gn/T/python-build.20180918160654.71021
Results logged to /var/folders/4m/cg10dgps2_j5f6_0pqpbcfc40000gn/T/python-build.20180918160654.71021.log

Last 10 log lines:
  File "/private/var/folders/4m/cg10dgps2_j5f6_0pqpbcfc40000gn/T/python-build.20180918160654.71021/Python-3.5.3/Lib/ensurepip/__main__.py", line 4, in <module>
    ensurepip._main()
  File "/private/var/folders/4m/cg10dgps2_j5f6_0pqpbcfc40000gn/T/python-build.20180918160654.71021/Python-3.5.3/Lib/ensurepip/__init__.py", line 209, in _main
    default_pip=args.default_pip,
  File "/private/var/folders/4m/cg10dgps2_j5f6_0pqpbcfc40000gn/T/python-build.20180918160654.71021/Python-3.5.3/Lib/ensurepip/__init__.py", line 116, in bootstrap
    _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
  File "/private/var/folders/4m/cg10dgps2_j5f6_0pqpbcfc40000gn/T/python-build.20180918160654.71021/Python-3.5.3/Lib/ensurepip/__init__.py", line 40, in _run_pip
    import pip
zipimport.ZipImportError: can't decompress data; zlib not available

解決方法

どうやら「Xcode command line tools」というものをインストールしないといけないらしい。

$ xcode-select --install
xcode-select: note: install requested for command line developer tools

このコマンドを打つとプロンプトが起動してGUIからインストールすることになる。
インストール完了後、改めてpythonをインストールする

$ CFLAGS="-I$(brew --prefix openssl)/include" LDFLAGS="-L$(brew --prefix openssl)/lib" pyenv install -v 3.5.3

3.5.3がインストールされていることを確認する

$ pyenv versions
* system
  3.5.3
  3.6.0

参考URL

入門 Python 3

入門 Python 3

【Python】MacOS High SierraでPyenvを利用してPythonをインストールしようとしたら失敗した

Pyenvを利用してPythonをインストールしようとしたらOpenSSL入れてる?的なエラーメッセージが出てインストールできなかった件。
High Sierraにする前にPyenvを利用した際は出なかったので、恐らくOSアップデートしたタイミングで何かおかしくなったっぽい...?

$ pyenv install 3.5.3
Downloading Python-3.5.3.tar.xz...
-> https://www.python.org/ftp/python/3.5.3/Python-3.5.3.tar.xz
Installing Python-3.5.3...
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems


BUILD FAILED (OS X 10.13.1 using python-build 20160602)

Inspect or clean up the working tree at /var/folders/4m/cg10dgps2_j5f6_0pqpbcfc40000gn/T/python-build.20180918154126.40711
Results logged to /var/folders/4m/cg10dgps2_j5f6_0pqpbcfc40000gn/T/python-build.20180918154126.40711.log

Last 10 log lines:
if test "xupgrade" != "xno"  ; then \
        case upgrade in \
            upgrade) ensurepip="--upgrade" ;; \
            install|*) ensurepip="" ;; \
        esac; \
         ./python.exe -E -m ensurepip \
            $ensurepip --root=/ ; \
    fi
Ignoring ensurepip failure: pip 9.0.1 requires SSL/TLS

インストール環境

解決方法

エラーメッセージのURLを確認するところ、コンパイラのパスを渡していけないみたい。
以下コマンドを利用して改めてインストールを実施してみる

$ CFLAGS="-I$(brew --prefix openssl)/include" \
> LDFLAGS="-L$(brew --prefix openssl)/lib" \
> pyenv install -v 3.5.3

参考URL

入門 Python 3

入門 Python 3

【Ruby】CarrierWaveを利用してS3に5GB以上のファイルをアップロードする

3日ほどさんざんハマっててようやく解決したのでメモ。

構築中のシステムでzipファイルをCarrierWaveを利用してS3に自動アップロードする処理があるが、特定のファイルだけどうしてもアップロードできずにハマってた。
ソースやデータを見てもおかしなことろがなく、「何がまずいのか...」と思っていたが、S3のドキュメントを見ていたら、

1 回のオペレーションでオブジェクトをアップロードする – 1 回の PUT オペレーションでアップロードできるオブジェクトの最大サイズは 5 GB です。

docs.aws.amazon.com

これだあああああああああ
S3では5GB以上のファイルは1度にアップロードできず、「マルチパートアップロードAPI」を利用しないといけないとのこと。
今回アップロードしようとしていたzipの容量が5.3GBだったので、これに引っかかっていた模様。
以下の記事を参考に、CarrierWaveの設定を追加

stackoverflow.com

CarrierWave.configure do |config|
  ...

  config.fog_attributes = { :multipart_chunk_size => 524288000 } # => 500MBずつアップロード

  ...
end

これで5GB以上のファイルも無事にアップロードできました。

Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門 (CodeZine BOOKS)

Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門 (CodeZine BOOKS)

【Tomcat7】DataSourceが見つからずにjava.lang.ClassNotFoundExceptionが発生する

Tomcatインストール後、DB接続情報を書いて接続確認した時にハマったのでメモ。

環境

今回は以下のような環境で実施してました

手順

%CATALINA_HOME%/webapps/Hoge にアプリケーション設置後、
%CATALINA_HOME%/conf/Catalina/localhost/Hoge.xml 作成し、以下のように接続情報を記載

<Context path="/Hoge" reloadable="true"
        docBase="/usr/share/tomcat/webapps/Hoge">

    <Resource name="MySQL_JDBC" auth="Container"
            factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
            type="javax.sql.DataSource"
            username="xxxx"
            password="xxxxxxxx"
            url="jdbc:mysql://127.0.0.1:xxxx/HogeDB"
            maxWait="3000" />
</Context>

%CATALINA_HOME%/webapps/Hoge/WEB-INF/web.xml に以下追記

<resource-ref>
    <res-ref-name>MySQL_JDBC</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
</resource-ref>

ブラウザでページを確認すると、次のようなエラーがががが。

Dec 06, 2017 5:16:58 PM org.apache.catalina.core.NamingContextListener addResource
WARNING: Failed to register in JMX: javax.naming.NamingException: Could not create resource factory instance [Root exception is java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory]

解決方法

StackOverFlowの記事によると、tomcat-dbcp-7.0.30.jar が破損しているとのこと。

%CATALINA_HOME%/lib/を確認してみると、そもそもtomcat-dbcp-7.0.30.jarが無かった...。
記事にある通りにjarファイルをダウンロードしてみる

$ wget -O /usr/share/java/tomcat-dbcp-7.0.30.jar http://search.maven.org/remotecontent?filepath=org/apache/tomcat/tomcat-dbcp 
/7.0.30/tomcat-dbcp-7.0.30.jar

再度ブラウザで確認してみると、エラー無く確認できた。
Tomcat初めて触るからわからないことだらけで大変だ...(白目

参考サイト

詳解 Tomcat

詳解 Tomcat