22import sys
33import multiprocessing
44import json
5- from contextlib import asynccontextmanager
6-
7- import asyncpg
8- import orjson
95
106os .environ ["TURBO_DISABLE_RATE_LIMITING" ] = "1"
117os .environ ["TURBO_DISABLE_CACHE" ] = "1"
128
13- from turboapi import TurboAPI , Request , Response , Path , Query , HTTPException
14- from turboapi .responses import PlainTextResponse , JSONResponse
15- from turboapi .middleware .gzip import GZipMiddleware
16- from turboapi .staticfiles import StaticFiles
17-
189# -- Dataset and constants --------------------------------------------------------
1910
2011CPU_COUNT = int (multiprocessing .cpu_count ())
3021except Exception :
3122 pass
3223
33- # -- Postgres DB ------------------------------------------------------------
34-
35- PG_POOL : asyncpg .Pool | None = None
36-
37- PG_QUERY = (
38- "SELECT id, name, category, price, quantity, active, tags, rating_score, rating_count "
39- "FROM items WHERE price BETWEEN $1 AND $2 LIMIT $3"
40- )
41-
42- class NoResetConnection (asyncpg .Connection ):
43- __slots__ = ()
44- def get_reset_query (self ):
45- return ""
46-
47- @asynccontextmanager
48- async def lifespan (application : TurboAPI ):
49- global PG_POOL , NoResetConnection
50- DATABASE_URL = os .environ .get ("DATABASE_URL" )
51- if DATABASE_URL :
52- try :
53- if DATABASE_URL .startswith ("postgres://" ):
54- DATABASE_URL = "postgresql://" + DATABASE_URL [len ("postgres://" ):]
55- PG_POOL_MAX_SIZE = 2
56- DATABASE_MAX_CONN = os .environ .get ("DATABASE_MAX_CONN" , None )
57- if DATABASE_MAX_CONN :
58- pool_size = int (DATABASE_MAX_CONN ) * 0.92 / WRK_COUNT
59- PG_POOL_MAX_SIZE = int (pool_size + 0.95 )
60- PG_POOL = await asyncpg .create_pool (
61- dsn = DATABASE_URL ,
62- min_size = 1 ,
63- max_size = max (PG_POOL_MAX_SIZE , 2 ),
64- connection_class = NoResetConnection
65- )
66- except Exception :
67- PG_POOL = None
68- yield
69- if PG_POOL :
70- await PG_POOL .close ()
71- PG_POOL = None
72-
73-
74- app = TurboAPI (lifespan = lifespan )
24+
25+ # -- APP -----------------------------------------------------------------------
26+
27+ from turboapi .request_handler import RequestBodyParser
28+
29+ original_parse_json_body = RequestBodyParser .parse_json_body
30+
31+ def fixed_parse_json_body (body , handler_signature ):
32+ if not body :
33+ return { }
34+ if body .startswith (b'{' ) or body .startswith (b'[' ):
35+ return original_parse_json_body (body , handler_signature )
36+ return { "_BODY_" : body .decode (errors = "replace" ) }
37+
38+ RequestBodyParser .parse_json_body = staticmethod (fixed_parse_json_body )
39+
40+ from turboapi import TurboAPI , Request , Path , Query , File , UploadFile , HTTPException
41+ from turboapi .responses import PlainTextResponse , JSONResponse
42+ from turboapi .middleware import GZipMiddleware
43+ from turboapi .staticfiles import StaticFiles
44+
45+ app = TurboAPI ()
7546
7647app .add_middleware (GZipMiddleware , minimum_size = 1 , compresslevel = 5 )
7748
7849
7950# -- Routes ------------------------------------------------------------------
8051
8152@app .get ("/pipeline" )
82- async def pipeline ():
53+ def pipeline ():
8354 return PlainTextResponse (b"ok" )
8455
8556
86- @app .api_route ("/baseline11" , methods = ["GET" , "POST" ])
87- async def baseline11 (request : Request ):
88- total = 0
89- for v in request .query_params .values ():
90- try :
91- total += int (v )
92- except ValueError :
93- pass
94- if request .method == "POST" :
95- body = await request .body ()
96- if body :
97- try :
98- total += int (body .strip ())
99- except ValueError :
100- pass
101- return PlainTextResponse (str (total ))
102-
103-
104- def json_common (request : Request , count : int , m_val : float ):
57+ @app .get ("/baseline11" )
58+ def baseline11 (a , b ):
59+ return PlainTextResponse ( str ( int (a ) + int (b ) ) )
60+
61+
62+ @app .post ("/baseline11" )
63+ def baseline11body (a , b , _BODY_ ):
64+ return PlainTextResponse ( str ( int (a ) + int (b ) + int (_BODY_ ) ) )
65+
66+
67+ def json_common (count : int , m_val : float ):
10568 global DATASET_ITEMS
10669 if not DATASET_ITEMS :
10770 return PlainTextResponse ("No dataset" , 500 )
@@ -113,66 +76,24 @@ def json_common(request: Request, count: int, m_val: float):
11376 item = dict (dsitem )
11477 item ["total" ] = dsitem ["price" ] * dsitem ["quantity" ] * m_val
11578 items .append (item )
116- return JSONResponse ( { "items" : items , "count" : len (items ) } )
79+ return { "items" : items , "count" : len (items ) }
11780 except Exception :
118- return JSONResponse ( { "items" : [ ], "count" : 0 } )
81+ return { "items" : [ ], "count" : 0 }
11982
12083
12184@app .get ("/json/{count}" )
122- async def json_endpoint (request : Request , count : int = Path (...), m : float = Query (...)):
123- return json_common (request , count , m )
85+ def json_endpoint (count , m ):
86+ count = int (count )
87+ m = float (m )
88+ return json_common (count , m )
12489
12590
12691@app .get ("/json-comp/{count}" )
127- async def json_comp_endpoint (request : Request , count : int = Path (...), m : float = Query (...)):
128- return json_common (request , count , m )
129-
130-
131- @app .get ("/async-db" )
132- async def async_db_endpoint (request : Request , min_val : float = Query (..., alias = "min" ), max_val : float = Query (..., alias = "max" ), limit : int = Query (...)):
133- global PG_POOL
134- if not PG_POOL :
135- return JSONResponse ( { "items" : [ ], "count" : 0 } )
136- try :
137- db_conn = await PG_POOL .acquire ()
138- try :
139- rows = await db_conn .fetch (PG_QUERY , min_val , max_val , limit )
140- finally :
141- await PG_POOL .release (db_conn )
142- items = [
143- {
144- 'id' : row ['id' ],
145- 'name' : row ['name' ],
146- 'category' : row ['category' ],
147- 'price' : row ['price' ],
148- 'quantity' : row ['quantity' ],
149- 'active' : row ['active' ],
150- 'tags' : json .loads (row ['tags' ]) if isinstance (row ['tags' ], str ) else row ['tags' ],
151- 'rating' : {
152- 'score' : row ['rating_score' ],
153- 'count' : row ['rating_count' ],
154- }
155- }
156- for row in rows
157- ]
158- return JSONResponse ( { "items" : items , "count" : len (items ) } )
159- except Exception :
160- return JSONResponse ( { "items" : [ ], "count" : 0 } )
161-
162-
163- @app .post ("/upload" )
164- async def upload_endpoint (request : Request ):
165- size = 0
166- async for chunk in request .stream ():
167- size += len (chunk )
168- return PlainTextResponse (str (size ))
169-
170-
171- try :
172- app .mount ("/static" , StaticFiles (directory = "/data/static/" ), name = "static" )
173- except Exception :
174- pass
92+ def json_comp_endpoint (count , m ):
93+ count = int (count )
94+ m = float (m )
95+ return json_common (count , m )
17596
17697
17798if __name__ == "__main__" :
178- app .run (host = "0.0.0.0" , port = 8080 , workers = WRK_COUNT )
99+ app .run (host = "0.0.0.0" , port = 8080 )
0 commit comments