API ってなんぞや？？

# APIとはいったい？？

> APIは、アプリケーションプログラミングインタフェース（API、英: Application Programming Interface）の略です！
by:「いまさら聞けない！APIとは何か？〜基礎の基礎を学ぼう〜」

と言われたところで、はっきり言って「なんやねん！」というところでしょう笑


こんにちは、しんちゃんです！今回はAPIが何で、何のために存在するのか？ということについて、わかりやすく（個人差）解説できればと思います。


###API
APIは簡単にいうと**「俺の作った便利な道具をみんなも使えるようにしてやる」**という試みになります。
よく「アプリケーションの連携をします」というものがありますが、あれがAPIの機能になります。

自身のソフトウェアをWEB上で公開することで、他の人もそのソフトウェアの機能の一部を利用することが可能になります。
スマートフォンを作った人が、街中にスマホを置いて**電話する機能だけ無料で使ってええよ？**って言ってる感じです。（余計わかりにくくなりましたか？笑）

有名なところで言えば「リクルート」が提供している「Talk API」（りんなちゃん）でしたり、Livedoorの「お天気API」などでしょうか。


###APIは何に役立つのか？？

APIは一体何に役立つのでしょうか？？

世の中にはたくさんのモノ・サービスがありますが、全てを1から10まで作っていたら手間暇がものすごいかかってしまいますよね？(人間国宝の「うつわ」など1から作ることで大きな価値が生じるものもあります。)

しかし、プログラミングはコードという目に見えない部分です。**誰がコーディングしても結局は同じですよね？**

誰かが一回作った機能を使ってしまえば、使うときの感覚は一緒です！ ならば、「時間の短縮」で「エラーが起きにくい」洗練されたものを使った方がいいですよね。

**今あるものを上手に使って「さらに新しいスゴイもの」を作ることができる！**というのがAPIのスゴイところです！


##APIを使ってみる

では、APIというものがなんとなくわかったところで、APIを実際に使いながらその特徴を学んでいくことにしましょう。

今回は上記のLivedoorの「お天気webサービス」を使って天気の情報を習得してみます！
まずは、モジュールのimportからです。（わからない方は、これを打ち込んでくれれば大丈夫です！）

```python
import requests
import json
from pprint import pprint
```
requestsはHTTPを扱うためのライブラリ
jsonはjsonファイルの読み込み・書き込みを行うためのライブラリ
pprintはデータ構造を見やすい形で出力するライブラリです
(ライブラリについては別枠で)

今回はlivedoorの「お天気webサービス」を使うので
そのサービスを使うためにHTTPを扱うrequestを用いて行きましょう。
今回リクエストを送る際のベースとなるURLはこれです。
http://weather.livedoor.com/forecast/webservice/json/v1

このURLの後ろに市の情報を記載して（JSONの）データを取得します。

###requestsライブラリ
```python
requests.メソッド('URL', params={'key1': 'value1', 'key2':'value2'})
```
requestsは、このようにして使います。
requestsというライブラリを使ってgetメソッドを使い上記のURLからお天気データを引っ張ってきます。

以下のように書いてみましょう！

```python
import requests
import json
from pprint import pprint

response = requests.get('http://weather.livedoor.com/forecast/webservice/json/v1', params={'city': '140020'})
```

もっとわかりやすく書くと

```python
import requests
import json
from pprint import pprint

odawara = {'city': '140020'}
response = requests.get('http://weather.livedoor.com/forecast/webservice/json/v1', params=odawara)
```
となります。responseというのは変数の名前なので気にしなくても大丈夫です。
getメソッド（メソッドについては別で）を用いて
小田原市のお天気データにアクセスすることができます。

上記データの

```python
params={'city': '140020'}
```
の部分ですが、これを「キー・バリュー・ストア」といい、Key1にキーワード、value1にそのバリュー（値など）を入れることで
数あるデータを整理することが楽になります。
レポートなどのデータをそれぞれのファイルにいれて整理するイメージですね！

##JSONデータ⇔辞書型に変換

読みこんだJSON（文字列）データを辞書型に変換します。
変換するには次のような手順を踏みます。

