Browse Source

Uvicorn (#2848)

* Added uvicorn, an asyncio server for Python 3.

* Include uvicorn in .travis.yml

* Fix content-type on json test case

* Write pid file to /tmp

* Fix content-type of JSON test type
Tom Christie 8 years ago
parent
commit
95eca14e8f

+ 1 - 0
.travis.yml

@@ -163,6 +163,7 @@ env:
     - "TESTDIR=Python/pyramid"
     - "TESTDIR=Python/pyramid"
     - "TESTDIR=Python/tornado"
     - "TESTDIR=Python/tornado"
     - "TESTDIR=Python/turbogears"
     - "TESTDIR=Python/turbogears"
+    - "TESTDIR=Python/uvicorn"
     - "TESTDIR=Python/uwsgi"
     - "TESTDIR=Python/uwsgi"
     - "TESTDIR=Python/web2py"
     - "TESTDIR=Python/web2py"
     - "TESTDIR=Python/weppy"
     - "TESTDIR=Python/weppy"

+ 34 - 0
frameworks/Python/uvicorn/README.md

@@ -0,0 +1,34 @@
+# Uvicorn Benchmark Test
+
+This is the Uvicorn portion of a [benchmarking tests suite](../../)
+comparing a variety of web development platforms.
+
+The information below is specific to Uvicorn. For further guidance,
+review the [documentation](http://frameworkbenchmarks.readthedocs.org/en/latest/).
+Also note that there is additional information provided in
+the [Python README](../).
+
+## Description
+
+[Uvicorn](https://github.com/tomchristie/uvicorn) is a lightning fast
+asyncio server for Python 3.
+
+## Implementation
+
+Uvicorn is implemented using:
+
+* Gunicorn for process managment.
+* The uvloop event loop.
+* The httptools HTTP parsing library.
+* The ASGI consumer interface, for interacting with the application layer.
+
+## Test Paths & Sources
+
+All of the test implementations are located within a single file ([app.py](app.py)).
+
+* [JSON Serialization](app.py): "/json"
+* [Plaintext](app.py): "/plaintext"
+
+## Resources
+
+* [Repo](https://github.com/tomchristie/uvicorn)

+ 48 - 0
frameworks/Python/uvicorn/app.py

@@ -0,0 +1,48 @@
+import ujson as json
+
+
+def json_endpoint(message):
+    content = json.dumps({'message': 'Hello, world!'}).encode('utf-8')
+    response = {
+        'status': 200,
+        'headers': [
+            [b'content-type', b'application/json'],
+        ],
+        'content': content
+    }
+    message['reply_channel'].send(response)
+
+
+def plaintext_endpoint(message):
+    content = b'Hello, world!'
+    response = {
+        'status': 200,
+        'headers': [
+            [b'content-type', b'text/plain'],
+        ],
+        'content': content
+    }
+    message['reply_channel'].send(response)
+
+
+def handle_404(message):
+    content = b'Not found'
+    response = {
+        'status': 404,
+        'headers': [
+            [b'content-type', b'text/plain'],
+        ],
+        'content': content
+    }
+    message['reply_channel'].send(response)
+
+
+routes = {
+    '/json': json_endpoint,
+    '/plaintext': plaintext_endpoint
+}
+
+
+def main(message):
+    path = message['content']['path']
+    routes.get(path, handle_404)(message)

+ 24 - 0
frameworks/Python/uvicorn/benchmark_config.json

@@ -0,0 +1,24 @@
+{
+  "framework": "uvicorn",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "json_url": "/json",
+      "plaintext_url": "/plaintext",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "framework": "uvicorn",
+      "language": "Python",
+      "flavor": "Python3",
+      "platform": "None",
+      "webserver": "None",
+      "os": "Linux",
+      "orm": "Raw",
+      "database_os": "Linux",
+      "database": "None",
+      "display_name": "uvicorn",
+      "notes": ""
+    }
+  }]
+}

+ 2 - 0
frameworks/Python/uvicorn/requirements.txt

@@ -0,0 +1,2 @@
+uvicorn==0.0.4
+ujson==1.35

+ 7 - 0
frameworks/Python/uvicorn/setup.sh

@@ -0,0 +1,7 @@
+#!/bin/bash
+
+fw_depends python3
+
+pip3 install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
+
+uvicorn app:main -c uvicorn_conf.py &

+ 13 - 0
frameworks/Python/uvicorn/uvicorn_conf.py

@@ -0,0 +1,13 @@
+import multiprocessing
+import os
+
+_is_travis = os.environ.get('TRAVIS') == 'true'
+
+workers = multiprocessing.cpu_count()
+if _is_travis:
+    workers = 2
+
+bind = "0.0.0.0:8080"
+keepalive = 120
+errorlog = '-'
+pidfile = '/tmp/uvicorn.pid'