1
+ import logging
1
2
from typing import Annotated , Union
3
+ from fastapi .exception_handlers import http_exception_handler
4
+ from fastapi .responses import JSONResponse
5
+ from pydantic import BaseModel
2
6
import uvicorn
3
7
4
- from fastapi import FastAPI , Query , Path
8
+ from fastapi import FastAPI , HTTPException , Query , Path , Request
5
9
6
10
app = FastAPI ()
7
11
@@ -18,6 +22,71 @@ def read_item(
18
22
):
19
23
return {"item_id" : item_id , "q" : q }
20
24
25
+
26
+
27
+ logger = logging .getLogger ("uvicorn" )
28
+ app = FastAPI ()
29
+
30
+ @app .get ("/" )
31
+ def read_root ():
32
+ return {"Hello" : "World" }
33
+ class Creature (BaseModel ):
34
+ id : int
35
+ family : str
36
+ common_name : str
37
+ class Config :
38
+ schema_extra = {
39
+ "example" : {
40
+ "id" : 1 ,
41
+ "family" : "Amphibian" ,
42
+ "name" : "Frog"
43
+ }
44
+ }
45
+
46
+ class AuthenticationError (HTTPException ):
47
+ def __init__ (self , detail : str ):
48
+ super ().__init__ (status_code = 401 , detail = detail )
49
+
50
+
51
+ creatures : list [Creature ] = [Creature (id = 1 , family = "Amphibian" , common_name = "Frog" )]
52
+
53
+ @app .post ("/create_amphibian" )
54
+ def create_amphibian (creature : Creature , user_level : int , throws : bool = False ) -> bool :
55
+ if throws :
56
+ raise Exception ("This is an unexpected exception" )
57
+ if creature .family != "Amphibian" : # validation error not caught by FastAPI
58
+ raise HTTPException (status_code = 400 , detail = "Only amphibians allowed" )
59
+ if user_level < 2 :
60
+ raise AuthenticationError (detail = "You are not admin" )
61
+ creatures .append (creature )
62
+ return True
63
+
64
+ @app .exception_handler (Exception )
65
+ async def _unhandled_exception_handler (request : Request , exc : Exception ):
66
+ logger .error ("There was an unhandled error" )
67
+ return JSONResponse (
68
+ status_code = exc .status_code ,
69
+ content = {"message" : exc .detail },
70
+ )
71
+
72
+ @app .exception_handler (HTTPException )
73
+ async def _http_exception_handler (request : Request , exc : HTTPException ):
74
+ logger .error ("There was an handled error" )
75
+
76
+ return await http_exception_handler (request , exc )
77
+
78
+ @app .exception_handler (AuthenticationError )
79
+ async def _authentication_exception_handler (request : Request , exc : AuthenticationError ):
80
+ logger .info (str (request .json ()))
81
+ logger .error (f"A level { request .user_level } user tried to access a restricted resource" )
82
+ return JSONResponse (
83
+ status_code = exc .status_code ,
84
+ content = {"message" : exc .detail },
85
+ )
86
+
87
+
88
+
89
+
21
90
# For local debugging
22
91
if __name__ == "__main__" :
23
92
uvicorn .run (app , host = "0.0.0.0" , port = 8000 )
0 commit comments