FastAPIの使い方(Python初心者やプログラミング初心者におすすめ)

# FastAPIとは
***Pythonのフレームワークで、高速でAPIを構築するためのフレームワーク***です。

# 参考動画

https://www.youtube.com/watch?v=vVNCVgYb6Xw

### Pythonのバージョン
Python3のバージョンです。

# 特徴
- 初学者向けのフレームワーク
- わかりやすい書き方
- 公式ドキュメントが豊富
- 自動ドキュメントを作る機能(Swaggerと連携取れている)
- バリデーション機能の実装簡単
- 型安全
- 高速

***初学者がPythonのAPI開発ならFastAPIがベスト***です。

発展的に学ぶ場合は以下のことを知っているといいみたいです。

タイプヒントを用いたバリデーション、非同期処理、オリジン間リソース共有(CORS)、GraphQL、WebSocketsなどです。

# Flaskと似ている
Flaskと書き方が似ているので、やったことある方はやりやすいと思います。

# python3.5から導入された型ヒント(type hints)
FastAPIの型ヒント（type hints）は、関数の引数と戻り値のデータ型を指定するためのPythonの注釈機能です。
まずは簡単に消費税から計算します。

```type_hints.py
# 型ヒント
price:int = 1000
tax:float = 1.1

def calc_price_including_tax(price:int,tax:float) -> int:
    return int(price*tax)

if __name__ == '__main__':
    print(f'{calc_price_including_tax(price=price,tax=tax)}円')

# 1100円と出力
```
ここで注意点で、型ヒントは注釈に過ぎないので、以下のように間違えた実装してもエラーにならないです。
```type_hints.py
# 型ヒント
price:int = 1000.1
tax:float = 10

def calc_price_including_tax(price:int,tax:float) -> int:
    return int(price*tax)

if __name__ == '__main__':
    print(f'{calc_price_including_tax(price=price,tax=tax)}円')

# 10001円
```

# ライブラリインストール
仮想環境を使用してFastAPIをインストールします。
- ***FastAPIのインストール***
仮想環境がアクティブな状態でFastAPIとUvicornをインストール。
```
pip install fastapi uvicorn
```

# FastAPI起動
まずは下のコードを見てください。
```main.py
from fastapi import FastAPI

app = FastAPI()#インスタンス化

@app.get("/")#ルーティング　@はdecorator
async def index():
    return {"message":"FastAPIだぞ"}
```
上のコメントでインスタンス化とルーティングを実装します。そしてFastAPIを起動します。
```
uvicorn main:app --reload
```
http://127.0.0.1:8000にアクセスすると

![スクリーンショット 2024-07-22 18.15.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/074e22e3-d877-9810-4af6-cadba831ba13.png)

***get("/")を使うことで、下の関数が処理***されます。

# APIドキュメントの自動生成(SwaggerUIの生成)
以下がSwaggerの説明です。

https://qiita.com/Hashimoto-Noriaki/items/8695e6c290519f3d7670

- ```公式ドキュメント```

https://swagger.io/docs/

- ```SwaggerUI```

https://swagger.io/tools/swagger-ui/


以下の記事を見ればどんな感じかわかると思います。***APIの仕様書を可視化***してくれます。

https://petstore.swagger.io/?_gl=1*1ozbne2*_gcl_au*MTAzMTY3NDQ2Mi4xNzIxNjQwMjQ5&_ga=2.256696139.1590731265.1721640244-2106335002.1721640244

***FastAPIでは、これを自動生成***してくれます。
サーバーを起動した状態で、```http://127.0.0.1:8000/docs```で確認すると以下のように出てきます。

![スクリーンショット 2024-07-22 18.31.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/0cdc9fb2-6509-f785-0eae-759b7e3d2524.png)

次に```http://127.0.0.1:8000/redoc```としてみましょう。
Swaggerのフォーマットを生成してくれています。

![スクリーンショット 2024-07-22 18.33.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/9d6baf86-8164-be52-0121-5703eafe3d30.png)

# パスパラメーター
ルーティングの設定で思ってもらえればいいです。

```main.py
from fastapi import FastAPI

app = FastAPI()#インスタンス化

@app.get("/greeting")#ルーティングを変更
async def index():
    return {"message":"FastAPIだぞ"}
```
そうすると```http://127.0.0.1:8000/greeting```で表示されます。

![スクリーンショット 2024-07-22 18.43.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/1fabe697-668d-c406-8ed3-8e5f09c76e73.png)

ルーティングも変更してみていきます。

