Kuzunoha-NEのブログ

プログラミングなどの勉強をしてます

ClovaSDKのPythonVerがあるのだ

ClovaSDKのPythonVerがあるのだ

こんばんは、葛の葉です。

先日、駅すぱあとのヴァル研究所さんで行われたハンズオンに出席しました。

linedev.connpass.com

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-developers.line.me

Clova Friendsってどんな感じ?

f:id:Kuzunoha-NE:20180816194217j:plain

Clova Friendsの大きさは500mlの缶ジュースより少し高さがあるくらいで、太さは500mlのペットボトルぐらいな気がしますClova Friends miniは持っていないのですが、Clova Friendsの半分ぐらいじゃないでしょうか?

clova.line.me

なんと、内臓バッテリー付きです。Bluetoothスマホと接続して音楽などを流したりすることもできますので、Clova Friendsを屋外に持ち出して、外で音楽を流すっていうこともできますね。一つ思いついた遊びとして、スマホで演奏するアプリを使って、Clova Friendsで流すなんてやれたら面白いかもなぁなんて思いました。

スキル、としては、ネットワークに繋がっていることが前提なものが多いように見受けられますので、外部に持ち出す部分とは少し相性悪いのかも?とは正直に思いました。


若干、最近スマートスピーカーに焦点が当たりつつあると思ってます。

皆さんもぜひ、色々なスマートスピーカーを触ってみてください。

Pythonで特定文字以降の文字を削除する(正規表現を使わない)

Pythonで特定文字以降の文字を削除する(正規表現を使わない)

イテレータで作ったVerがありますので、よかったら以下もどうぞ

kuzunoha-ne.hateblo.jp

こんばんは、葛の葉です。

さて、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と連携してみた

こんばんは、葛の葉です。

さて、よくNginxuWSGIを使ってWebサーバーの構築をしている記事は見かけますが、

同じコンテナ内でNginxuWSGIをインストールしているケースが多く、

NginxuWSGIと別コンテナで構築しているケースがあまり無いのかな、と思いました。

DockerComposeを使った場合になるのですが、簡単に書いていきたいと思います。

なお、もっといいケースなんてたくさんあると思うので、むしろ教えて頂ければと思います。


まず、docker-compose.ymlが必要で、更にIPアドレスを固定化するか、コンテナネームを固定化したほうがよいです。

それは記事にしましたので、下に載せます。

コンテナネームの固定化について

kuzunoha-ne.hateblo.jp

コンテナのIPアドレスの固定化について

kuzunoha-ne.hateblo.jp


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 -iIPアドレスを確認してみましょう。

root@xxxxxxxxxxxx:/# hostname -i
172.19.0.3 

IPアドレスが表示されました!

GSSとGASとDiscordで遊んじゃおう

GSSとGASとDiscordで遊んじゃおう

こんにちは、葛の葉です。

GoogleSpreadSheetってあるじゃあないですか。

このGoogleSpreadSheetにscriptを実装できるようになっていて

それがGoogleAppsScriptっていうやつになります。

developers.google.com

さらに、そのGoogleAppsScriptを使ってDiscordと連携できるようになります。

今回はGoogleSpreadSheetのセルの中身をGASで取得してDiscordに発信するbot

作りたいと思います。


必要な材料

  • Googleアカウント
  • Discordアカウント
  • Discordのノリにそれなりについていける心

好きなシートを作るんだ

好きなシートを作りましょう。

A1セルに好きな言葉も入れておきましょう。

ちなみに私葛の葉って名前だけど、これ元は雌の狐の名前なので

よーく考えたら男なのに女性の名前使ってましたね。

まぁ…いいか…

f:id:Kuzunoha-NE:20180720194400p:plain

スクリプトエディタ起動

右上に[ツール]タブがあって、そのメニューにスクリプトエディタっていうのがありますので

クリックすると別画面が開いて、それがスクリプトエディタが表示されます。

f:id:Kuzunoha-NE:20180720194810p:plain

こんな画面がスクリプトエディタです。

f:id:Kuzunoha-NE:20180720195159p:plain


DiscordのWebhookを起動

botとして出力させたいDiscordのチャンネルで歯車のボタンを押します。

f:id:Kuzunoha-NE:20180720195519p:plain

そこから画面左側の[Webhooks][Webhooks作成]をクリックします。

出てきた画面には好きなbotの名前やアイコンを設定して保存しましょう。

f:id:Kuzunoha-NE:20180720200655p:plain

そうしたら画面右側に作ったbotが表示されていると思うので[編集]を押します。

さっきbotを作った画面に似たようなものが出てきますが、その下にスクロールすると

URL[画面の赤い四角部分]が表示されていますので、これをコピーします。

f:id:Kuzunoha-NE:20180720201250p:plain

コピーした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です。

f:id:Kuzunoha-NE:20180720204152p:plain

そしたら、葛の葉ってメッセージが#generalに表示されるはず!


A1の値を変えてもいいですし、sheet.getRange(1,1)(1,1)の値を変えてみるのも面白いですよ!

Pythonで1から6の数字出すDiscordbot作ったよの巻

PythonでDiscordbot作ったよの巻

こんばんは、葛の葉です。

なんかDiscordっていうチャットアプリがあるんですよ、知ってますか?

discordapp.com

ゲームで使う用のボイスチャットアプリなんですけど、普通にチャットするだけでもずいぶん使えるんですよね。

そのDiscordにbotを追加することができるんです。


pipでモジュールを追加

pipでdiscordのbot用のモジュールを追加します。

pip install discord.py

discord用のモジュールの追加はこんな感じ。

他にも

pip install asyncioとかも必要かもしれない。(僕は使ったことないのに入ってたけどね)


公式サイトからトークンを取得

discordapp.com

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の値を返してくれるぞ!!!!

f:id:Kuzunoha-NE:20180712203051j:plain

色々と改造して遊ぼうかな。

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ネーム]5pingを打つ。

ping -c 5 lion
ping -c 5 albatross

どっちのcontainerに入っていても、pingが通るはずです!