๐ โ¶
๐ค ๐ โ ๐โ ๐ ๐ช ๐จ โ ๐ฉโ๐ป ๐ โ๏ธ ๐ ๐ ๏ธ.
๐ ๐ฉโ๐ป ๐ช ๐ฅ โฎ๏ธ ๐ธ, ๐ โช๏ธโก๏ธ ๐ฑ ๐, โ ๐ณ, โ๏ธ.
๐ ๐ช ๐ช ๐ฌ ๐ฉโ๐ป ๐:
- ๐ฉโ๐ป ๐ซ โ๏ธ ๐ฅ ๐ ๐ ๐ ๏ธ.
- ๐ฉโ๐ป ๐ซ โ๏ธ ๐ ๐ โน.
- ๐ฌ ๐ฉโ๐ป ๐ ๐ ๐ซ ๐.
- โ๏ธ.
๐ซ ๐ผ, ๐ ๐ ๐ ๐จ ๐บ๐ธ๐ ๐ ๐ โ 4๏ธโฃ0๏ธโฃ0๏ธโฃ (โช๏ธโก๏ธ 4๏ธโฃ0๏ธโฃ0๏ธโฃ 4๏ธโฃ9๏ธโฃ9๏ธโฃ).
๐ ๐ 2๏ธโฃ0๏ธโฃ0๏ธโฃ ๐บ๐ธ๐ ๐ ๐ (โช๏ธโก๏ธ 2๏ธโฃ0๏ธโฃ0๏ธโฃ 2๏ธโฃ9๏ธโฃ9๏ธโฃ). ๐ "2๏ธโฃ0๏ธโฃ0๏ธโฃ" ๐ ๐ โ ๐ ๐ซ ๐ค "๐" ๐จ.
๐ ๐ 4๏ธโฃ0๏ธโฃ0๏ธโฃ โ โ ๐ ๐ค โ โช๏ธโก๏ธ ๐ฉโ๐ป.
๐ญ ๐ ๐ "4๏ธโฃ0๏ธโฃ4๏ธโฃ ๐ซ ๐" โ (& ๐คฃ) โ
โ๏ธ HTTPException
¶
๐จ ๐บ๐ธ๐ ๐จ โฎ๏ธ โ ๐ฉโ๐ป ๐ โ๏ธ HTTPException
.
๐ HTTPException
¶
from fastapi import FastAPI, HTTPException
app = FastAPI()
items = {"foo": "The Foo Wrestlers"}
@app.get("/items/{item_id}")
async def read_item(item_id: str):
if item_id not in items:
raise HTTPException(status_code=404, detail="Item not found")
return {"item": items[item_id]}
๐ค HTTPException
๐ ๐¶
HTTPException
๐ ๐ โ โฎ๏ธ ๐ ๐ ๐ ๐.
โฉ๏ธ โซ๏ธ ๐ โ , ๐ ๐ซ return
โซ๏ธ, ๐ raise
โซ๏ธ.
๐ โ ๐ ๐ฅ ๐ ๐ ๐ ๐ข ๐ ๐ ๐ค ๐ ๐ โก ๐ ๏ธ ๐ข, & ๐ ๐ค HTTPException
โช๏ธโก๏ธ ๐ ๐ ๐ ๐ข, โซ๏ธ ๐ ๐ซ ๐ ๐ ๐ โก ๐ ๏ธ ๐ข, โซ๏ธ ๐ โ ๐ ๐จ โถ๏ธ๏ธ โ๏ธ & ๐จ ๐บ๐ธ๐ โ โช๏ธโก๏ธ HTTPException
๐ฉโ๐ป.
๐ฐ ๐โโ โ ๐คญ return
๐
๐ฒ ๐ ๐ โญ ๐ ๐ ๐ & ๐โโ.
๐ ๐ผ, ๐โ ๐ฉโ๐ป ๐จ ๐ฌ ๐ ๐ ๐ซ ๐, ๐ค โ โฎ๏ธ ๐ ๐ 404
:
from fastapi import FastAPI, HTTPException
app = FastAPI()
items = {"foo": "The Foo Wrestlers"}
@app.get("/items/{item_id}")
async def read_item(item_id: str):
if item_id not in items:
raise HTTPException(status_code=404, detail="Item not found")
return {"item": items[item_id]}
๐ ๐จ¶
๐ฅ ๐ฉโ๐ป ๐จ http://example.com/items/foo
( item_id
"foo"
), ๐ ๐ฉโ๐ป ๐ ๐จ ๐บ๐ธ๐ ๐ ๐ 2๏ธโฃ0๏ธโฃ0๏ธโฃ, & ๐ป ๐จ:
{
"item": "The Foo Wrestlers"
}
โ๏ธ ๐ฅ ๐ฉโ๐ป ๐จ http://example.com/items/bar
(๐ซ-๐ซ item_id
"bar"
), ๐ ๐ฉโ๐ป ๐ ๐จ ๐บ๐ธ๐ ๐ ๐ 4๏ธโฃ0๏ธโฃ4๏ธโฃ ("๐ซ ๐" โ), & ๐ป ๐จ:
{
"detail": "Item not found"
}
Tip
๐โ ๐โโ HTTPException
, ๐ ๐ช ๐ถโโ๏ธ ๐ ๐ฒ ๐ ๐ช ๐ ๐ป ๐ข detail
, ๐ซ ๐ด str
.
๐ ๐ช ๐ถโโ๏ธ dict
, list
, โ๏ธ.
๐ซ ๐ต ๐ FastAPI & ๐ ๐ป.
๐ฎ ๐ ๐¶
๐ค โ ๐โ โซ๏ธ โ ๐ช ๐ฎ ๐ ๐ ๐บ๐ธ๐ โ. ๐ผ, ๐ ๐โโ.
๐ ๐ฒ ๐ ๐ซ ๐ช โ๏ธ โซ๏ธ ๐ ๐ ๐.
โ๏ธ ๐ผ ๐ ๐ช โซ๏ธ ๐ง ๐, ๐ ๐ช ๐ฎ ๐ ๐:
from fastapi import FastAPI, HTTPException
app = FastAPI()
items = {"foo": "The Foo Wrestlers"}
@app.get("/items-header/{item_id}")
async def read_item_header(item_id: str):
if item_id not in items:
raise HTTPException(
status_code=404,
detail="Item not found",
headers={"X-Error": "There goes my error"},
)
return {"item": items[item_id]}
โ ๐ โ ๐โ๐ฆบ¶
๐ ๐ช ๐ฎ ๐ โ ๐โ๐ฆบ โฎ๏ธ ๐ โ ๐ โช๏ธโก๏ธ ๐.
โก๏ธ ๐ฌ ๐ โ๏ธ ๐ โ UnicornException
๐ ๐ (โ๏ธ ๐ ๐ โ๏ธ) ๐ช raise
.
& ๐ ๐ ๐ต ๐ โ ๐ โฎ๏ธ FastAPI.
๐ ๐ช ๐ฎ ๐ โ ๐โ๐ฆบ โฎ๏ธ @app.exception_handler()
:
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
class UnicornException(Exception):
def __init__(self, name: str):
self.name = name
app = FastAPI()
@app.exception_handler(UnicornException)
async def unicorn_exception_handler(request: Request, exc: UnicornException):
return JSONResponse(
status_code=418,
content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."},
)
@app.get("/unicorns/{name}")
async def read_unicorn(name: str):
if name == "yolo":
raise UnicornException(name=name)
return {"unicorn_name": name}
๐ฅ, ๐ฅ ๐ ๐จ /unicorns/yolo
, โก ๐ ๏ธ ๐ raise
UnicornException
.
โ๏ธ โซ๏ธ ๐ ๐ต unicorn_exception_handler
.
, ๐ ๐ ๐จ ๐งน โ, โฎ๏ธ ๐บ๐ธ๐ ๐ ๐ 418
& ๐ป ๐:
{"message": "Oops! yolo did something. There goes a rainbow..."}
๐ก โน
๐ ๐ช โ๏ธ from starlette.requests import Request
& from starlette.responses import JSONResponse
.
FastAPI ๐ ๐ starlette.responses
fastapi.responses
๐ช ๐, ๐ฉโ๐ป. โ๏ธ ๐
๐ช ๐จ ๐ ๐ โช๏ธโก๏ธ ๐. ๐ โฎ๏ธ Request
.
๐ ๐ข โ ๐โ๐ฆบ¶
FastAPI โ๏ธ ๐ข โ ๐โ๐ฆบ.
๐ซ ๐โ๐ฆบ ๐ ๐ฌ ๐ข ๐ป ๐จ ๐โ ๐ raise
HTTPException
& ๐โ ๐จ โ๏ธ โ ๐ฝ.
๐ ๐ช ๐ ๐ซ โ ๐โ๐ฆบ โฎ๏ธ ๐ ๐.
๐ ๐จ ๐ฌ โ ¶
๐โ ๐จ ๐ โ ๐, FastAPI ๐ ๐ค RequestValidationError
.
& โซ๏ธ ๐ ๐ข โ ๐โ๐ฆบ โซ๏ธ.
๐ โซ๏ธ, ๐ RequestValidationError
& โ๏ธ โซ๏ธ โฎ๏ธ @app.exception_handler(RequestValidationError)
๐ โ ๐โ๐ฆบ.
โ ๐โ๐ฆบ ๐ ๐จ Request
& โ .
from fastapi import FastAPI, HTTPException
from fastapi.exceptions import RequestValidationError
from fastapi.responses import PlainTextResponse
from starlette.exceptions import HTTPException as StarletteHTTPException
app = FastAPI()
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request, exc):
return PlainTextResponse(str(exc.detail), status_code=exc.status_code)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
return PlainTextResponse(str(exc), status_code=400)
@app.get("/items/{item_id}")
async def read_item(item_id: int):
if item_id == 3:
raise HTTPException(status_code=418, detail="Nope! I don't like 3.")
return {"item_id": item_id}
๐, ๐ฅ ๐ ๐ถ /items/foo
, โฉ๏ธ ๐โโ ๐ข ๐ป โ โฎ๏ธ:
{
"detail": [
{
"loc": [
"path",
"item_id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
๐ ๐ ๐ค โ โฌ, โฎ๏ธ:
1 validation error
path -> item_id
value is not a valid integer (type=type_error.integer)
RequestValidationError
๐ ValidationError
¶
Warning
๐ซ ๐ก โน ๐ ๐ ๐ช ๐ถ ๐ฅ โซ๏ธ ๐ซ โ ๐ ๐.
RequestValidationError
๐ง-๐ Pydantic ValidationError
.
FastAPI โ๏ธ โซ๏ธ ๐, ๐ฅ ๐ โ๏ธ Pydantic ๐ท response_model
, & ๐ ๐ฝ โ๏ธ โ, ๐ ๐ ๐ โ ๐ ๐น.
โ๏ธ ๐ฉโ๐ป/๐ฉโ๐ป ๐ ๐ซ ๐ โซ๏ธ. โฉ๏ธ, ๐ฉโ๐ป ๐ ๐จ "๐ ๐ฝ โ" โฎ๏ธ ๐บ๐ธ๐ ๐ ๐ 500
.
โซ๏ธ ๐ ๐ ๐ โฉ๏ธ ๐ฅ ๐ โ๏ธ Pydantic ValidationError
๐ ๐จ โ๏ธ ๐ ๐ ๐ (๐ซ ๐ฉโ๐ป ๐จ), โซ๏ธ ๐ค ๐ ๐ ๐.
& โช ๐ ๐ง โซ๏ธ, ๐ ๐ฉโ๐ป/๐ฉโ๐ป ๐ซ๐ ๐ซ โ๏ธ ๐ ๐ โน ๐ โ, ๐ ๐ช ๐ฆ ๐โโ โ .
๐ HTTPException
โ ๐โ๐ฆบ¶
๐ ๐, ๐ ๐ช ๐ HTTPException
๐โ๐ฆบ.
๐ผ, ๐ ๐ช ๐ ๐จ โ โ ๐จ โฉ๏ธ ๐ป ๐ซ โ:
from fastapi import FastAPI, HTTPException
from fastapi.exceptions import RequestValidationError
from fastapi.responses import PlainTextResponse
from starlette.exceptions import HTTPException as StarletteHTTPException
app = FastAPI()
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request, exc):
return PlainTextResponse(str(exc.detail), status_code=exc.status_code)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
return PlainTextResponse(str(exc), status_code=400)
@app.get("/items/{item_id}")
async def read_item(item_id: int):
if item_id == 3:
raise HTTPException(status_code=418, detail="Nope! I don't like 3.")
return {"item_id": item_id}
๐ก โน
๐ ๐ช โ๏ธ from starlette.responses import PlainTextResponse
.
FastAPI ๐ ๐ starlette.responses
fastapi.responses
๐ช ๐, ๐ฉโ๐ป. โ๏ธ ๐
๐ช ๐จ ๐ ๐ โช๏ธโก๏ธ ๐.
โ๏ธ RequestValidationError
๐ช¶
RequestValidationError
๐ body
โซ๏ธ ๐จ โฎ๏ธ โ ๐ฝ.
๐ ๐ช โ๏ธ โซ๏ธ โช ๐ ๏ธ ๐ ๐ฑ ๐น ๐ช & โน โซ๏ธ, ๐จ โซ๏ธ ๐ฉโ๐ป, โ๏ธ.
from fastapi import FastAPI, Request, status
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from pydantic import BaseModel
app = FastAPI()
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content=jsonable_encoder({"detail": exc.errors(), "body": exc.body}),
)
class Item(BaseModel):
title: str
size: int
@app.post("/items/")
async def create_item(item: Item):
return item
๐ ๐ ๐จ โ ๐ฌ ๐:
{
"title": "towel",
"size": "XL"
}
๐ ๐ ๐จ ๐จ ๐ฌ ๐ ๐ ๐ฝ โ โ ๐จ ๐ช:
{
"detail": [
{
"loc": [
"body",
"size"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
],
"body": {
"title": "towel",
"size": "XL"
}
}
FastAPI HTTPException
๐ ๐ HTTPException
¶
FastAPI โ๏ธ ๐ฎ ๐ HTTPException
.
& FastAPI'โ HTTPException
โ ๐ ๐ โช๏ธโก๏ธ ๐ HTTPException
โ ๐.
๐ด ๐บ, ๐ FastAPI'โ HTTPException
โ ๐ ๐ฎ ๐ ๐ ๐จ.
๐ ๐ช/โ๏ธ ๐ โณ 2๏ธโฃ.0๏ธโฃ & ๐โโ ๐.
, ๐ ๐ช ๐ง ๐โโ FastAPI'โ HTTPException
๐ ๐ ๐.
โ๏ธ ๐โ ๐ ยฎ โ ๐โ๐ฆบ, ๐ ๐ ยฎ โซ๏ธ ๐ HTTPException
.
๐ ๐, ๐ฅ ๐ ๐ ๐ ๐ ๐, โ๏ธ ๐ โ โ๏ธ ๐ -, ๐ค ๐ HTTPException
, ๐ ๐โ๐ฆบ ๐ ๐ช โ & ๐ต โซ๏ธ.
๐ ๐ผ, ๐ช โ๏ธ ๐ฏโโ๏ธ HTTPException
โ ๐ ๐, ๐ โ ๐ StarletteHTTPException
:
from starlette.exceptions import HTTPException as StarletteHTTPException
๐ค-โ๏ธ FastAPI'โ โ ๐โ๐ฆบ¶
๐ฅ ๐ ๐ โ๏ธ โ โคด๏ธ โฎ๏ธ ๐ ๐ข โ ๐โ๐ฆบ โช๏ธโก๏ธ FastAPI, ๐ ๐ช ๐ & ๐ค-โ๏ธ ๐ข โ ๐โ๐ฆบ โช๏ธโก๏ธ fastapi.exception_handlers
:
from fastapi import FastAPI, HTTPException
from fastapi.exception_handlers import (
http_exception_handler,
request_validation_exception_handler,
)
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException as StarletteHTTPException
app = FastAPI()
@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request, exc):
print(f"OMG! An HTTP error!: {repr(exc)}")
return await http_exception_handler(request, exc)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
print(f"OMG! The client sent invalid data!: {exc}")
return await request_validation_exception_handler(request, exc)
@app.get("/items/{item_id}")
async def read_item(item_id: int):
if item_id == 3:
raise HTTPException(status_code=418, detail="Nope! I don't like 3.")
return {"item_id": item_id}
๐ ๐ผ ๐ print
๐
โ โฎ๏ธ ๐ถ ๐จ ๐ง, โ๏ธ ๐ ๐ค ๐ญ. ๐ ๐ช โ๏ธ โ & โคด๏ธ ๐ค-โ๏ธ ๐ข โ ๐โ๐ฆบ.