Browse Source

[Python] fastapi fix gunicorn, add socketify-asgi (#7781)

* Added a benchmark test for the socketify.py Python/PyPy web framework

* removed alpine docker

* updated readme.md

* No need to manually add Date header anymore on Socketify.py

* updated socketify.py benchmark to use object factories to increase performance

* add object factory to app-python3.py in socketify

* [Python] Update socketify.py with ASGI and SSGI, add Falcon ASGI SSGI with socketify.py

* fix merge erros

* remove \n from plaintext in socketify.py-wsgi plaintext

* [Python] fastapi fix gunicorn, add socketify-asgi

* make gunicorn+uvicorn default

* fix pypy json benchmark
Ciro Spaciari 2 years ago
parent
commit
4224e8f355

+ 47 - 0
frameworks/Python/fastapi/app-socketify-asgi.py

@@ -0,0 +1,47 @@
+import os
+import multiprocessing
+import logging
+from fastapi import FastAPI, Request
+from fastapi.responses import PlainTextResponse
+from socketify import ASGI
+
+
+try:
+    import orjson
+    from fastapi.responses import ORJSONResponse as JSONResponse
+except ImportError:
+    from fastapi.responses import JSONResponse as JSONResponse
+
+app = FastAPI()
+
[email protected]("/json")
+async def json_serialization():
+    return JSONResponse({"message": "Hello, world!"})
+
[email protected]("/plaintext")
+async def plaintext():
+    return PlainTextResponse(b"Hello, world!")
+
+
+_is_travis = os.environ.get('TRAVIS') == 'true'
+
+workers = int(multiprocessing.cpu_count())
+if _is_travis:
+    workers = 2
+
+def run_app():
+    ASGI(app).listen(8080, lambda config: logging.info(f"Listening on port http://localhost:{config.port} now\n")).run()
+
+
+def create_fork():
+    n = os.fork()
+    # n greater than 0 means parent process
+    if not n > 0:
+        run_app()
+
+
+# fork limiting the cpu count - 1
+for i in range(1, workers):
+    create_fork()
+
+run_app()  # run app on the main process too :)

+ 38 - 0
frameworks/Python/fastapi/benchmark_config.json

@@ -24,6 +24,44 @@
         "notes": "",
         "notes": "",
         "versus": "None"
         "versus": "None"
       },
       },
+      "socketify-asgi": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "Postgres",
+        "framework": "FastAPI",
+        "language": "Python",
+        "flavor": "Python3",
+        "orm": "Raw",
+        "platform": "asyncio",
+        "webserver": "Socketify.py",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "FastAPI [Socketify.py ASGI]",
+        "notes": "",
+        "versus": "None"
+      },
+      "socketify-asgi-pypy": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "Postgres",
+        "framework": "FastAPI",
+        "language": "Python",
+        "flavor": "Python3",
+        "orm": "Raw",
+        "platform": "asyncio",
+        "webserver": "Socketify.py",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "FastAPI [Socketify.py ASGI PyPy3]",
+        "notes": "",
+        "versus": "None"
+      },
       "gunicorn-orjson": {
       "gunicorn-orjson": {
         "json_url": "/json",
         "json_url": "/json",
         "fortune_url": "/fortunes",
         "fortune_url": "/fortunes",

+ 26 - 0
frameworks/Python/fastapi/config.toml

@@ -18,6 +18,32 @@ platform = "None"
 webserver = "Gunicorn"
 webserver = "Gunicorn"
 versus = "None"
 versus = "None"
 
 
+[socketify-asgi-pypy]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+database = "Postgres"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "None"
+webserver = "Socketify.py"
+versus = "None"
+
+[socketify-asgi]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+database = "Postgres"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "None"
+webserver = "Socketify.py"
+versus = "None"
+
 [gunicorn-orjson]
 [gunicorn-orjson]
 urls.plaintext = "/plaintext"
 urls.plaintext = "/plaintext"
 urls.json = "/json"
 urls.json = "/json"

+ 16 - 0
frameworks/Python/fastapi/fastapi-socketify-asgi-pypy.dockerfile

@@ -0,0 +1,16 @@
+FROM pypy:3.9-bullseye
+
+WORKDIR /fastapi
+
+RUN python -m venv /opt/venv
+ENV PATH="/opt/venv/bin:$PATH"
+
+COPY requirements-socketify-pypy.txt ./
+RUN apt-get update; apt-get install libuv1 -y
+RUN pip3 install -r requirements-socketify-pypy.txt
+
+COPY . ./
+
+EXPOSE 8080
+
+CMD python ./app-socketify-asgi.py

+ 19 - 0
frameworks/Python/fastapi/fastapi-socketify-asgi.dockerfile

@@ -0,0 +1,19 @@
+FROM python:3.10-bullseye
+
+WORKDIR /fastapi
+
+RUN python -m venv /opt/venv
+ENV PATH="/opt/venv/bin:$PATH"
+
+RUN apt-get update; apt-get install libuv1 -y
+RUN pip3 install cython==0.29.32
+
+COPY requirements-socketify.txt ./
+
+RUN pip3 install -r requirements-socketify.txt
+
+COPY . ./
+
+EXPOSE 8080
+
+CMD python ./app-socketify-asgi.py

+ 0 - 0
frameworks/Python/fastapi/fastapi-gunicorn.dockerfile → frameworks/Python/fastapi/fastapi.dockerfile


+ 2 - 0
frameworks/Python/fastapi/requirements-socketify-pypy.txt

@@ -0,0 +1,2 @@
+fastapi==0.88.0
+git+https://github.com/cirospaciari/socketify.py.git@main#socketify

+ 3 - 0
frameworks/Python/fastapi/requirements-socketify.txt

@@ -0,0 +1,3 @@
+orjson==3.8.0
+fastapi==0.88.0
+git+https://github.com/cirospaciari/socketify.py.git@main#socketify