Pythonで湧き水APIを触ってみる＋LambdaでAPIを自作してみる

# はじめに
インターネット上でデータをやり取りする際、APIは非常に便利なツールです。
APIを利用することで、さまざまなデータにアクセスしたり、サービスを実行したりすることができます。
しかし、「APIを自分で使うにはどうすればいいの？」と疑問を持つ方も多いかもしれません。

本記事では、APIの基本的な概念から始め、自分でAPIを実行し、その応答を確認する方法を紹介します。

前半でAPIとは何かを説明した上で、Pythonを使って実際にAPIを呼び出し、データを取得する体験をしてみましょう。
そして後半では、AWS Lambdaを使用して自分で関数(API)を作成しLambda上でのテストとVScodeを使用してPythonで自作API呼び出しまでを行います。

<br>
この記事は以下のような人におすすめです。

- APIを実行する方法が知りたい
- AWS Lambdaを使用した関数作成の方法が知りたい


# 記事の構成

**【前半】**
APIとは何か？というところから湧き水APIを呼び出して応答を確認するところまでを行います。
1. APIって何？
1. 湧き水APIとは？
1. APIの取得方法
1. 湧き水APIをPythonで実行してみる

**【後半】**
前半でAPIを使用した体験を元に、今度は自作APIを作成し、Pythonで実行するところまでを行います。
API作成にはAWS Lambdaを使用します。
1. AWS Lambdaとは？
1. Lambdaで関数を作成
1. デフォルトのコードを書き換える
1. テストコードを実行する
1. 関数URLから応答を確認する
1. 自作APIをPythonで実行してみる


# 【前半】Pythonで湧き水APIを実行してみる
### 使用環境
OS：Windows 11
Pythonバージョン：3.12.6
使用ライブラリ：requests、dotenv

インストールされていないライブラリがある場合は下記コマンドを実行しインストールを行なってください。
```
pip install requests
pip install python-dotenv
```

<br>

- **APIとは？**


APIとは「Application Programming Interface」の略で、ソフトウェアやサービス間でデータやコマンドをやり取りするための仕組みです。

APIは、異なるプログラムやサービス間の通訳や橋渡しの役割を果たします。
特定のルール（プロトコル）に従ってリクエストを送り、必要なデータを受け取ります。

開発者はこの仕組みを利用することで、一から複雑な機能を作る必要がなく、既存のサービスの機能を自分のアプリに組み込むことができます。
無料のものから有料のものまで様々なAPIが公開されています。
<br>



- **湧き水APIとは？**

下記サイトで公開されている「湧き水検索」というAPIのことで、
全国の湧き水の場所をJSON形式で返してくれます。

https://tabi2api.docs.apiary.io/#introduction



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/434b0bbd-b9a2-d48c-938a-e01938d7aa06.png)


- **湧き水APIの取得方法**


旅々APIに載っているAPIを使用するためにはリブログアカウントの登録が必要なので、下記サイトからアカウントの新規登録を行います。

https://livlog.xyz/sso/login


ログインしたら、画像のAPIページにアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/4e98fdc4-9a55-f34b-f8b0-2aacdfd1dd48.png)

**トークンを生成**をクリックし、APIトークンを発行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/72d4b154-74c0-94a6-da24-34313353edf3.png)

:::note alert
**APIトークンの取り扱いについて**
**絶対に他の人にトークンが漏れないように管理してください。**
**流出すると、APIが不正利用されてしまいます。**
:::
<br>

- **実際にPythonで実行してみる**

まず、湧き水検索の一覧取得をクリックしてGETの部分をコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/eed378e9-a349-80c5-2d47-f2962a9423aa.png)


次にこのコードをPythonに変換します。
生成AIに「これをPythonで実行できるようにして」とコードと一緒に質問を投げます。

今回は以下のコードが生成されました。
愛知県に絞って湧き水の場所を標示してくれます。

