Google Cloud Functions (Python) から Cloud Firestore の データを 読み出す – Cloud SDK を使う方法 と Firebase Admin SDK を使う方法 –

Cloud Firestore を Python で作成した Cloud Functions から利用するには 活用する SDK 別に以下の2つがあります。 Cloud SDK を使う方法 Firebase Admin SDK を使う方法 両者に特に メリット / デメリット があるわけではなさそうですが、少し紛らわしい部分もありますので、 簡単なサンプルコード を用いて整理していきたいと思います。 前提 本記事は以下を前提としてすすめていきます。 Cloud SDK インストール 済み Firebase Admin SDK インストール 済み Cloud Firestore データベース作成 済み これらについては、以下の記事も参考にしてください。 Cloud Firestore の内容を Read する データ 登録済みの Cloud Firestore のデータを Python で作成した Cloud Functions で読み出してみます。 Read する Cloud Firestore データ の内容 今回読み出してみる Firestore のデータを GCP Console からみてみます。名前 フィールド のみを持つ シンプル な データ 構造となっています。 ちなみに Firebase Console からみてみても、同じ データ を確認することができます。 ベース となる 関数の準備 次に、 ベース となる 最小構成の Python 関数を作成していきます。 この関数を以下の コマンド で Functions Framework を用いて ローカル 環境で実行してみます。 http://localhost:5000 にアクセスしてみると、以下の結果が表示されます。 Python Client for Google Cloud Firestore の インストール Cloud SDK を用いる方法を進める前に … Read more

Google Secret Manager に 辞書型データを格納し、Cloud Functions から アクセスする方法

こちらの記事 で Google Secret Manager に パスワード や API キー といった 「他者に知られたくない」あるいは 「公開したくない」 情報を格納する方法を紹介しました。 今回はより実践的な管理方法として 辞書型 の データ を Secret に登録して Python で 作成した Cloud Functions 関数 で 意図通り 辞書型 として扱う方法について紹介していきます。  前提 本記事を読みすすめるにあたっては、以下を実施済みであることが前提となっています。 Python 開発環境の設定 サービスアカウント作成済み Secret Manager API の有効化 Secret Manager への アクセス ロール 付与済み これらが未実施の場合は 以下の 関連記事 を参照してください。 Secret の作成 それでは早速 辞書型の データ を Secret Manager に登録していきます。本記事では 以下のような 構造をもつ Dict 型 の データ を登録してみます。 以下の リンク を クリック して GCP コンソール から Secret Manager を表示し、「 シークレットを作成 」を クリック します。 https://console.cloud.google.com/security/secret-manager シークレット の詳細として 以下を設定します。 名前: 任意の名称(ここでは、 my-dict-secret ) シークレットの値: 上述した 辞書型 の データ 他の項目は デフォルト のままで 「シークレット を作成」 をクリックし、 Secret の作成を完了させます。 Secret 作成後 Secret の値を確認してみます。 特に フォーマット が変換されることもなく、そのままの テキスト … Read more

Google Secret Manager で パスワードや API キー などの秘匿情報を管理し Cloud Funcitons から参照する方法

ソフトウェアデベロッパー にとって、 パスワード、 APIキー、 認証情報 といった秘匿情報の管理は頭を悩ませる問題の一つといえます。 開発環境と本番環境では別の情報を用いる必要があることが殆どだと思いますし、 このような秘匿情報を誤って公開 Repository にコミットしてしまうと、 様々な被害を被る危険性があります。 一方で、秘匿情報をローカルで管理すると、 紛失のリスクや、バージョン管理面での不都合などが生じてしまいます。 その問題に対処すべく Google Cloud では Secret Manager を使うことで、 秘匿情報を安全に管理する方法を提供しています。 本記事では、 Secret Manager に サンプルの API キー を格納し、 Python で作成した Cloud Functions から参照する方法を紹介します。 引用元: https://cloud.google.com/secret-manager/ 本記事の概要 本記事では以下を実施していきます。 シークレット バージョン の作成 Python で作成した Cloud Functions 関数から 事前に作成した シークレット バージョン の値を取得 なお、“シークレット バージョン” という呼称は、個人的に少し馴染みが無いため以下のように捉えています。 「パスワードなどの秘匿情報 = (Secret) をバージョン管理したもの」 前提 なお本記事を読みすすめるにあたっては、以下を実施済みであることが前提となっています。 Python 開発環境の設定 サービスアカウント作成済み 参考記事: Secret Manager を利用するための準備 Secret Manager API の有効化 まずは、 Secret Manager API を有効化します。この API を有効化することで、後述する Secret Manager を使って シークレット バージョン を管理することができるようになります。 GCP コンソール から以下のように遷移し有効にしていきます。 既存 サービスアカウント への Secret Manager への アクセスロール 付与 次に、Secret Manager にアクセスできるようにしていきます。最初に Secret Manager 関連のロールにどのようなものがあるのかを確認していきます。 Secret Manager 関連ロール Secret Manager 関連ロールには以下が用意されています。今回は、作成済みの シークレット に Cloud Functions … Read more

