Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. FastAPI Dictionary
  3. Enum Parameters

Enum Parameters

Since: FastAPI 0.1(2019)

In FastAPI, you can restrict the accepted values of a parameter to a specific set of choices by using Python's standard library Enum class as a type annotation. If an invalid value is sent, FastAPI automatically returns a 422 error, and the available choices are also listed in the OpenAPI documentation (Swagger UI).

Syntax

from enum import Enum
from fastapi import FastAPI

# Define choices by inheriting from the Enum class
class EnumName(str, Enum):
    choice1 = "value1"   # A string Enum inherits from both str and Enum
    choice2 = "value2"

app = FastAPI()

@app.get("/endpoint/")
def function_name(param: EnumName):
    # param only accepts one of the Enum values
    return {"param": param}

Common uses of Enum

ItemDescription
Multiple inheritance with str, EnumInheriting from both str and Enum at the same time allows values to be treated as strings. Serialization into JSON responses also works without any extra steps.
Applying to query parametersSpecifying an Enum class as the type annotation of a function argument restricts that query parameter to the Enum's choices.
Applying to path parametersYou can also specify an Enum class as the type annotation of a path parameter. Use this when you want to limit part of the URL path to a fixed set of values.
Getting the value with .valueThe actual value of an Enum member (such as a string) can be retrieved with the .value property. Use this when you need to include the value in a response.
Getting the name with .nameThe definition name of an Enum member (its Python identifier) can be retrieved with the .name property.
Integer EnumYou can also define integer choices by using multiple inheritance with int, Enum.

Sample code

This sample defines product categories and sort order as Enums and uses them as query parameters and path parameters.

main.py
# ---- main.py ----

from enum import Enum
from fastapi import FastAPI

# Create a FastAPI instance
app = FastAPI()


# Define product categories as a string Enum
# Inheriting from both str and Enum allows direct conversion to JSON
class Category(str, Enum):
    fruit = "fruit"
    dairy = "dairy"
    bread = "bread"


# Define sort order as a string Enum
class SortOrder(str, Enum):
    asc  = "asc"   # ascending
    desc = "desc"  # descending


# Sample product data (a real app would use a database)
ITEMS = [
    {"id": 1, "name": "apple",   "price": 120, "category": "fruit"},
    {"id": 2, "name": "orange",  "price": 80,  "category": "fruit"},
    {"id": 3, "name": "milk",    "price": 200, "category": "dairy"},
    {"id": 4, "name": "cheese",  "price": 350, "category": "dairy"},
    {"id": 5, "name": "bread",   "price": 250, "category": "bread"},
]


# Endpoint that uses Enum as query parameters
# Access it like: GET /items/?category=fruit&order=asc
# Any value other than fruit / dairy / bread for category results in a 422 error
@app.get("/items/")
def get_items(
    category: Category,
    order: SortOrder = SortOrder.asc,   # Specify an Enum member as the default value
):
    # Use .value to get the actual string and filter items
    matched = [item for item in ITEMS if item["category"] == category.value]

    # Sort by price in ascending or descending order
    reverse = (order == SortOrder.desc)
    matched = sorted(matched, key=lambda x: x["price"], reverse=reverse)

    return {
        "category": category,    # Enum members can be returned directly (treated as str)
        "order":    order,
        "results":  matched,
    }


# Endpoint that uses Enum as a path parameter
# Access it like: GET /categories/fruit/summary
# A value in the path that is not one of the Enum choices results in a 422 error
@app.get("/categories/{category}/summary")
def get_category_summary(category: Category):
    # Get products in the matching category
    matched = [item for item in ITEMS if item["category"] == category.value]

    # Calculate the average price
    avg_price = sum(item["price"] for item in matched) / len(matched) if matched else 0

    return {
        "category":  category.value,   # Return as a string using .value
        "count":     len(matched),
        "avg_price": avg_price,
    }

Common mistake 1: forgetting to inherit from str

If you define the class as class Category(Enum) alone, FastAPI will fail to serialize it to JSON when including it in a response. To treat values as strings, you need to use multiple inheritance with str, Enum.

NG — not inheriting from str

from enum import Enum

class Rank(Enum):
    kyo = "kyo"
    iori = "iori"
    mai = "mai"

When FastAPI tries to serialize the response, it cannot convert Enum members directly to JSON and raises a ValueError.

OK — use multiple inheritance with str and Enum

from enum import Enum

class Rank(str, Enum):
    kyo = "kyo"
    iori = "iori"
    mai = "mai"

Common mistake 2: using .value for comparisons

You can avoid using .value when comparing Enum members. An Enum that inherits from str, Enum can be compared directly against other Enum members.

NG — comparing with .value against a string

@app.get("/fighter/")
def get_fighter(rank: Rank):
    if rank.value == "iori":
        return {"name": "Yagami Iori"}

This works, but it does not take advantage of Enum's type safety. Because it becomes a string comparison, there is a risk that Enum name changes during refactoring are missed.

OK — compare Enum members directly

@app.get("/fighter/")
def get_fighter(rank: Rank):
    if rank == Rank.iori:
        return {"name": "Yagami Iori"}

Summary

Using Enum parameters restricts accepted values to only the defined choices. When an invalid value is passed, FastAPI automatically returns a 422 Unprocessable Entity, so you can skip manual validation inside the endpoint. The available choices are also displayed automatically in the OpenAPI documentation (Swagger UI), making it easy for API consumers to see at a glance what values are accepted. Use str, Enum for string values and int, Enum for integer values. The value of an Enum member is available via .value, and its Python identifier name is available via .name. You can also combine Enum parameters with Query() for additional query parameter validation. See also Path parameters for applying Enum to path parameters.

If you find any errors or copyright issues, please .