```python:wakimizu.py
import os
import requests
import json
from dotenv import load_dotenv

# .envファイルから環境変数を読み込む
load_dotenv()

# APIのURL
url = "https://app.livlog.xyz/webapi/v2/spring-water/list"

# パラメータの設定
params = {
    "pref": "愛知県"  # エンコード済みのパラメータ
}

# 環境変数からトークンを取得
api_token = os.getenv("API_TOKEN")

# ヘッダーの設定
headers = {
    "Accept": "application/json",
    "Authorization": f"Bearer {api_token}"  # トークンが必要な場合
}

try:
    # APIリクエストの送信
    response = requests.get(url, params=params, headers=headers)

    # ステータスコードの確認
    if response.status_code == 200:
        # JSONデータの取得
        data = response.json()
        
        # 結果の表示
        print(json.dumps(data, indent=2, ensure_ascii=False))
    else:
        print(f"エラー: ステータスコード {response.status_code}")
        print(response.text)

except requests.exceptions.RequestException as e:
    print(f"リクエストエラー: {e}")
```

<br>

コードの中で環境変数からトークンを取得してくる部分があります。
```Python:wakimizu.py
# 環境変数からトークンを取得
api_token = os.getenv("API_TOKEN")
```
今回は同じフォルダ内に **.env** というファイルを作成してトークンを取得できるようにしましょう。
<br>

**.envファイル**とは、データベースのパスワードやAPIキーなど、アプリケーションの動作に必要な**秘密の情報を含んでいるファイル**です。
このファイルを使うことで、環境変数をまとめて管理できるようになります。

通常、環境変数はOSに設定する必要がありますが、.envファイルを使えば、OSの設定に頼らず、アプリケーションが起動時にこのファイルから必要な変数を読み込んで使用できます。

<br>

今回はwakimizu.pyで、API_TOKENの値を取得すると表記されているので、 .envは以下のような内容にします。

```.env
API_TOKEN = 生成したAPIトークン

```
:::note alert
**GitHubに上げる際の注意点**
.envのように**誰にも見られたくない**ファイルをgitに上げる際は
**.gitignore**でファイルを無視する設定を行うようにしてください。
:::
<br>
<br>
これでAPIを呼び出す準備が整ったので、実行すると…

#### 無事Pythonで湧き水の情報を表示できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/5c48b8c0-b804-fc0f-6ad8-b8a5faf81264.png)


今回は愛知県でしたが、千葉県の湧き水を指定することもできます。

```python:wakimizu.py
# パラメータの設定
params = {
    "pref": "愛知県"  # エンコード済みのパラメータ
    #ここを千葉県に変える
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/86e28ee4-cd56-cbaf-0fd7-8ca26f610967.png)

千葉県の湧き水の場所を表示することができました！


# 【後半】AWS LambdaでAPIを自作してみる
それでは、今度はAPIを自作してみましょう。
今回はAWS Lambdaを使用します。

- **AWS Lambdaとは？**

プログラムを書いて動かすためにサーバーを管理する必要がなく、コードを書けば自動的に実行してくれるAWSサービスです。
たとえば、何かイベント（データがアップロードされたり、ボタンがクリックされたり）が発生したときに、そのイベントに反応してプログラム（Lambda関数）が実行されます。

https://aws.amazon.com/jp/lambda/


- **Lambdaで関数を作成**

まず、AWSコンソールにログインし**Lambda**の関数ページに移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/36a65d21-74b3-8e82-8400-733b39ce0016.png)

関数の作成をクリックし、画像の通り設定を行います。

ランタイム：Python 3.12
アーキテクチャ：arm64

設定ができたら下にスクロールして作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/becf664c-f7c8-b478-fbca-156d24186c7d.png)

これで関数が作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/c90d6fc5-cf6a-2a43-d546-fe9fe1f1bc39.png)




- **デフォルトのコードを書き換えてみる**

コードはデフォルトだと、Hello from Lambda!を返してくれるだけの内容になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/87edeba6-8fb0-8d07-a6bf-7d4dbcdce10a.png)

Lambdaの部分をクエリパラメータから取得した名前になるように変えてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/31715387-7707-7a5a-ba6c-eb7fe3115667.png)

```python:practice_my_api

import json

def lambda_handler(event, context):
    # クエリパラメータから名前を取得
    name = event.get('queryStringParameters', {}).get('name', 'Lambda')
    
    # レスポンスメッセージを作成
    message = f'Hello from {name}!'
    
    # レスポンスを返す
    return {
        'statusCode': 200,
        'body': json.dumps(message)
    }