[Python3] 年月日などの情報から日時オブジェクト datetime を作成する方法

Python で日時を扱う際に datetime オブジェクトを用いると、オブジェクト同士の比較や、時差を考慮することができるようになるので大変便利です。日付を表現した文字列から datetime に変換するサンプルは数多く見つけることができましたが、イチから作成する方法はあまり紹介されていないようだったので紹介します。 環境:Python 3.9 Python datetime について まずは、Python における日時オブジェクトである datetime について簡単に触れていきます。 Python における日時オブジェクトである datetime は、Aware と Naive という2つに分類されます。 Aware: タイムゾーンなどの付加情報をもつため、解釈の余地のない特定の実時刻を表現 Naive: タイムゾーンなどの付加情報をもたないため、多少曖昧ともいえる時刻を表現 また、datetime で取り扱うことができる型は以下の通りです。 date 日付:年、月、日からなる日付 time 時刻:時、分、秒、ミリ秒、 tzinfo からなる時刻 datetime 日付+時刻:date と time を組み合わせたもの timedelta 時間差(経過時間): date, time, datetime について、2つのインスタンス間の時間差 tzinfo タイムゾーン情報: datetime, time で用いるタイムゾーン情報 timezone タイムゾーン:tzinfo に基づいた時刻を UTC からのオフセットとして実装 datetime — 基本的な日付型および時間型 厳密な時刻を扱う必要がない場合は、 Naive が簡素に扱えそうです。ここでは、Aware か Naive かを意識して日時オブジェクトを作成していきます。 datetime オブジェクトの作成 それでは、実際に datetime オブジェクトを作成していきます。まずは、より簡単に作成することができる Naive から始めます。対話型 Python を使ってすすめていきます。 時差を意識しない Naive オブジェクトの作成 対話型 Python を起動します。 年、月、日 を指定して作成してみます。 次に、年月日に加え、時分秒まで指定してみます。 なお、時分秒ミリ秒は省略可能で省略するとゼロとして扱われますが、年月日は省略不可となります。 続いて、より正確な日時を表す Aware オブジェクトを作成していきます。 時差を意識した Aware オブジェクトの作成 Aware オブジェクトを作成するためには、 tzinfo を指定して作成する必要があります。まずは、 UTC で作成してみます。 次に、同じ時刻を JST として作成してみます。JST として作成するためには、datetime のサブクラスである timezone を使って JST を表現する必要があります。以下にあるように、UTC からの固定の時差を指定することで表現することができます。用途に応じて timezone の作成方法に違いがあります。ここでは、後者の方法で進めていきます。 timezone クラスは tzinfo のサブクラスで、各インスタンスは UTC からの固定されたオフセットで定義されたタイムゾーンを表しています。 … Read more

[GCP Cloud Functions Tutorial] Python クイックスタート(関数の作成、デプロイ、テスト、関数の削除)

