ClovaSDKのPythonVerがあるのだ
ClovaSDKのPythonVerがあるのだ
こんばんは、葛の葉です。
先日、駅すぱあとのヴァル研究所さんで行われたハンズオンに出席しました。
Lineさんが作っているスマートスピーカーの「Clova」の「スキル」の開発についての勉強会だったのですが、これが中々に面白い体験でした。正直、スマートスピーカーを触ったのが今回はじめてだったのですが、「スキル」を開発出来てとても面白かったです。
そんな「Clova」の開発用のPythonで使用できるSDKが出たということで、そのドキュメントのリンクを張っておきます。
こちら↓
Clova Extension Kit SDK for Python — clova-cek-sdk 1.0.0 documentation
なお、PythonのClovaSDKはpipでインストールすることが出来ます。
pip install clova-cek-sdk
モジュールとして使うときはimport cek
で使います。
import cek
ちょっとSDKとは直接関係ないお話
スキルって?
スマートスピーカーを触ったことがなかった私には「スキル」という言葉がよくわからなかったです。いわゆる、スマートフォンにおける「アプリ」のようなものでして、機能の一単位のことになるようです。それで、今回のClovaSDKはそのスキルを作成できるものとなっています。
Clova Friendsってどんな感じ?
Clova Friendsの大きさは500mlの缶ジュースより少し高さがあるくらいで、太さは500mlのペットボトルぐらいな気がしますClova Friends miniは持っていないのですが、Clova Friendsの半分ぐらいじゃないでしょうか?
なんと、内臓バッテリー付きです。Bluetoothでスマホと接続して音楽などを流したりすることもできますので、Clova Friendsを屋外に持ち出して、外で音楽を流すっていうこともできますね。一つ思いついた遊びとして、スマホで演奏するアプリを使って、Clova Friendsで流すなんてやれたら面白いかもなぁなんて思いました。
スキル、としては、ネットワークに繋がっていることが前提なものが多いように見受けられますので、外部に持ち出す部分とは少し相性悪いのかも?とは正直に思いました。
若干、最近スマートスピーカーに焦点が当たりつつあると思ってます。
皆さんもぜひ、色々なスマートスピーカーを触ってみてください。
Pythonで特定文字以降の文字を削除する(正規表現を使わない)
Pythonで特定文字以降の文字を削除する(正規表現を使わない)
イテレータで作ったVerがありますので、よかったら以下もどうぞ
こんばんは、葛の葉です。
さて、APIなどで、文字列を取得することがあると思うのですが、余分な部分は無くして綺麗な形で変数や配列に入れたいと思うことが多々あると思います。
たとえば町田(東京)
の(東京)
部分
たとえばシェフの気まぐれサラダ(工場生産)
の(工場生産)
の部分
たとえばからあげ:20180810
の:20180810
の部分
正規表現で削除することも出来るのですが、私はこんなやりかたをしてみました。
moji = 'シェフの気まぐれサラダ(工場生産)' moji = moji.split('(')[0] print(moji) >>>シェフの気まぐれサラダ
>>>シェフの気まぐれサラダ
出来ました!!!
要するにsplit('(')
を使って(
を境に文字を区切って配列にしています。
moji.split('(')
は['シェフの気まぐれサラダ', '工場生産)']
という配列になりますね。
その[0]
番目の要素を取り出すのでシェフの気まぐれサラダ
の部分だけ取り出すことが出来るわけですねぇ。
ただ、配列に分解して取り出しているだけなので、複雑な文等には適していないと思います。
切りたい文字が入っている要素、入っていない要素の入子になっている配列での取り出し方
また、例えば配列の中に括弧()
が入っている、入っていないものが入子になっている配列もあるかと思います。
dinners = ['チキングリル', 'シェフの気まぐれサラダ(工場生産)', 'ドラゴンのしっぽビール(発泡酒)', 'スコーン']
こんな場合は以下のようにしてみましょうか
dinners = ['チキングリル', 'シェフの気まぐれサラダ(工場生産)', 'ドラゴンのしっぽビール(発泡酒)', 'スコーン'] cut_dinners = [] # 入れ替える別配列を用意しておく for dinner in dinners: if '(' in dinner: cut_dinners.append(dinner.split('(')[0]) else: cut_dinners.append(dinner) print(cut_dinners) >>> ['チキングリル', 'シェフの気まぐれサラダ', 'ドラゴンのしっぽビール', 'スコーン']
if '(' in dinner:
という方法をとると良いですね。
文字列内に(
があるか…?を判定し、
Trueならcut_dinners.append(dinner.split('(')[0])
Flaseならcut_dinners.append(dinner)
とします。
API等を使うと色んな値が入った文字列と出会うようになったなぁと思ってます。
その文字列を加工していくことも、すごく重要ですよね。
API使って開発されている皆様のお役に立てれば幸いです。
DockerでflaskとuWSGIを別コンテナのNginxと連携してみた
DockerでflaskとuWSGIを別コンテナのNginxと連携してみた
こんばんは、葛の葉です。
さて、よくNginx
とuWSGI
を使ってWebサーバー
の構築をしている記事は見かけますが、
同じコンテナ内でNginx
とuWSGI
をインストールしているケースが多く、
Nginx
とuWSGI
と別コンテナで構築しているケースがあまり無いのかな、と思いました。
DockerCompose
を使った場合になるのですが、簡単に書いていきたいと思います。
なお、もっといいケースなんてたくさんあると思うので、むしろ教えて頂ければと思います。
まず、docker-compose.yml
が必要で、更にIPアドレスを固定化するか、コンテナネームを固定化したほうがよいです。
それは記事にしましたので、下に載せます。
コンテナネームの固定化について
コンテナのIPアドレスの固定化について
flaskのあるコンテナでの設定
uWSGI
が必要なため、flask
のあるコンテナでpipでインストールします。
pip install uwsgi
また、設定ファイルが必要なので、uwsgi.ini
というデータを作り、以下のように記載します。
[uwsgi] http = :3031 #ここはuwsgiのポート番号 chdir = /var/www/ #下記、flaskで実行したいプログラムのあるディレクトリ wsgi-file = page.py #flaskのプログラム callable = app #flaskを実行するためにここは不変更
そして、コマンドでuwsgi --ini uwsgi.ini(先程のuwsgi.ini)
として、実行すればよいです。
これをdocker-composeでのcommand
で設定すれば、コンテナが起動するときに指定したコマンドが実行されるはずです。
command: uwsgi --ini uwsgi.ini
とすればよいです。
uwsgi.ini
をホストマシンから持ってくるにはvolumes
で共有すればよいので、
例えばdocker-compose.yml
のあるディレクトリにapp/config
ディレクトリを作り、
そのapp/config
以下に先程のuwsgi.ini
を保存しておき、docker-compose.yml
で以下のように記載して共有します。
また、docker-compose up
時にuwsgi.ini
を起動するようにしておきます。
volumes: - ./flask_app/config/:/var/www/config/ command: uwsgi --ini /var/www/config/uwsgi.ini
とこのようにしておきます。
Nginxのあるコンテナでの設定
Nginxは/etc/nginx/nginx.conf
の設定を変えてあげればうまくいきます。
また、そのnginx.conf
をホストOSで作ってあげて、渡してあげればよい、ということになります。
ホストOSにnginx.conf
を持ってくる方法はとりあえず記載しないとして
(一度、Nginxコンテナ単体で起動して、共有のフォルダにコピーしてホストOSに持ってくる等)
設定ファイルのlocation
部分を以下のようにの設定します。
location / { client_max_body_size 1m; client_body_buffer_size 8k; proxy_pass http://[flaskのあるコンテナネームorコンテナのIPアドレス]:3031; proxy_redirect default; }
これを、例えばdocker-compose.yml
のあるディレクトリにnginx/config
ディレクトリを作り、
そのnginx/config
以下に先程のnginx.conf
を保存しておき、docker-compose.yml
で以下のように記載して共有します。
volumes: - ./nginx/config/nginx.conf:/etc/nginx/nginx.conf
直接、Nginxのnginx.conf
ファイルに共有してあげます。
専用のconf
をつくって、そこに読みに行くような設定もありますが、ちょっとこちらでは記載しません。(Nginxの設定方法の話になるので)
docker-compose upする
この状態でdocker-compose up
すると、nginxで開放したポート番号に接続すれば、flaskのアプリが起動するはずです。
DockerComposeでContainerのIPアドレスの固定化をするかー
こんばんは、葛の葉です。
久しぶりにDockerのことを書こうと思いました。
今回はDocker-ComposeでcontainerのIPアドレスを固定化を行いました。
networks: aplication_net: ipv4_address: 172.19.x.x
DockerComposeで各コンテナの設定部分に上記の部分を記載すればよいです。
aplication_net
はDockerNetworkの名称になります。
ipv4_address: 172.19.x.x
は使用するIPアドレスです。
また、コンテナ間にDockerNetworkを構成する記述を行います。
networks: aplication_net: driver: bridge ipam: driver: default config: - subnet: 172.19.0.0/24
aplication_net:
部分はDockerNetwork名を記載します。
subnet: 172.19.0.0/24
は使用したいネットワークアドレスとそのサブネットマスクをプレフィックス長で記載します。
なお、cofig:
下ではgateway:
というプロパティ、デフォルトゲートウェイの設定もあるそうなのですか、v3
では出来ないようです。
デフォルトゲートウェイがどういうIPアドレスであるかが不明なため、今回は172.19.0.1
を想定しています。
docker-compose.yml
は以下の通りになります。
services: mysql: image: ./mysql ~~~~~~~~~~~中略~~~~~~~~~~~~~~~~~~ networks: aplication_net: ipv4_address: 172.19.0.2 app: build: ./app ~~~~~~~~~~~中略~~~~~~~~~~~~~~~~~~ networks: aplication_net: ipv4_address: 172.19.0.3 nginx: image: nginx ~~~~~~~~~~~中略~~~~~~~~~~~~~~~~~~ networks: aplication_net: ipv4_address: 172.19.0.4 networks: aplication_net: driver: bridge ipam: driver: default config: - subnet: 172.19.0.0/24
docker-compose up
でコンテナを起動しましょう。
docker exec -it コンテナ名 /bin/bash
でコンテナ内に入り、hostname -i
でIPアドレスを確認してみましょう。
root@xxxxxxxxxxxx:/# hostname -i 172.19.0.3
IPアドレスが表示されました!
GSSとGASとDiscordで遊んじゃおう
GSSとGASとDiscordで遊んじゃおう
こんにちは、葛の葉です。
GoogleSpreadSheet
ってあるじゃあないですか。
このGoogleSpreadSheetにscriptを実装できるようになっていて
それがGoogleAppsScript
っていうやつになります。
さらに、そのGoogleAppsScriptを使ってDiscord
と連携できるようになります。
今回はGoogleSpreadSheetのセルの中身をGASで取得してDiscordに発信するbotを
作りたいと思います。
必要な材料
- Googleアカウント
- Discordアカウント
- Discordのノリにそれなりについていける心
好きなシートを作るんだ
好きなシートを作りましょう。
A1
セルに好きな言葉も入れておきましょう。
ちなみに私葛の葉
って名前だけど、これ元は雌の狐の名前なので
よーく考えたら男なのに女性の名前使ってましたね。
まぁ…いいか…
スクリプトエディタ起動
右上に[ツール]タブ
があって、そのメニューにスクリプトエディタ
っていうのがありますので
クリックすると別画面が開いて、それがスクリプトエディタが表示されます。
こんな画面がスクリプトエディタです。
DiscordのWebhookを起動
botとして出力させたいDiscordのチャンネルで歯車のボタンを押します。
そこから画面左側の[Webhooks]
→[Webhooks作成]
をクリックします。
出てきた画面には好きなbotの名前やアイコンを設定して保存しましょう。
そうしたら画面右側に作ったbotが表示されていると思うので[編集]
を押します。
さっきbotを作った画面に似たようなものが出てきますが、その下にスクロールすると
URL[画面の赤い四角部分]が表示されていますので、これをコピーします。
コピーしたURLをブラウザーで開くと何やらいろいろ書かれたものが出てきますが、
"token: "
の右側の色んな文字数字をコピーしておいてください。
スクリプトエディタでコードを書く
function submit(){ discord(get_value()) }; function get_value() { var sheet = get_sheet('自分の作ったシートのURL',0); var range = sheet.getRange(1,1); //ここの(1,1)は座標です。第一引数が行、第二引数が列です。 var value = range.getValue(); return value; }; function get_sheet(gss_url,sheet_num) { var ss = SpreadsheetApp.openByUrl(gss_url); var sheet = ss.getSheets()[sheet_num]; return sheet; }; function discord(message) { const url = 'さっきコピーしたwebhooksのURL'; const token = 'さっきのURLの中のtokenの文字列'; const channel = '#general'; const text = message; const username = 'bot'; const parse = 'full'; const method = 'post'; const payload = { 'token' : token, 'channel' : channel, "content" : text, 'username' : username, 'parse' : parse, }; const params = { 'method' : method, 'payload' : payload, 'muteHttpExceptions': true }; response = UrlFetchApp.fetch(url, params); }
関数の実行
関数を選択
を押すとプルダウンがでてきますのでsubmit
を押してください。
実行ボタンを押すとスクリプトエディタの上部になんかメッセージが出てきます。
権限がどうのって聞いてきますが、ポチポチ押せばOKです。
そしたら、葛の葉
ってメッセージが#general
に表示されるはず!
A1
の値を変えてもいいですし、sheet.getRange(1,1)
の(1,1)
の値を変えてみるのも面白いですよ!
Pythonで1から6の数字出すDiscordbot作ったよの巻
PythonでDiscordbot作ったよの巻
こんばんは、葛の葉です。
なんかDiscordっていうチャットアプリがあるんですよ、知ってますか?
ゲームで使う用のボイスチャットアプリなんですけど、普通にチャットするだけでもずいぶん使えるんですよね。
そのDiscordにbotを追加することができるんです。
pipでモジュールを追加
pipでdiscordのbot用のモジュールを追加します。
pip install discord.py
discord用のモジュールの追加はこんな感じ。
他にも
pip install asyncio
とかも必要かもしれない。(僕は使ったことないのに入ってたけどね)
公式サイトからトークンを取得
Web版のdiscordにログインした状態でここで色々とあれこれやるとbotトークンが手に入ります。
pythonで書いてみよう
pythonコードは以下の感じ。
import asyncio #なんか必要らしい import discord #さっきpipで取り入れたやつだぞ! import random #ランダムな数字を作るモジュールだぞ! client = discord.Client() @client.event #コマンドラインに出力されるぞ。printのところが出ないなら何かが間違ってるぞ async def on_ready(): print('Logged in as') print(client.user.name) print(client.user.id) print('------') @client.event async def on_message(message): if message.content.startswith("!dice"): #ここの!diceは好きなのにしていいぞ if client.user != message.author: num_random = random.randrange(1,6) m = str(num_random) await client.send_message(message.channel, m) client.run("[手に入れたトークンを記入しよう]")
!dice
って書き込むと1-6
の値を返してくれるぞ!!!!
色々と改造して遊ぼうかな。
DockerCompose で コンテナの名前を作るのだ
葛の葉です。
Dockerの話が続いていきますよ~
DockerComposeではコンテナに名前を付けることが出来ます。
docker-composer.yml
は以下の感じ!
version: "3" services: ubuntu1: image: ubuntu:18.04 container_name: lion stdin_open: true tty: true ubuntu2: image: ubuntu:18.04 container_name: albatross stdin_open: true tty: true
container_name: *****
の ところがcontainerネームになりますですね。
76ad******fdc ubuntu:18.04 "/bin/bash" 2 minutes ago Up 2 minutes lion 7991******f1b ubuntu:18.04 "/bin/bash" 2 minutes ago Up 2 minutes albatross
こんな感じになります。
docker exec -it [containerネーム] /bin/bash
でcontainerの中を覗けますよ!docker-compose.yml内で一緒に立ち上げたcontainerなら名前解決もしているのでping
も通ります!
ping
が打てるようにするためのパッケージをinstallする。
apt update apt install iputils-ping
ping -c 5 [containerネーム]
で5
回ping
を打つ。
ping -c 5 lion ping -c 5 albatross
どっちのcontainerに入っていても、ping
が通るはずです!