Bottleで学ぶクライアントとサーバーのやりとり

# Introduction

## きっかけ
Brython習得が徒労に終わったので、BottleというPythonフレームワークを用いたWebアプリケーション作成を始めました。

Brython奮闘記に関しては[こちら](https://qiita.com/Senple/items/f5ccb083d0cf7c997d3d)
※今回の記事とはまったく関係ありません。

クライアントとサーバーの間でのGETやPOSTの仕組みがさっぱりわからなかったので、調べながら作成したものを書き記しておきます。おそらくものすごい初歩的な内容なのでコンピュータサイエンスを学んでいる人は読む必要がないと思います。~~むしろきちんとした知識があるお兄さん方[^1]は教えてください~~



## 自己紹介
![smile.jpg](https://qiita-image-store.s3.amazonaws.com/0/262742/71ecb16a-0d75-8c36-9324-43303d7fc2a7.jpeg)

[自己紹介ページ](https://qiita.com/Senple/items/b47374e68e4d8d26d0cb)

```
環境情報
Python 3.6.5 |Anaconda, Inc.|
Windows10
```



### 対象者
・Python3系を使っているユーザー(Anacondaでインストール)
・クライアントとサーバーの意味を理解している人
・プログラミングをフィーリングで学んでいる人(僕も同じです！)
・1を聞いて10を理解できるエンジニア
・**Windows**の人

### 非対象者
・Python2系を使っているユーザー
・クライアント？サーバー？何それおいしいの？状態な人
・コンピュータサイエンスを学んだ(or学んでいる)ひと
・説明下手な筆者を攻撃しようとするエンジニア
・**Mac**の人

Cf.)Python2系とかPython3系の意味が分からない人へ！
Pythonには2系と3系があって、最近始めた人ならほとんどPython3系だと思います。一応バージョンを確認する方法を記載しておきます。
コマンドプロンプトでPythonのインタラクティブ(対話)モードを起動すればバージョン情報が表示されます。

```
$ Python
>Python 3.6.5 |Anaconda, Inc.| (default, Mar 29 2018, 13:32:41) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
インタラクティブモードを辞めるには*exit()*を入力しましょう！



# Let's Start
Bootleに関しては、[参照サイト](https://qiita.com/masaibar/items/e3b6911aee6741037549)をもとに学びました。しかし参照サイトのほうでは、クライアント側については全く説明されておらず、僕はよくわからなかったので、本記事ではクライアント・サーバーでのやりとりについてもまとめます。

クライアント側とサーバー側をきちんと知りたい方は[こちら](https://qiita.com/shuntaro_tamura/items/ae55b99deb9e2a170754)


### クライアント側
クライアント側はHTMLやCSS、JavaScriptで記述されたWebページです。

```html:Semple.html
<!DOCTYPE html>
<html lang="ja">
 <head>
    <meta charset="UTF-8">
    <title>Semple'page</title>
   </head>
 <body>
    <p>Hello,Semple!</p>
   </body>
</html>
```
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/262742/51897d3d-37ff-ac44-5181-7365621c7908.png)


上記のコードでは、まぁこんな画面がwebページに広がると思います。
こうやってwebページに表示されるのがクライアント側ですね。

### サーバー側
まずは、Bottleをインストールして、作業用ディレクトリへbottle.pyを移動しましょう。

```
pip install bottle
```

```作業用ディレクトリ.md
Bottle.py
Semple.py
Semple.html
```

Bottle.pyはインストールしたものをそのままディレクトリを変えます。
Semple.htmlは上記のファイルをコピペしてください。

Semple.pyは今から説明します。[参照サイト](https://qiita.com/masaibar/items/e3b6911aee6741037549#%E3%81%A8%E3%82%8A%E3%81%82%E3%81%88%E3%81%9A%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B)をほぼコピペしてますが、以下の通りです。

```Python:Semple.py
# -*- coding:utf-8 -*-
from bottle import route, run, template


@route('/hello')
def hello():
    return template("Semple.html")

run(host='localhost', port=8080, debug=True)
```

上記のファイルを作成します。
コマンドライン上で、実行します。

```
python Semple.py
```
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/262742/2910bd4d-4897-9395-8f5f-3a1439d35cdb.png)


まぁクライアント側と同じように表示されます。
bottleを用いればPythonユーザーでも気軽にWebアプリケーションを作成できます。

# GETとPOSTについて
ここからが本題です。BottleによってPythonでの処理がクライアント側に表示されると思っていた僕は悩みました。クライアント側の値をサーバー側へ送信(Request)してクライアント側へどのように送り返す(Response)のか。
技術的な話は[こちら](https://qiita.com/tomotaka_ito/items/62fc4d58d1be7867a158)

クライアント側で設定した値をサーバー側で受け取り、サーバー側で処理してクライアント側へ効率よく戻したいのですが、まとまっている記事はなかったので自分でまとめようと思いました。~~あったら紹介してください！~~
参考ページは[こちら](https://qiita.com/yamao2253/items/e518048b9bbfe58ffa52)

```Python:Semple.py
# -*- coding:utf-8 -*-
from bottle import route, run, template, request, response

@route('/hello')
def hello():
    return template("Semple.html")

@route('/talk', method="GET")
def talk():
    content_id = int(request.query.country)
    translate_list = ["Japan","Australia","Bangladesh","China","Philippine"]
    content = translate_list[content_id]
    return "<p>{}</p>".format(content)

```


```html:Semple.html
<!DOCTYPE html>
<html lang="ja">
 <head>
    <meta charset="UTF-8">
    <title>Semple'page</title>
   </head>
 <body>
    <form id="test" method="GET" name="Semple" action="/talk">
    <label>国を選択してください：</label>
      <select id="number" name="country">
        <option value="0">日本</option>
        <option value="1">オーストラリア</opiton>
        <option value="2">バングラデシュ</option>
        <option value="3">中国</option>
        <option value="4">フィリピン</option>
       </select>
       <input type="submit" value="英語.ver" />
     </form>
   </body>
</html>
```

![キャプチャ1.PNG](https://qiita-image-store.s3.amazonaws.com/0/262742/101b6677-4724-7189-9838-5044f0358cf4.png)

実行すると画面が以下のように遷移します。

![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/262742/11ecf8ae-1d48-476c-ef8d-e37667679917.png)

クライアント(HTMLファイル)側で取得した値(request.query.country)をサーバー(Pythonファイル)側で「content_id」という変数で受け取っています。
「content_id」は取得した値に応じて遷移後の画面が変わります。
本来なら一枚目の「国を選択してください」の下あたりに英語.verを表示させたいのですが、そういった処理になるともう少し複雑になります。
自分のやりたい上記の処理が「複雑になる」ということ自体が判らなかったので、備忘録として書きのこしておきます。~~意味が分からず一日調べ続けました~~




## Future Work
画面を遷移させずに、変更点を反映させたい場合はもう少し難しい実装になりますが、Ajaxや動的ページの生成が必要となります。
絶賛勉強中ですが、少しずつWebアプリケーションがわかってきました。
[Ajax+Bottle](https://www.slideshare.net/satoshiyamada71697/bottlepy)


## 参考ページ
[Bottleの日本語ドキュメント](https://bottl-translate-ja.readthedocs.io/en/latest/01_1_tutorial.html#id5)
[Bottleの英語ドキュメント](https://bottlepy.org/docs/dev/tutorial.html#request-routing)
[HTMLのinput属性解説](http://www.htmq.com/html5/input.shtml)

[^1]: もちろんお姉さんでも可