```main.py
from fastapi import FastAPI

app = FastAPI()#インスタンス化

@app.get("/countries/{country_name}")#ルーティング　@はdecorator
async def country(country_name):
    return {"country_name":country_name}
```
サーバーを起動すると以下のようになります。"/countries/{country_name}のcountry_nameはAmericaにしてもbaseballにしても使えます。

![スクリーンショット 2024-07-22 23.07.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/37d7faa8-a2e2-7198-802b-af69bfa48364.png)

```main.py
from fastapi import FastAPI

app = FastAPI()#インスタンス化

@app.get("/countries/{country_name}")#ルーティング　@はdecorator
async def country(country_name:int):#int追記
    return {"country_name":country_name}

```
引数にintを追記しました。すると以下のように設定するといいです。

![スクリーンショット 2024-07-22 23.10.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/ae7b071c-72db-59c3-0c7c-97c1067d4737.png)

先ほどのSwaggerUIを確認してみます。
http://127.0.0.1:8000/docs
で調べてみました。

![スクリーンショット 2024-07-22 23.11.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/d8e30d11-6ddc-f49d-756e-27afbd5f13b1.png)

![スクリーンショット 2024-07-22 23.12.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/272762b9-bace-3bcf-2338-511b38d6b7f7.png)

このように追記したりしました。ここでエラーなど確認できたりします。
型ヒントをベースにして、ドキュメントを作ってくれます。
RailsとNext.jsの開発だとSwaggerを組んだりしないといけないので、大変なんですね。😅
FastAPIすげーと思いました。😀

### 処理の順番
プログラムは、上から順番に処理がされます。

```main.py
from fastapi import FastAPI

app = FastAPI()#インスタンス化

@app.get("/countries/japan")#ルーティング追記
async def country():
    return {"message":'日本だー'}

@app.get("/countries/{country_name}")#ルーティング　@はdecorator
async def country(country_name:str):
    return {"country_name":country_name}
```
ルーティングをhttp://127.0.0.1:8000/countries/japan
になると、下のようになりますが、
![スクリーンショット 2024-07-24 1.06.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/40c45278-c5ae-8556-600b-8d87b43b045d.png)

処理を逆にすると、

![スクリーンショット 2024-07-24 1.07.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/58b9b2c9-609c-3615-e288-bde1d9639b68.png)

入れ替えたのは、下の感じです。
```main.py
from fastapi import FastAPI

app = FastAPI()#インスタンス化

@app.get("/countries/{country_name}")#ルーティング　@はdecorator
async def country(country_name:str):
    return {"country_name":country_name}

@app.get("/countries/japan")#ルーティング　@はdecorator
async def country():
    return {"message":'日本だー'}
```

# クエリパラメーター
***パスパラメーターはないけど、引数が設定されているのがクエリパラメーター***です。
```main.py
# クエリパラメーター
@app.get("/countries/")#ルーティング　@はdecorator
async def country(country_name: str = 'japan',country_no: int =1)
    return {
        "country_name": country_name,
        "country_no": country_no
    }

```
URLをhttp://127.0.0.1:8000/countries/?country_name=England&country_no=3
で実行したら以下のように表示されます。

![スクリーンショット 2024-07-24 1.51.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/482bce13-0566-517b-9308-d2423c5a65ea.png)

country_nameとcountry_noは任意で、変えられます。

# クエリパラメーターとパスパラメーターの組み合わせ
```main.py
from fastapi import FastAPI

app = FastAPI()#インスタンス化

# クエリパラメーター
country_nameからcity_nameに変えます。

@app.get("/countries/{country_name}")#ルーティング　@はdecorator
async def country(country_name: str = 'japan',city_name: str = 'Tokyo'):#パスパラメーターはないけど、引数が設定されているのがクエリパラメーター
    return {
        "country_name": country_name,
        "city_name": city_name
    }
```

![スクリーンショット 2024-07-24 2.01.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/39aeb138-e408-e9cf-2460-040541ce8cb0.png)


country_nameを日本からイギリスに変えてみます。
http://127.0.0.1:8000/countries/england?city_name=London

![スクリーンショット 2024-07-24 2.04.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/50e184ef-1407-a853-8f99-3109d363eecc.png)


# おすすめUdemy
本格的に学びたい場合はこの参考動画の方のUdemyをご覧ください。


https://www.udemy.com/course/python-fastapi/?couponCode=KEEPLEARNING


# 公式ドキュメント

https://fastapi.tiangolo.com/ja/

# 資料

https://zenn.dev/sh0nk/books/537bb028709ab9/viewer/f1b6fc