Lewati ke isi

Parameter Path

"parameter" atau "variabel" path didefinisikan dengan sintaksis Python format string:

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id):
    return {"item_id": item_id}

Nilai parameter path item_id akan dikirim ke fungsi sebagai argument item_id:

Jika anda menjalankan contoh berikut dan kunjungi http://127.0.0.1:8000/items/foo, anda akan melihat respon:

{"item_id":"foo"}

Parameter path dengan tipe data

Tipe data parameter path bisa didefinisikan di dalam fungsi, menggunakan anotasi tipe data standar Python:

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id}

Dalam hal ini item_id didefinisikan sebagai int.

Periksa

Penyunting kode anda bisa membantu periksa di dalam fungsi seperti pemeriksaan kesalahan, kelengkapan kode, dll.

Konversi data

Jika contoh berikut dijalankan dan diakses browser melalui http://127.0.0.1:8000/items/3, anda akan melihat respon:

{"item_id":3}

Periksa

Perhatikan nilai fungsi yang diterima (dan dihasilkan) adalah 3, sebagai int di Python, dan bukan string "3".

Sehingga dengan deklarasi tipe data FastAPI memberikan request otomatis "parsing".

Validasi Data

Tetapi jika di browser anda akses http://127.0.0.1:8000/items/foo, anda akan melihat pesan kesalahan HTTP:

{
  "detail": [
    {
      "type": "int_parsing",
      "loc": [
        "path",
        "item_id"
      ],
      "msg": "Input should be a valid integer, unable to parse string as an integer",
      "input": "foo",
      "url": "https://errors.pydantic.dev/2.1/v/int_parsing"
    }
  ]
}

Karena parameter path item_id bernilai "foo" yang bukan tipe data int.

Kesalahan yang sama akan muncul jika menggunakan float daripada int, seperti di: http://127.0.0.1:8000/items/4.2

Periksa

Dengan deklarasi tipe data Python, FastAPI melakukan validasi data.

Perhatikan kesalahan tersebut juga menjelaskan validasi apa yang tidak sesuai.

Validasi ini sangat membantu ketika mengembangkan dan men-debug kode yang berhubungan dengan API anda.

Dokumentasi

Ketika anda membuka browser di http://127.0.0.1:8000/docs, anda melihat dokumentasi API interaktif otomatis berikut:

Periksa

Dengan deklarasi tipe data Python yang sama, FastAPI membuat dokumentasi interaktif otomatis (terintegrasi Swagger UI).

Perhatikan parameter path dideklarasikan sebagai integer.

Keuntungan basis-standar, dokumentasi alternatif

Karena skema yang dibuat berasal dari standar OpenAPI, maka banyak alat lain yang kompatibel.

Sehingga FastAPI menyediakan dokumentasi alternatif (menggunakan ReDoc), yang bisa diakses di http://127.0.0.1:8000/redoc:

Cara yang sama untuk menggunakan tools kompatibel lainnya. Termasuk alat membuat kode otomatis untuk banyak bahasa.

Pydantic

Semua validasi data dikerjakan di belakang layar oleh Pydantic, sehingga anda mendapatkan banyak kemudahan. Anda juga tahu proses ini akan ditangani dengan baik.

Anda bisa mendeklarasikan tipe data dengan str, float, bool dan banyak tipe data kompleks lainnya.

Beberapa tipe di atas akan dibahas pada bab berikutnya tutorial ini.

Urutan berpengaruh

Ketika membuat operasi path, anda bisa menghadapi kondisi dimana path nya sudah tetap.

Seperti /users/me, untuk mendapatkan data user yang sedang aktif.

Kemudian anda bisa memiliki path /users/{user_id} untuk mendapatkan data user tertentu melalui user ID.

karena operasi path dievaluasi melalui urutan, anda harus memastikan path untuk /users/me dideklarasikan sebelum /user/{user_id}:

from fastapi import FastAPI

app = FastAPI()


@app.get("/users/me")
async def read_user_me():
    return {"user_id": "the current user"}


@app.get("/users/{user_id}")
async def read_user(user_id: str):
    return {"user_id": user_id}

Sebaliknya, path /users/{user_id} juga akan sesuai dengan /users/me, "menganggap" menerima parameter user_id dengan nilai "me".

Serupa, anda juga tidak bisa mendefinisikan operasi path:

from fastapi import FastAPI

app = FastAPI()


@app.get("/users")
async def read_users():
    return ["Rick", "Morty"]


@app.get("/users")
async def read_users2():
    return ["Bean", "Elfo"]

Path pertama akan selalu digunakan karena path sesuai dengan yang pertama.

Nilai terdefinisi

Jika ada operasi path yang menerima parameter path, tetapi anda ingin nilai valid parameter path sudah terdefinisi, anda bisa menggunakan standar Python Enum.

Membuat class Enum

Import Enum dan buat sub-class warisan dari str dan Enum.

Dengan warisan dari str dokumen API mengetahui nilai nya harus berjenis string supaya bisa digunakan dengan benar.

Kemudian buat atribut class dengan nilai tetap string yang benar:

