Skip to content

Commit

Permalink
Better support for ASGI building
Browse files Browse the repository at this point in the history
  • Loading branch information
joamag committed Nov 11, 2019
1 parent 7fb00fb commit 7bb2160
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/appier/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
from .base import APP, LEVEL, NAME, VERSION, PLATFORM, IDENTIFIER_SHORT, IDENTIFIER_LONG, IDENTIFIER,\
API_VERSION, BUFFER_SIZE, MAX_LOG_SIZE, MAX_LOG_COUNT, App, APIApp, WebApp, Template, get_app, get_name,\
get_base_path, get_cache, get_preferences, get_bus, get_request, get_session, get_model, get_controller, get_part,\
get_adapter, get_manager, get_logger, get_level, is_loaded, is_devel, is_safe, to_locale, on_exit
get_adapter, get_manager, get_logger, get_level, is_loaded, is_devel, is_safe, to_locale, on_exit, build_asgi
from .bus import Bus, MemoryBus, RedisBus
from .cache import Cache, MemoryCache, FileCache, RedisCache, SerializedCache
from .component import Component
Expand Down
36 changes: 34 additions & 2 deletions src/appier/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
""" The license for the module """

import io
import tempfile

from . import util
from . import exceptions

class ASGIApp(object):
Expand Down Expand Up @@ -97,6 +99,8 @@ async def asgi_lifespan(self, scope, receive, send):

async def asgi_http(self, scope, receive, send):
self.prepare()
body = await self._build_body(receive)
environ = await self._build_environ(scope, body)
try:
await send({
"type": "http.response.start",
Expand All @@ -112,7 +116,30 @@ async def asgi_http(self, scope, receive, send):
finally:
self.restore()

def build_environ(self, scope, body):
def start_response(self, status, headers):
code = status.split(" ", 1)[0]
code = int(code)
headers = [
(name.lower().encode("ascii"), value.encode("ascii"))
for name, value in headers
]
self.response_start = {
"type": "http.response.start",
"status": code,
"headers": headers
}

async def _build_body(self, receive):
with tempfile.SpooledTemporaryFile(max_size = 65536) as body:
while True:
message = await receive()
util.verify(message["type"] == "http.request")
body.write(message.get("body", b""))
if not message.get("more_body"): break
body.seek(0)
return body

async def _build_environ(self, scope, body):
"""
Builds a scope and request body into a WSGI environ object.
Expand Down Expand Up @@ -151,7 +178,7 @@ def build_environ(self, scope, body):
if "client" in scope:
environ["REMOTE_ADDR"] = scope["client"][0]

for name, value in self.scope.get("headers", []):
for name, value in scope.get("headers", []):
name = name.decode("latin1")
if name == "content-length":
corrected_name = "CONTENT_LENGTH"
Expand All @@ -166,3 +193,8 @@ def build_environ(self, scope, body):
environ[corrected_name] = value

return environ

def build_asgi(app_cls):
async def app_asgi(scope, receive, send):
return await app_cls.asgi_entry(scope, receive, send)
return app_asgi
3 changes: 3 additions & 0 deletions src/appier/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@
if legacy.PYTHON_ASYNC:
from . import asgi
EXTRA_CLS.append(asgi.ASGIApp)
build_asgi = asgi.build_asgi
else:
build_asgi = None

class App(
legacy.with_meta(
Expand Down

0 comments on commit 7bb2160

Please sign in to comment.