33import json , time
44from fastapi import FastAPI , Request , status , Depends , Response
55from fastapi .responses import JSONResponse
6+ from starlette .middleware .base import BaseHTTPMiddleware
7+ from starlette .middleware import Middleware
68from auth import VerifyToken
79from threading import Thread # Not used yet
810
1719 redis_client ,
1820 WHITELISTED_IPS ,
1921 append_request_log ,
22+ append_denied_log ,
2023)
2124
2225from sql import selectQuery , insertQuery
23- import surftimer .queries # Containing all SurfTimer queries from `queries.sp`
2426
2527# Import all the endpoints for each table
2628from surftimer .ck_latestrecords import router as ck_latestrecords_router
@@ -44,11 +46,28 @@ def to_dict(self):
4446 return {"inserted" : self .inserted }
4547
4648
47- # Swagger UI configuration
49+ class IPValidatorMiddleware (BaseHTTPMiddleware ):
50+ async def dispatch (self , request : Request , call_next ):
51+ # Get client IP
52+ ip = str (request .client .host )
53+
54+ # Check if IP is allowed
55+ if ip not in WHITELISTED_IPS :
56+ append_denied_log (request )
57+ data = {"message" : "Not Allowed" , "ip" : ip }
58+ return JSONResponse (status_code = status .HTTP_400_BAD_REQUEST , content = data )
59+
60+ append_request_log (request )
61+ # Proceed if IP is allowed
62+ return await call_next (request )
63+
64+
65+ # Swagger UI configuration - https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/
4866swagger_config = {
4967 "displayOperationId" : False , # Show operationId on the UI
5068 "defaultModelsExpandDepth" : 1 , # The default expansion depth for models (set to -1 completely hide the models)
5169 "defaultModelExpandDepth" : 2 ,
70+ "defaultModelRendering" : "example" ,
5271 "deepLinking" : True , # Enables deep linking for tags and operations
5372 "useUnsafeMarkdown" : True ,
5473 "displayRequestDuration" : True ,
@@ -65,22 +84,10 @@ def to_dict(self):
6584 version = "0.0.0" ,
6685 debug = True ,
6786 swagger_ui_parameters = swagger_config ,
68- # docs_url=None ,
87+ middleware = [ Middleware ( IPValidatorMiddleware )] ,
6988)
7089
7190
72- @app .get ("/docs2" , include_in_schema = False )
73- async def custom_swagger_ui_html_cdn ():
74- return get_swagger_ui_html (
75- openapi_url = app .openapi_url ,
76- title = f"{ app .title } - Swagger UI" ,
77- # swagger_ui_dark.css CDN link
78- swagger_css_url = "https://cdn.jsdelivr.net/gh/Itz-fork/Fastapi-Swagger-UI-Dark/assets/swagger_ui_dark.min.css" ,
79- # swagger_css_url="https://raw.clarityeu.com/theme-newspaper.css",
80- swagger_ui_parameters = swagger_config ,
81- )
82-
83-
8491# Attach the routes
8592app .include_router (ck_latestrecords_router )
8693app .include_router (ck_maptier_router )
@@ -91,18 +98,15 @@ async def custom_swagger_ui_html_cdn():
9198app .include_router (ck_playertemp_router )
9299
93100
94- @app .middleware ("http" )
95- async def validate_ip (request : Request , call_next ):
96- # Get client IP
97- ip = str (request .client .host )
98-
99- # Check if IP is allowed
100- if ip not in WHITELISTED_IPS :
101- data = {"message" : f"IP { ip } is not allowed to access this resource." }
102- return JSONResponse (status_code = status .HTTP_400_BAD_REQUEST , content = data )
103-
104- # Proceed if IP is allowed
105- return await call_next (request )
101+ @app .get ("/docs2" , include_in_schema = False )
102+ async def custom_swagger_ui_html_cdn ():
103+ return get_swagger_ui_html (
104+ openapi_url = app .openapi_url ,
105+ title = f"{ app .title } - Swagger UI" ,
106+ # swagger_ui_dark.css CDN link
107+ swagger_css_url = "https://cdn.jsdelivr.net/gh/Itz-fork/Fastapi-Swagger-UI-Dark/assets/swagger_ui_dark.min.css" ,
108+ swagger_ui_parameters = swagger_config ,
109+ )
106110
107111
108112@app .get ("/" )
@@ -140,20 +144,15 @@ async def mapchooser(
140144 ```"""
141145 tic = time .perf_counter ()
142146
143- append_request_log (request )
144-
145147 json_data = []
146148
147149 # Check if data is cached in Redis
148- cached_data = redis_client .get (
149- f"mapchooser_{ type } _{ tier_min } _{ tier_max } _{ tier } _{ steamid } _{ style } "
150- )
150+ cache_key = f"mapchooser:{ type } _{ tier_min } _{ tier_max } _{ tier } _{ steamid } _{ style } "
151+ cached_data = redis_client .get (cache_key )
151152 if cached_data :
152153 # Return cached data
153154 # print(json.loads(cached_data))
154- print (
155- f"[Redis] Loaded 'mapchooser_{ type } _{ tier_min } _{ tier_max } _{ tier } _{ steamid } _{ style } ' ({ time .perf_counter () - tic :0.4f} s)"
156- )
155+ print (f"[Redis] Loaded '{ cache_key } ' ({ time .perf_counter () - tic :0.4f} s)" )
157156 return JSONResponse (
158157 status_code = status .HTTP_200_OK , content = json .loads (cached_data )
159158 )
@@ -255,47 +254,14 @@ async def mapchooser(
255254
256255 # Cache the data in Redis
257256 redis_client .set (
258- f"mapchooser_ { type } _ { tier_min } _ { tier_max } _ { tier } _ { steamid } _ { style } " ,
257+ cache_key ,
259258 json .dumps (json_data ),
260259 ex = config ["REDIS" ]["EXPIRY" ],
261260 )
262261
263262 return json_data
264263
265264
266- # request: Request,
267- # response: Response,
268- # steamid32: str,
269- # name: str,
270- # runtime: float,
271- # mapname: str,
272- # ):
273- # """Inserts a new record to the table\n
274- # ```char sql_insertLatestRecords[] = ....```"""
275- # tic = time.perf_counter()
276- # append_request_log(request)
277-
278- # sql = surftimer.queries.sql_insertLatestRecords.format(
279- # steamid32, name, runtime, mapname
280- # )
281- # # xquery = insertQuery(sql)
282- # xquery = 0
283- # # time.sleep(3)
284-
285- # if xquery < 1:
286- # JSONResponse(
287- # status_code=status.HTTP_204_NO_CONTENT,
288- # content={"inserted": xquery, "xtime": time.perf_counter() - tic},
289- # )
290-
291- # # Prepare the response
292- # toc = time.perf_counter()
293- # print(f"Execution time {toc - tic:0.4f}")
294- # # output = ResponseInsertQuery(xquery)
295-
296- # return {"inserted": xquery, "xtime": time.perf_counter() - tic}
297-
298-
299265# new code 👇
300266@app .get (
301267 "/api/private" ,
0 commit comments