Pythonデータ分析チートシート

データのロード CSVファイルのロード 1 2 import pandas as pd pd.read_csv('./data.csv') BigQueryクエリ結果のロード 1 2 3 4 5 6 7 8 9 10 import pydata_google_auth import pydata_google_auth.cache from google.cloud.bigquery import Client credentials = pydata_google_auth.get_user_credentials( scopes = ['https://www.googleapis.com/auth/bigquery'], ) client = Client(project="myprojectname", credentials=credentials) job = client.query("SELECT * FROM mytable;") df = job.to_dataframe() データ仕様の把握 データの中身を見る 1 2 df.head() # 先頭 df.tail() # 末端 スキーマ情報を見る 1 df.info() 1 2 3 4 5 6 7 8 9 <class 'pandas....

December 28, 2022

NextCloudのパーミッションエラー回避

こんな感じでNextCloudをk8sにデプロイするとします。 nextcloud.yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 apiVersion: apps/v1 kind: Deployment metadata: name: nextcloud namespace: default spec: replicas: 1 selector: matchLabels: app: nextcloud template: metadata: labels: app: nextcloud spec: containers: - name: nextcloud image: nextcloud env: - name: NEXTCLOUD_DATA_DIR value: /data ports: - containerPort: 80 protocol: TCP volumeMounts: - name: myvolume subPath: config mountPath: /var/www/html - name: myvolume subPath: data mountPath: /data volumes: - name: myvolume persistentVolumeClaim: claimName: myvolume securityContext: fsGroup: 33 --- apiVersion: v1 kind: Service metadata: name: nextcloud namespace: default spec: ports: - name: http port: 80 protocol: TCP selector: app: nextcloud clusterIP: None すると初回ログイン後に以下のようなエラーが出てきます。...

November 29, 2022

BigQueryのデータを元にパーソナライズされたメールを送信する

BigQueryに格納されている行動ログを元にマーケティングオートメーションを構築、SendGridでメールを発射したいケースは多々あるかと思います。 MAツールはかなり高価なものが多いため、シュッと自前構築するためのサンプルコードを掲載します。 送信したメールの効果測定・分析方法についても少し触れます。 1. SendGridテンプレートの作成 公式ドキュメントを参考に、Dyamic templateを作成します。 詳細は割愛しますが、今回は以下のようなメールを送りたいとします。 1 2 3 4 5 6 7 foobar様への今週のおすすめ商品です! 1. ほげほげ (1000円) 2. ふがふが (1500円) 購入はこちらから! https://example.com テンプレートはこんな感じで記述します。 1 2 3 4 5 6 7 8 {{customer_name}}様への今週のおすすめ商品です! {{#each products}} {{this.number}}. {{this.product_name}} ({{this.price}}円) {{/each}} 購入はこちらから! https://example.com このテンプレートに対して、送信対象ごとに以下のようなデータを埋め込む事が目標になります。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 { "customer_name": "foobar", "products": [ { "number": 1, "product_name": "ほげほげ", "price": 1000 }, { "number": 1, "product_name": "ふがふが", "price": 1500 }, ] } 2....

November 8, 2022

Kinesis Data FirehoseからMongoDB Cloudにデータを流してみる

