From 8b352f29c93fef74231bab97974db61109197b20 Mon Sep 17 00:00:00 2001 From: Christian Jensen Date: Tue, 14 Mar 2023 13:58:51 -0700 Subject: [PATCH] Add in FastAPI as a benchmark * Introduce FastAPI as a new benchmark * Add a new gunicorn benchmark for ninja * Remove graph as it becomes stale too easily * Sort imports * Remove unused code from run_test.py * Intentionally unfreeze the requirements.txt - this is to allow for the benchmark to run with the latest versions. --- Dockerfile | 3 ++- README.md | 13 +++++++++++- app_fastapi/main.py | 48 ++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 15 ++++++++++++++ img/results.png | Bin 51900 -> 0 bytes requirements.txt | 25 +++++++++++------------ run_test.py | 36 +++++++++++++-------------------- 7 files changed, 103 insertions(+), 37 deletions(-) create mode 100644 app_fastapi/main.py delete mode 100644 img/results.png diff --git a/Dockerfile b/Dockerfile index 120be1e..e9fbae7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.8.2 +FROM python:3 ENV PYTHONUNBUFFERED=1 PIP_DISABLE_PIP_VERSION_CHECK=on @@ -9,4 +9,5 @@ COPY common_django_settings.py /common_django_settings.py COPY app_drf /app_drf COPY app_flask_marshmallow /app_flask_marshmallow COPY app_ninja /app_ninja +COPY app_fastapi /app_fastapi COPY network_service.py /network_service.py diff --git a/README.md b/README.md index 556f9de..52082dc 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,15 @@ python run_test.py ### Results -![Django Ninja REST Framework](img/results.png) +```text +Framework : 1 2 4 8 16 32 64 +drf_uwsgi : 9.37 18.95 37.15 70.35 123.77 209.73 234.63 +fastapi_gunicorn : 9.57 17.52 36.13 52.74 113.62 208.13 262.85 +fastapi_uvicorn : 9.50 17.94 31.52 55.63 118.94 167.54 194.12 +flask_marshmallow_uwsgi : 9.53 18.75 37.04 72.74 131.16 229.92 326.55 +ninja_gunicorn : 240.49 278.57 317.09 309.32 285.71 246.44 256.98 +ninja_uvicorn : 265.31 289.09 280.00 305.05 247.62 237.71 212.58 +ninja_uwsgi : 9.29 18.56 36.04 68.98 128.32 180.89 182.31 +Columns indicate the number of workers in each run +Values are in requests per second - higher is better. +``` \ No newline at end of file diff --git a/app_fastapi/main.py b/app_fastapi/main.py new file mode 100644 index 0000000..ed6d54b --- /dev/null +++ b/app_fastapi/main.py @@ -0,0 +1,48 @@ +import datetime +from typing import List + +import requests +from fastapi import FastAPI +from pydantic import BaseModel, Field + + +class Location(BaseModel): + latitude: float | None = None + longitude: float | None = None + + +class Skill(BaseModel): + subject: str + subject_id: int + category: str + qual_level: str + qual_level_id: int + qual_level_ranking: float = 0 + + +class Model(BaseModel): + id: int + client_name: str = Field(max_length=255) + sort_index: float + client_phone: str | None = Field(None, max_length=255) + location: Location + contractor: int | None = Field(None, gt=0) + upstream_http_referrer: str | None = Field(None, max_length=1023) + grecaptcha_response: str = Field(min_length=20, max_length=1000) + last_updated: datetime.datetime | None + skills: List[Skill] + + +app = FastAPI() + + +@app.post("/api/create") +async def create(data: Model): + return {"success": True}, 201 + + +@app.get("/api/iojob") +async def iojob(): + response = requests.get('http://network_service:8000/job') + assert response.status_code == 200 + return {"success": True}, 200 diff --git a/docker-compose.yml b/docker-compose.yml index 020a59d..8497a91 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,6 +30,21 @@ services: working_dir: /app_ninja command: uvicorn djninja.asgi:application --host 0.0.0.0 --workers ${WORKERS} + ninja_gunicorn: + <<: *common + working_dir: /app_ninja + command: gunicorn djninja.asgi:application --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 --workers ${WORKERS} + + fastapi_gunicorn: + <<: *common + working_dir: /app_fastapi + command: gunicorn main:app --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 --workers ${WORKERS} + + fastapi_uvicorn: + <<: *common + working_dir: /app_fastapi + command: uvicorn main:app --host 0.0.0.0 --workers ${WORKERS} + network_service: build: . command: python network_service.py > /dev/null diff --git a/img/results.png b/img/results.png deleted file mode 100644 index 1310776184326fffa17c8f20a12a6ef7a2b6369d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51900 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', end='') - print('') + + print() + for framework, results in sorted(results.items()): print(f'{framework:<23} :', end='') for w in WORKERS_CASES: print(f'{results[w][0]:>9}', end='') - print('') + print() + print('Columns indicate the number of workers in each run') + print('Values are in requests per second - higher is better.') if __name__ == '__main__': main()