GCP のサーバーレスコンピューティングサービスである、 Cloud Functions について、 Python で動作させるためのチュートリアル、Python クイックスタートについて解説していきます。 事前準備1、事前準備2が完了していることが前提となりますので、そちらがまだの場合は是非先にご参照ください。なお、各見出しに対応するチュートリアルページへのリンクを設定しています。 関数を作成する GCP コンソール左上のハンバーガーメニューを下にスクロールしていくと、「サーバーレス」セクションの中に「Cloud Functions」がありますので、これをクリックして、 Cloud Functions を作成していきます。 余談ですが、ピンアイコンをクリックすることで、そのサービスがリストの上に固定表示されるようになります。GCP のサービスは数も多いので、よく使うサービスの場合はピン留めしておくと便利です。 「関数を作成」をクリックします。 次に、関数の基本情報を設定します。チュートリアルに記載されている内容に従って必要な項目を埋めていきます。チュートリアル上の手順6番までを実施することになります。 「リージョン」に関しては、後から変更できないため、適切なものを検討した上で選択してください。 なお「ランタイム、ビルド、接続の設定」はこのタイミングでは特に変更する必要はありません。「保存」をクリックした後、画面の一番下に出現する「次へ」ボタンをクリックして関数のコードを記載する画面を表示します。 ここでは、チュートリアルの残りの手順(7、8)を実施していきます。 手順が前後してしまいますが、まずは「ランタイム」プルダウンから使用したいランタイムを選択します。ここでは、Python 3.9 を選択して進めていきます。 ランタイム選択前はデフォルトの Node.js 14 に関するコードが表示されていましたが、Python 3.9 選択後は Python 3.9 のものに更新されます。 サンプルコードの内容 チュートリアルでは触れられていませんが、ここで簡単にサンプルコードの内容を見ていきます。 main.py Cloud Functions の関数は基本的に Web の API として動作することを想定していて、デフォルトで用意されているものはFlaskフレームワークを用いています。このチュートリアルでは ここで定義した hello_world というエンドポイントをデプロイすることになり、API 呼出し時の情報は request 変数に格納されることになります。 最初に、 request_json 変数に、呼出し時の情報を JSON化します。 次に、API呼出し情報にパラメータがあり、そのパラメータ名が message なら、そのmessageパラメータに指定された内容をそのまま呼出し元に返すようにしています。 同様に、JSON化した際に、message が存在した場合にも同様の処理を施すようにしています。前者がGETによるクエリパラメータへの対応で、後者がJSON形式でのPOSTへの対応となっています。(後ほど、それぞれテスト動作させてみます) API呼出し情報に message パラメータが存在しない場合は、Hello World! を返します。 requirements.txt 初期段階では本ファイルはコメント行があるのみの状態です。 関数をデプロイする デプロイするには画面下部の「デプロイ」をクリックします。 デプロイには1〜2分ほどかかります。デプロイが完了すると、以下の様にリスト表示されます。それでは、デプロイした関数をテストして動作をみていきます。「操作」列の3点リーダーをクリックして、「関数をテスト」をクリックします。 関数をテストする テスト画面が表示されます。まずは、そのまま、「関数をテストする」をクリックしてみます。これは、パラメータなしで関数を呼び出すことになりますので、さきほどコードを見たとおり、 Hello World! が返ってくることが期待値になります。 テストが完了すると、「出力」と「実行ログ」が表示されます。期待値通り、 Hello World! と表示されていることが確認できます。 JSON形式POST 次に、JSON形式のPOSTをした場合の動作をテストしてみます。message パラメータに指定された内容がそのまま返ってくることが期待値になります。 こちらも期待どおりの動作が確認できます。 エンドポイントへのGET確認 チュートリアルには言及がありませんが、ブラウザでエンドポイントにアクセスして動作を確認してみます。 関数一覧から、関数名をクリックして「関数の詳細」を表示します。 「トリガー」タブを選択すると、エンドポイントのURLが記載されていますので、これをコピーしてブラウザに貼りつます。 パラメータ指定がないため、 期待値の Hello World! が表示されました。 パラメータを指定してみます。こちらも期待通りの結果となりました。 ログを表示する テスト実施時のログを確認してみます。関数一覧のページの操作列、「ログを表示」をクリックします。 各種ログが表示されます。赤枠で囲った「クエリ」部分に、プロジェクトやCloud Functions といった情報であらかじめフィルタリングされた状態でログが表示されています。 関数を削除する 最後に、チュートリアルには言及がありませんが、関数を削除します。チュートリアルということもあり、未認証でもアクセスできてしまう状態で進めていますので、忘れない内に削除しておかないと、何かがきっかけで想定外の請求が来てしまいかねないリスクは回避したいところです。Cloud Functions では、有効・無効を切り替えるようなことはできないようなので、削除することにします。 関数一覧のページの、操作列「削除」をクリックします。 「削除」をクリックします。削除してしまうと関数内のコードは失われてしまうので、必要に応じて手元にコピーするなどバックアップ対策を講じてください。 なお、一時的に無効化する Tips としては、単純にコード全体をコメントアウトするのが現実解のようです。 参考: https://stackoverflow.com/questions/43681644/is-there-a-way-to-stop-disable-a-google-cloud-function まとめ … Read more

[Python][Selenium]How to launch WebDriver with Headless Chrome

If you are going to use Selenium against a dynamic web site such as using Javascript, you should use Headless Chrome. However, it seems that there are no helpful instruction so far. So I’m going to explain how to launch WebDriver with Headless Chrome. Photo by Diego Molina (diemol) / CC BY-SA 4.0 Environment Mac OS Big Sur 11.1Python 3.8.3ChromeDriver 89.0.4389.23 ChromeDriver Official Sample Code I found the official sample code from ChromeDriver Official Site, however, there are no explanation about “Headless”. Here is the sample code cited from this site. Add options parameters What we have to do to launch with Headless Chrome is to add “options” parameters as following. Note … Read more

[Python][Selenium] Headless Chrome での WebDriver 起動方法

[Python][Selenium]Headless ChromeでのWebDriver起動方法

Javascript を用いた動的サイトを対象とし、Selenium を動作させようとしたところ、簡単なところで躓いてしまったので、備忘までに以下に手順を残します。 Mac OS Big Sur 11.1Python 3.8.3ChromeDriver 89.0.4389.23 公式のサンプルコード 公式の Getting Started を参照すればよいのですが、Headless についての言及がされていないようでした。 Headlessで起動するためのオプション 色々と調べたところ、以下の様にheadlessのオプション指定をすることで動作することがわかりました。 最終的なサンプルコード ‘/usr/local/bin/chromedriver’ の部分は適宜環境に合わせて修正する必要があります。 まとめ Headless で起動するには、 driver に options.add_argument(‘–headless’) を追加 chromedriver の実行モジュールへのパスは、適宜実行環境に合わせる