Amazon Kinesis Data Firehose が MongoDB Cloud へのデータ配信のサポートを開始 したそうなので試してみましたが、色々と「ん?」と思う点があったので書き残します。 MongoDB Atlas でClusterを作成 MongoDB Atlas、MongoDB Realmという単語が登場しますが、AtlasはDBaaSとしてのMongoDBそのもの、RealmはAtlasを操作するためのインターフェースとなるサービスのようです。 まずはAtlasでCluster, Database, Collectionを作成します。 Get Started with Atlas MongoDB Realm Functionsを実装 てっきりGUIポチポチで連携完了するものかとおもってましたが、FirehoseからのWebhookエンドポイントとなるサーバーレス関数を自前で実装する必要があります。 だったらKinesis Data Streams + Lambdaでよくね…? MongoDB Realm Functions リリースノートのリンク先のサンプルコードの冒頭はこんな感じ。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 exports = function(payload, response) { /* Using Buffer in Realm causes a severe performance hit this function is ~6 times faster */ const decodeBase64 = (s) => { var e={},i,b=0,c,x,l=0,a,r='',w=String....

February 2, 2022

2021年 エンジニア的に買ってよかったもの

仕事(エンジニア/フルリモート)に役立ったかどうか、という観点で備忘的にまとめてみました。 自宅サーバー (自作) サーバーとして使っていたRaspberry piが成仏し、現在どこも在庫が皆無なため代わりにファンレスPCを組みました。スペック的にも物理的な拡張性にも余裕があるためより一層遊べるようになり、結果として大正解。 サブスクのクラウドサービスをセルフホステッドにどんどん切り替えていってるので、スキルアップと家計の両面に大いに貢献しています。 消費電力は25W/hくらい、電気代は月500円弱。 動かしているアプリケーションに関してはまた別記事で書きたい。 パーツ 型番 M/B BIOSTAR J4105NH CPU オンボード MEM CFD W4U2400PS-4GC17 (4GB x 2) PSU DC-DCコンバータ + 120W ACアダプタ ストレージ 余っているSSD/HDDいっぱい。合計10TBくらい ケース 100均の書類ケースに適当にネジ止め 自作キーボード YD60MQ 何個かキーボードを作ってみて得た結論として、 特殊すぎる配列はメリットに対して切り替えコストが割に合わない 右手でマウスを持ったまま左手で右側のキーを押す事があるため、自分の場合は左右分割だと効率が下がる という事から、結局HHKB配列の YMDK YD60MQ に落ち着きました。 Cherry MX銀軸が自分にかなりマッチしており、HHKBを使っていたときより指の疲労が低減しました。 LG ウルトラワイドモニター 35WN75C-B 買ったというか、転職サイトから貰った。 4kモニタは既に持っていてこちらの方が解像度は低かった(3440×1440)けど、大きい正方形のウィンドウ2つを横に並べても視野に収まるのが予想以上に便利でメインモニタに昇格しました。 曲面のため光の映り込みが少ないのも便利。 つっぱり棚 サバゲーやる人が銃を飾るのによく使っているアレです。 棚が小物類で散らかりまくってカオスだったので、いっそ全てを壁に引っ掛けるスタイルにしました。 ヘッドホンとかメガネとか、100均のS字フックでなんでも引っ掛けています。 適当に積む事が物理的にできなくなりました。負債を貯めないように頑張るのではなく、負債が貯まらない仕組みができました。 Mi Band 6 安くて小型軽量、更にめちゃくちゃ電池が持つスマートウォッチです。 Apple Watchをあまり着けなくなった過去がありますが、こいつは1週間以上電池が持つので基本つけっぱなしです。 運動量と睡眠の可視化、Slackの通知などに使っています。 パネルヒーター ファンヒーターより気持ちいい暖かさで消費電力も少ない。 暖房を普段より弱くして頭寒足熱状態にすると集中しやすい。 底面にもパネルがあるタイプがお勧め。 コーヒーメーカー 誰でもわかるレベルでインスタントコーヒーより美味しく、エナジードリンク依存を脱却できました。 手動ミル + ペーパーフィルター + コーヒーメーカー(ドリップのみ) のスタックで運用しています。...

January 9, 2022

Kubernetesに写真サーバーを構築する

2021年6月1日からGoogle Photoの容量が無制限ではなくなり、無料枠は15GBに制限されてしまいました。 完全に音楽サーバーを構築した話の二番煎じですが、自宅k8sに写真サーバーを構築してそちらに移行する事にしました。 デプロイ self-hostedな写真サーバーで最もメジャーなプロダクトはPiwigoの模様。 サクっとyamlを書いてデプロイします。 deployment.yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 apiVersion: apps/v1 kind: Deployment metadata: name: piwigo spec: replicas: 1 selector: matchLabels: app: piwigo template: metadata: labels: app: piwigo spec: containers: - name: piwigo image: lscr....

January 4, 2022

おうちKubernetesに音楽ストリーミングサーバー(兼ファイルサーバー)を構築する

神(Google)は「Play Music」と言われた。するとGoogle Play Musicがあった。 神はそのUXを見て、良しとされた。 神はまた言われた。「YouTube Musicに移行してください」 UIは使いづらく、バックグラウンド再生できず、ロードは遅くなり、楽曲メタデータは編集できなくなった。 神はお休みになった。 概要 所有している音楽データをアップロードし、インターネット経由で聴くというサービスでしっくりくるものがないため、自宅Kubernetesクラスタに自前で構築してみます。 家庭内LANからファイルサーバーとして使える ファイルサーバーにアップロードした音楽データをインターネット経由で聴ける ファイルサイズが大きい楽曲はサーバーサイドでリアルタイムに圧縮して配信する という要件から、以下のような構成にしてみます。 音楽配信サーバーには Airsonicを使います Ingress(L7ロードバランサー)経由でインターネットに接続します IngressをTLS終端にします ファイルサーバーとしてSambaを構築します Airsonicとストレージを共有します LoadBalancer Service(L4ロードバランサー)経由で家庭内LANに接続し、インターネットからは遮断します 構築 1. Storage まず初めに、Podからホストマシンのストレージを使うためのPersistentVolume(PV)とPersistentVolumeClaim(PVC)を作成します。 今回は node1 の /mnt/hdd に音楽データとメタデータ(設定、アカウント情報など)を永続化するとします。 pv.yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 apiVersion: v1 kind: PersistentVolume metadata: name: music spec: capacity: storage: 1000Gi accessModes: - ReadWriteOnce local: path: /mnt/hdd/music nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes....

December 2, 2021

ArgoCD GitOpsにおけるSecret管理

KubernetesでGitOps運用となると必ず話題になるのがSecretの管理です。 Sealed Secretsやkubesecなどの手元で暗号化する系 Kubernetes Secrets Store CSI Driverやkubernetes-external-secretsなどの外部シークレットストアから引っ張ってくる系 機密情報だけ別Repoにする など様々な方法がありますが、学習コストや実運用をイメージするとどのソリューションもしっくり来ませんでした。 そんな中でIBM社が開発しているArgoCD Vault Pluginを触ってみたところ、ArgoCDのデプロイ時にplaceholderをreplaceするという合理的かつシンプルな仕組みで非常に好感触でした。 2022/02追記: Argo Projectに移管されたようです。 https://argocd-vault-plugin.readthedocs.io/en/stable/ (上記でいう「外部シークレットストアから引っ張ってくる系」の一種に該当します) ArgoCD Vault Plugin (以下AVP) は日本語の情報が皆無に等しかったため、布教の目的も込めて導入・運用方法を記載します。 テスト AVPはbrewからも導入でき、手元で簡単にテストができます。 シークレットストアはAWS Secrets Mangerを使う前提で解説します。 ローカル環境にインストール (Mac) 1 $ brew install argocd-vault-plugin AWS Secrets Mangerに機密文字列を登録する 1 2 key: my_secret value: foobar Kubernetes Manifestを作成する Secretの実装は非常に簡単で、 アノテーションに参照するSecret Managerのパスを記述する Secret Managerのキー名を<> で囲う だけでOKです。 1 2 3 4 5 6 7 8 apiVersion: v1 kind: Secret metadata: name: credentials annotations: avp.kubernetes.io/path: "avp/test" data: MY_SECRET: <my_secret | base64encode> Decryptのテスト 1 2 3 4 5 6 7 8 9 10 11 12 13 $ export AWS_ACCESS_KEY_ID=xxxx $ export AWS_SECRET_ACCESS_KEY=xxxx $ export AWS_REGION=ap-northeast-1 $ export AVP_TYPE=awssecretsmanager $ argocd-vault-plugin generate path/to/secrets....

November 1, 2021

Argo Workflowsの失敗時にデフォルトでSlackに通知する

Argo workflowsでは Default Workflow Spec を設定する事でワークフローに色々とパッチできる。 以下のようにexit-handlerをworkflowDefaultsにしておくと、ワークフロー側に何も記述せずとも失敗時にSlackに通知できる。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 apiVersion: v1 kind: ConfigMap metadata: name: workflow-controller-configmap data: workflowDefaults: | spec: onExit: exit-handler templates: - name: exit-handler when: "{{workflow.status}} != Succeeded" container: image: curlimages/curl:latest args: ["-X","POST","-H",'Content-type: application/json',"--data", '{"attachments": [{"title":"Workflow status: {{workflow.status}}","color": "danger","fields": [{"title": "name", "value": "{{workflow.name}}", "short": true }, {"title": "url", "value": "https://{{inputs....

October 29, 2021

embulkをArgo workflowsで実行するTemplate

Argo Workflowsの公式ドキュメントが分かりづらかったので、試しにembulkを実行するテンプレートを作ってみました。 config.ymlはartifactsとして渡します。 Dockerfile 1 2 3 4 5 6 7 8 9 10 11 12 FROM openjdk:8-jre-alpine ARG VERSION=latest RUN mkdir -p /root/.embulk/bin \ && wget -q https://dl.embulk.org/embulk-${VERSION}.jar -O /root/.embulk/bin/embulk \ && chmod +x /root/.embulk/bin/embulk ENV PATH=$PATH:/root/.embulk/bin RUN apk add --no-cache libc6-compat RUN embulk gem install embulk-input-s3 ENTRYPOINT ["java", "-jar", "/root/.embulk/bin/embulk"] 1 2 3 $ EMBULK_VERSION=0.9.23 $ docker build . -t embulk:$EMBULK_VERSION --build-arg VERSION=$EMBULK_VERSION $ docker run -v /path/to/configfile:/config embulk:latest run /config/config....

October 28, 2021