from enum import Enum

from fastapi import FastAPI


class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"


app = FastAPI()


@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
    if model_name is ModelName.alexnet:
        return {"model_name": model_name, "message": "Deep Learning FTW!"}

    if model_name.value == "lenet":
        return {"model_name": model_name, "message": "LeCNN all the images"}

    return {"model_name": model_name, "message": "Have some residuals"}

Tips

"AlxexNet", "ResNet", dan "LeNet" adalah nama model Machine Learning.

Mendeklarasikan parameter path

Kemudian buat parameter path dengan tipe anotasi menggunakan class enum dari (ModelName)

from enum import Enum

from fastapi import FastAPI


class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"


app = FastAPI()


@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
    if model_name is ModelName.alexnet:
        return {"model_name": model_name, "message": "Deep Learning FTW!"}

    if model_name.value == "lenet":
        return {"model_name": model_name, "message": "LeCNN all the images"}

    return {"model_name": model_name, "message": "Have some residuals"}

Periksa dokumentasi

Karena nilai yang tersedia untuk parameter path telah terdefinisi, dokumen interatik bisa memunculkan:

Bekerja dengan enumarasi Python

Nilai parameter path akan menjadi anggota enumerasi.

Membandingkan anggota enumerasi

Anda bisa membandingkan parameter path dengan anggota enumerasi di enum ModelName yang anda buat:

from enum import Enum

from fastapi import FastAPI


class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"


app = FastAPI()


@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
    if model_name is ModelName.alexnet:
        return {"model_name": model_name, "message": "Deep Learning FTW!"}

    if model_name.value == "lenet":
        return {"model_name": model_name, "message": "LeCNN all the images"}

    return {"model_name": model_name, "message": "Have some residuals"}

Mendapatkan nilai enumerasi

Anda bisa mendapatkan nilai (str dalam kasus ini) menggunakan model_name.value, atau secara umum anggota_enum_anda.value:

from enum import Enum

from fastapi import FastAPI


class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"


app = FastAPI()


@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
    if model_name is ModelName.alexnet:
        return {"model_name": model_name, "message": "Deep Learning FTW!"}

    if model_name.value == "lenet":
        return {"model_name": model_name, "message": "LeCNN all the images"}

    return {"model_name": model_name, "message": "Have some residuals"}

Tips

Anda bisa mengakses nilai "lenet" dnegan ModelName.lenet.value.

Menghasilkan anggota enumerasi

Anda bisa menghasilkan anggota enumerasi dari operasi path bahkan di body JSON bersarang (contoh dict).

They will be converted to their corresponding values (strings in this case) before returning them to the client:

from enum import Enum

from fastapi import FastAPI


class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"


app = FastAPI()


@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
    if model_name is ModelName.alexnet:
        return {"model_name": model_name, "message": "Deep Learning FTW!"}

    if model_name.value == "lenet":
        return {"model_name": model_name, "message": "LeCNN all the images"}

    return {"model_name": model_name, "message": "Have some residuals"}

Klien akan mendapatkan respon JSON seperti berikut:

{
  "model_name": "alexnet",
  "message": "Deep Learning FTW!"
}

Parameter path berisi path

Misalkan terdapat operasi path dengan path /files/{file_path}.

Tetapi anda memerlukan file_path itu berisi path, seperti like home/johndoe/myfile.txt.

Sehingga URL untuk file tersebut akan seperti: /files/home/johndoe/myfile.txt.

Dukungan OpenAPI

OpenAPI tidak bisa mendeklarasikan parameter path berisi path di dalamnya, karena menyebabkan kondisi yang sulit ditest dan didefinisikan.

Tetapi, di FastAPI anda tetap bisa melakukannya dengan menggunakan tools internal dari Starlette.

Dan dokumentasi tetap berfungsi walaupun tidak menambahkan keterangan bahwa parameter harus berisi path.

Konverter path

Melalui Starlette anda bisa mendeklarasikan parameter path berisi path dengan URL seperti:

/files/{file_path:path}

Dikondisi ini nama parameter adalah file_path dan bagian terakhir :path menginformasikan parameter harus sesuai dengan setiap path.

Sehingga anda bisa menggunakan:

from fastapi import FastAPI

app = FastAPI()


@app.get("/files/{file_path:path}")
async def read_file(file_path: str):
    return {"file_path": file_path}

Tips

Anda mungkin perlu parameter berisi /home/johndoe/myfile.txt di awali garis belakang (/).

Di kondisi ini, URL nya menjadi: /files//home/johndoe/myfile.txt, dengan dua garis belakang (//) di antara files dan home.

Ringkasan

Di FastAPI dengan menggunakan deklarasi tipe Python standar, pendek, intuitif, anda mendapatkan:

  • Dukungan editor: pemeriksaan kesalahan, autocompletion, dll.
  • "Parsing" data.
  • Validasi data.
  • Annotasi API dan dokumentasi otomatis.

Semua itu anda hanya perlu mendeklarasikan sekali saja.

Ini adalah salah satu keunggulan FastAPI dibandingkan dengan framework lainnya (selain dari performa Python nativec)