```


- **テストを作成して、応答をテストする**

テストコードを用いて挙動を確認することが出来ます。

テストタブに移動し、新しいイベントを作成からテストを新規作成します。
今回、名前はtestにして何も変更せず保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/92bffd3d-71cd-3442-a85b-19dd63e9012f.png)

変更を行っていない状態でテストを行い返答を確認してみます。
このコードではnameを指定していないので、Hello from Lambda!が返ってきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/35d3e811-c829-a938-8325-d56501c410e3.png)


テストコードを以下の内容に書き換えます。
クエリパラメータのnameをJohnにするという内容です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/1d548f8b-6ca6-9a3a-b389-1d2aed336ab8.png)

```json:test
{
  "queryStringParameters": {
    "name": "John"
  }
}

```
保存したあとに、テストをクリックします。
詳細▶を開くと、テスト結果が表示されて、応答がJohnに代わっていることを確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/ead26ec0-b2a3-f068-078e-ac5caf4ec402.png)


- **関数URLから応答を確認する**

関数URLから応答を確認します。
まず、設定タブに移動し、関数URLをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/9380bda2-8532-194e-11db-81f50b621369.png)

今回は後ほどPythonで実行するため、認証タイプを NONE にします。
これで世界にAPIを公開することが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/669f4497-2437-6b36-98d7-292c016f62b6.png)

:::note info
**APIの公開範囲について**
APIのセキュリティや用途によって選択してください。
- **AWS_IAM**
**APIを使える人やシステムをIAMユーザーやロールで制限**できます。
つまり、AWSアカウントに登録されているユーザーやサービスだけがAPIにアクセスできるようになります。
- **NONE**
特別なアクセス制限をかけない設定で、**APIに誰でもアクセスできる状態**になります。
APIがインターネット上に公開されていて、アクセスするために特別な認証は必要とされません。
:::


これで関数URLを作成できました。
クリックしてアクセスしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/76a5078c-d528-baa3-ad5f-ad57b7824c3f.png)


応答が返ってきました。
nameのクエリパラメータをこちらで指定していない為、Lambdaのままになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/0efaf203-eaf6-69df-646f-4d33fcea4785.png)


URLを変更してnameに任意の名前を入れてみます。
awsの末尾に　?name=(任意の名前)　を追加します
今回はKCと入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/d33db2b7-82d5-e5d3-581f-b0ce7a1379ad.png)

URLを更新すると"Hello from KC!"と表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/a894388f-6880-5ae7-71e3-bbcee054363b.png)

# 自作APIをPythonで実行してみる
最後に湧き水APIのように自作APIを呼び出してみましょう。

下記のコードを使用します。
nameと定義した変数に値を入れると、nameのクエリパラメータがその値に変更されて表示されます。
今回は、nameをnaitoとします。
```python:hello_lambda.py
import requests

def get_response(name):
        url = f"[自分の関数URL]/?name={name}"
    
    try:
        response = requests.get(url)
        response.raise_for_status()  # エラーがあれば例外を発生させる
        return response.json()
    except requests.RequestException as e:
        return f"エラーが発生しました: {e}"

# 使用例
name = "naito"
result = get_response(name)
print(result)
```

Hello from naito!と返ってきたので、関数の実行は成功です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885031/e28ecce6-e6f6-dbc2-d74d-ad0722c0c8da.png)

# まとめ
本記事ではAPIを使う、作るといったことを行いました。

サーバーレス環境であるLambdaを使うことで、簡単に関数を作成し、呼び出すことができました。
今回はシンプルな関数を作成して呼び出しただけなので、スケーリング機能は活用していませんが、その手軽さがとても印象的でした。

また、今回は「自作して自分で実行してみる」という部分に重点を置いたため、Lambdaの設定は最小限に留めています。
実際に運用する際には、認証やアクセス制限などセキュリティ面の設定を十分に行うことを推奨いたします。


少しでもこの記事が参考になりましたら幸いです。
読んでいただきありがとうございました！