###JSON➡︎辞書型
1.JSONをインポート(一番最初にしたので、やらなくて大丈夫です）
2.「json.loads()」で辞書型化

```python
import requests
import json
from pprint import pprint

odawara = {'city': '140020'}
response = requests.get('http://weather.livedoor.com/forecast/webservice/json/v1', params=odawara)
weather_data = json.loads(response.text)


>>>type(response)
str

>>>type(weather_data)
dict
```



逆に
###辞書型➡︎JSON
1.JSONをインポート(一番最初にしたので、やらなくて大丈夫です）
2.「json.dumps()」で文字列化

でできる。

##実際に出力してみる
では、早速jupyter notebookなり、terminal(vim)なりで、

```python
import requests
import json
from pprint import pprint

odawara = {'city': '140020'}
response = requests.get('http://weather.livedoor.com/forecast/webservice/json/v1', params=odawara)
weather_data = json.loads(response.text)

pprint(weather_data)
```

を実行してみよう。

次のように出力されたのではないだろうか？

> 
{'copyright': {'image': {'height': 26,
                         'link': 'http://weather.livedoor.com/',
                         'title': 'livedoor 天気情報',
                         'url': 'http://weather.livedoor.com/img/cmn/livedoor.gif',
                         'width': 118},
               'link': 'http://weather.livedoor.com/',
               'provider': [{'link': 'http://tenki.jp/', 'name': '日本気象協会'}],
               'title': '(C) LINE Corporation'},
 'description': {'publicTime': '2019-10-05T10:37:00+0900',
                 'text': ' 大陸の高気圧が東シナ海から西日本に張り出しています。\n'
                         '\n'
                         ' 神奈川県は、晴れています。\n'
                         '\n'
                         ' '
                         '5日は、大陸の高気圧が本州付近に張り出すため晴れますが、湿った空気の影響により、夜は曇りとなるでしょう。なお、神奈川県では高温が予想されるため、熱中症など健康管理に注意してください。\n'
                         '\n'
                         ' 6日は、低気圧や湿った空気の影響により、曇りで夜は雨の降る所がある見込みです。\n'
                         '\n'
                         ' 神奈川県の海上では、5日から6日にかけて、多少波があるでしょう。'},
 'forecasts': [{'date': '2019-10-05',
                'dateLabel': '今日',
                'image': {'height': 31,
                          'title': '晴のち曇',
                          'url': 'http://weather.livedoor.com/img/icon/5.gif',
                          'width': 50},
                'telop': '晴のち曇',
                'temperature': {'max': {'celsius': '30', 'fahrenheit': '86.0'},
                                'min': None}},
               {'date': '2019-10-06',
                'dateLabel': '明日',
                'image': {'height': 31,
                          'title': '曇り',
                          'url': 'http://weather.livedoor.com/img/icon/8.gif',
                          'width': 50},
                'telop': '曇り',
                'temperature': {'max': {'celsius': '26', 'fahrenheit': '78.8'},
                                'min': {'celsius': '20',
                                        'fahrenheit': '68.0'}}},
               {'date': '2019-10-07',
                'dateLabel': '明後日',
                'image': {'height': 31,
                          'title': '曇時々雨',
                          'url': 'http://weather.livedoor.com/img/icon/10.gif',
                          'width': 50},
                'telop': '曇時々雨',
                'temperature': {'max': None, 'min': None}}],
 'link': 'http://weather.livedoor.com/area/forecast/140020',
 'location': {'area': '関東', 'city': '小田原', 'prefecture': '神奈川県'},
 'pinpointLocations': [{'link': 'http://weather.livedoor.com/area/forecast/1415000',
                        'name': '相模原市'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1415011',
                        'name': '相模原市西部'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1415012',
                        'name': '相模原市東部'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1420600',
                        'name': '小田原市'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1421100',
                        'name': '秦野市'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1421200',
                        'name': '厚木市'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1421400',
                        'name': '伊勢原市'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1421700',
                        'name': '南足柄市'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1436100',
                        'name': '中井町'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1436200',
                        'name': '大井町'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1436300',
                        'name': '松田町'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1436400',
                        'name': '山北町'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1436600',
                        'name': '開成町'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1438200',
                        'name': '箱根町'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1438300',
                        'name': '真鶴町'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1438400',
                        'name': '湯河原町'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1440100',
                        'name': '愛川町'},
                       {'link': 'http://weather.livedoor.com/area/forecast/1440200',
                        'name': '清川村'}],
 'publicTime': '2019-10-05T11:00:00+0900',
 'title': '神奈川県 小田原 の天気'}

---

ひゃー、欲しい情報は一体何処へ？？？？

ということで、以下にlivedoorのページにより公開されている出力の構成を貼っておきます。
[livedoorお天気webサービスはこれ](http://weather.livedoor.com/weather_hacks/webservice)

<img width="641" alt="livedoorお天気webサービスプロパティ1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485454/feffcd2a-1ec9-4c44-3eb9-5584bf261902.png">
<img width="639" alt="livedoorお天気webサービスプロパティ2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485454/68437a8f-74de-96b2-0409-56d6cf9f8f42.png">

プロパティに関しては順不同なので、辞書型のprint出力を行えば欲しいデータが得られるはず！

つまり、小田原市の今日の天気が欲しければ

```python
import requests
import json
from pprint import pprint

odawara = {'city': '140020'}
response = requests.get('http://weather.livedoor.com/forecast/webservice/json/v1', params=odawara)
weather_data = json.loads(response.text)

print(weather_data['forecasts'][0]['telop'])
```
とすればいいですね。

というわけで！今回はlivedoorのお天気APIを実際に使ってみてAPIの素晴らしさを理解できたのではないでしょうか？？


ん？

はい？

まだ？


最後のprint(weather_data['forecasts'][0]['telop']) がわからない？

print(weather_data['forecasts']['telop']) じゃないのか？
「listなんちゃらsliceなんちゃらstrなんちゃら」のエラーが出た？？

もう少し説明が必要ですか？

では、最後の部分について少しだけ補足しますね。

上の画像から分かるように今回はforecastsのプロパティ内部のtelopの情報が欲しいのです！
そのためには引っ張ってききたデータ（JOSNから辞書型に変えたもの）から、欲しい情報を選択する必要があります。

次のようにコードを打ってみましょう。

```python
import requests
import json
from pprint import pprint

odawara = {'city': '140020'}
response = requests.get('http://weather.livedoor.com/forecast/webservice/json/v1', params=odawara)
weather_data = json.loads(response.text)

print(weather_data['forecasts'])
```

出力は次のようになりませんか？（意図的に改行しているので本当は一連になっているはずです。）

>[**{'dateLabel': '今日', 'telop': '晴のち曇', 'date': '2019-10-05', 'temperature': {'min': None, 'max': {'celsius': '30', 'fahrenheit': '86.0'}}, 'image': {'width': 50, 'url': 'http://weather.livedoor.com/img/icon/5.gif', 'title': '晴のち曇', 'height': 31}}** , 
>
**{'dateLabel': '明日', 'telop': '曇り', 'date': '2019-10-06', 'temperature': {'min': {'celsius': '20', 'fahrenheit': '68.0'}, 'max': {'celsius': '26', 'fahrenheit': '78.8'}}, 'image': {'width': 50, 'url': 'http://weather.livedoor.com/img/icon/8.gif', 'title': '曇り', 'height': 31}}**, 
>
**{'dateLabel': '明後日', 'telop': '曇時々雨', 'date': '2019-10-07', 'temperature': {'min': None, 'max': None}, 'image': {'width': 50, 'url': 'http://weather.livedoor.com/img/icon/10.gif', 'title': '曇時々雨', 'height': 31}}**]

この改行した部分をそれぞれみるとforecastsのプロパティ内にリストが3つあるのがわかりますか？（'dataLabel'から始まる{}で囲まれた塊です。）
つまり、この塊一つ一つがリストなっているのです。であれば、リストのインデックスを指定する必要がありますよね？？

問題は『dateLabelが今日』のデータが欲しいので、インデックスは[0]を指定してその中のtelopを引っ張ってくればいいのです。
意外と細かいところでつまづくことが多いのでしっかりおさえていきましょう。

では、今回はここで終了です！！
次はリクルートの Talk API を使いこなしてりんなちゃん（LINEbot）を作ってみましょう。

なお細かい部分の質問は
→Twitter(最近作ったので):[@shinchan_tlpu](https://twitter.com/shinchan_tlpu)
→mail : shinchan.tlpu@gmail.com
にご連絡いただけると対応できます。

では、また次回にお会いしましょう。

***練習問題***
1.那覇市の明日の天気を出力してください。(他県のIDはwebお天気サービスページに記載されています。→[livedoorお天webサービスはこれ](http://weather.livedoor.com/weather_hacks/webservice))


2.横浜市の今日の最高気温を摂氏・華氏でそれぞれ出力してください。出力には「摂氏31°C」「華氏87.8°F」など正規の表記がされるようにしてください。


***答え***
1.

```python
import requests
import json
from pprint import pprint

naha = {'city': '471010'}
response = requests.get('http://weather.livedoor.com/forecast/webservice/json/v1', params=naha)
weather_data = json.loads(response.text)

print(weather_data['forecasts'][0]['telop'])
```


2.

```python
import requests
import json
from pprint import pprint

yokohama = {'city': '140010'}
response = requests.get('http://weather.livedoor.com/forecast/webservice/json/v1', params=yokohama)
weather_data = json.loads(response.text)

print('摂氏' +weather_data['forecasts'][0]['temperature']['max']['celsius'] +'℃')
print('華氏' +weather_data['forecasts'][0]['temperature']['max']['fahrenheit'] +'F')
```