Skip to content

Commit 890ba36

Browse files
authored
[Python] Bump Panther to 5.0.1 (#9995)
1 parent 9816b9c commit 890ba36

File tree

3 files changed

+52
-61
lines changed

3 files changed

+52
-61
lines changed

frameworks/Python/panther/app.py

Lines changed: 37 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import multiprocessing
2-
from pathlib import Path
32
from random import randint, sample
43

54
import asyncpg
@@ -10,19 +9,22 @@
109
from panther.request import Request
1110
from panther.response import Response, PlainTextResponse, HTMLResponse
1211

13-
READ_ROW_SQL = 'SELECT "id", "randomnumber" FROM "world" WHERE id = $1'
14-
WRITE_ROW_SQL = 'UPDATE "world" SET "randomnumber"=$1 WHERE id=$2'
15-
ADDITIONAL_ROW = [0, 'Additional fortune added at request time.']
16-
MAX_POOL_SIZE = 1000 // multiprocessing.cpu_count()
17-
MIN_POOL_SIZE = max(int(MAX_POOL_SIZE / 2), 1)
12+
cpu_count = multiprocessing.cpu_count()
13+
MAX_POOL_SIZE = 1000 // cpu_count
14+
MIN_POOL_SIZE = max(MAX_POOL_SIZE // 2, 1)
1815

19-
pool = None
16+
connection_pool = None
17+
18+
fortune_template = jinja2.Environment(
19+
loader=jinja2.FileSystemLoader('templates'),
20+
autoescape=True
21+
).get_template('fortune.html')
2022

2123

2224
@Event.startup
23-
async def create_db_pool():
24-
global pool
25-
pool = await asyncpg.create_pool(
25+
async def on_startup():
26+
global connection_pool
27+
connection_pool = await asyncpg.create_pool(
2628
user='benchmarkdbuser',
2729
password='benchmarkdbpass',
2830
database='hello_world',
@@ -34,85 +36,70 @@ async def create_db_pool():
3436

3537

3638
@Event.shutdown
37-
async def clean_db_pool():
38-
await pool.close()
39-
40-
41-
with Path('templates/fortune.html').open() as f:
42-
fortune_template = jinja2.Template(f.read())
43-
44-
45-
def get_num_queries(request):
46-
value = request.query_params.get('queries')
47-
if value is None:
48-
return 1
49-
50-
try:
51-
query_count = int(value)
52-
except ValueError:
53-
return 1
54-
if query_count < 1:
55-
return 1
56-
if query_count > 500:
57-
return 500
58-
return query_count
39+
async def on_shutdown():
40+
await connection_pool.close()
5941

6042

6143
@API()
62-
async def json_serialization():
44+
def json_serialization():
6345
return Response(data={'message': 'Hello, world!'})
6446

6547

6648
@API()
6749
async def single_database_query():
6850
row_id = randint(1, 10000)
69-
async with pool.acquire() as connection:
70-
number = await connection.fetchval(READ_ROW_SQL, row_id)
51+
async with connection_pool.acquire() as connection:
52+
number = await connection.fetchval('SELECT id, randomnumber FROM world WHERE id = $1', row_id)
7153
return Response(data={'id': row_id, 'randomNumber': number})
7254

7355

7456
@API()
7557
async def multiple_database_queries(request: Request):
76-
num_queries = get_num_queries(request)
77-
row_ids = sample(range(1, 10000), num_queries)
78-
79-
async with pool.acquire() as connection:
80-
statement = await connection.prepare(READ_ROW_SQL)
58+
try:
59+
count = int(request.query_params.get('queries', 1))
60+
except (ValueError, TypeError):
61+
count = 1
62+
row_ids = sample(range(1, 10000), min(max(count, 1), 500))
63+
async with connection_pool.acquire() as connection:
64+
statement = await connection.prepare('SELECT id, randomnumber FROM world WHERE id = $1')
8165
worlds = [{'id': i, 'randomNumber': await statement.fetchval(i)} for i in row_ids]
82-
8366
return Response(data=worlds)
8467

8568

8669
@API()
8770
async def fortunes():
88-
async with pool.acquire() as connection:
71+
async with connection_pool.acquire() as connection:
8972
fortune_records = await connection.fetch('SELECT * FROM Fortune')
90-
fortune_records.append(ADDITIONAL_ROW)
73+
fortune_records = [(row['id'], row['message']) for row in fortune_records]
74+
fortune_records.append((0, 'Additional fortune added at request time.'))
9175
fortune_records.sort(key=lambda row: row[1])
9276
data = fortune_template.render(fortunes=fortune_records)
9377
return HTMLResponse(data=data)
9478

9579

9680
@API()
9781
async def database_updates(request: Request):
98-
num_queries = get_num_queries(request)
82+
try:
83+
count = int(request.query_params.get('queries', 1))
84+
except (ValueError, TypeError):
85+
count = 1
86+
num_queries = min(max(count, 1), 500)
87+
9988
updates = list(zip(
10089
sample(range(1, 10000), num_queries),
10190
sorted(sample(range(1, 10000), num_queries))
10291
))
103-
10492
worlds = [{'id': row_id, 'randomNumber': number} for row_id, number in updates]
105-
106-
async with pool.acquire() as connection:
107-
statement = await connection.prepare(READ_ROW_SQL)
93+
async with connection_pool.acquire() as connection:
94+
statement = await connection.prepare('SELECT id, randomnumber FROM world WHERE id = $1')
10895
for _, row_id in updates:
10996
await statement.fetchval(row_id)
110-
await connection.executemany(WRITE_ROW_SQL, updates)
97+
await connection.executemany('UPDATE world SET randomnumber = $1 WHERE id = $2', updates)
11198
return Response(data=worlds)
11299

113100

114101
@API()
115-
async def plaintext():
102+
def plaintext():
116103
return PlainTextResponse(b'Hello, world!')
117104

118105

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
FROM python:3.11-bullseye
2-
1+
FROM python:3.12 AS builder
32
WORKDIR /panther
3+
RUN python -m venv /opt/venv
4+
RUN pip install --no-cache-dir uv
5+
COPY requirements.txt .
6+
RUN /usr/local/bin/uv pip install -r requirements.txt --python /opt/venv/bin/python
47

5-
COPY ./ /panther
6-
7-
RUN pip3 install -U pip
8-
RUN pip3 install -r /panther/requirements.txt
8+
FROM python:3.12-slim AS production
9+
ENV PYTHONUNBUFFERED=1
10+
ENV PATH="/opt/venv/bin:$PATH"
11+
COPY --from=builder /opt/venv /opt/venv
12+
WORKDIR /panther
13+
COPY . /panther
914

1015
EXPOSE 8080
11-
1216
CMD gunicorn app:app -k uvicorn.workers.UvicornWorker -c panther_conf.py
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
panther==4.3.1
2-
cython==3.0.11
3-
asyncpg==0.29.0
1+
panther==5.0.1
2+
cython==3.1.2
3+
asyncpg==0.30.0
44
gunicorn==23.0.0
5-
uvloop==0.20.0
5+
uvloop==0.21.0

0 commit comments

Comments
 (0)