@Satoh_D no blog

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

【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

Mac OS High Sierra(10.13) で Illustrator CS6を利用する

そろそろYosemiteでの作業が辛くなってきた今日この頃。
思い立ってHigh Sierraにアップデートしてみました。

アップデートも無事完了し、Illustrator CS6を利用しようとしたら
Java SE6ランタイム入れて下さい的なアラートが...

f:id:Satoh_D:20170929151029p:plain

今更古いランタイムは入れたくない...何か方法はないものかと調べていると
どうやらPhotoshop CS6/Illustrator CS6ではJava SE6は利用しておらず、
ディレクトリの存在確認のみ行っているとのこと...

なので、単純に存在確認を行っているディレクトリを作成してあげれば良いらしい。
必要なディレクトリの作成コマンドは次の通り。

$ sudo mkdir -p /System/Library/Java/JavaVirtualMachines/1.6.0.jdk
$ sudo mkdir -p /System/Library/Java/Support/Deploy.bundle

ただ、High Sierraでは(というかEl Capitan以降では)、System Integrity Protection(SIP)の影響で
デフォルトの状態では書き込むことができず、一旦SIPを無効にしないといけません。

  1. OSをリカバリーモードで起動する(cmd+rを押しながらOSを起動)
  2. メニューバーからターミナルを開き、# csrutil disableを入力
    (この時点でSIPが無効化され、/System以下に書き込めるようになる)
  3. mac再起動し、前述の2つのディレクトリを作成する
  4. 再びリカバリーモードで起動する
  5. メニューバーからターミナルを開き、# csrutil enableを入力
    SIPを再び有効化する)
  6. macを再起動する

参考にしたページ

以下の内容を参考にさせていただきました。
ありがとうございますありがとうございます。