Пример #1
0
async def test_wsgi_stops_iterating_after_content_length_bytes():
    """
    Makes sure WsgiToAsgi does not iterate after than Content-Length bytes
    """
    def wsgi_application(environ, start_response):
        start_response("200 OK", [("Content-Length", "4")])
        yield b"0123"
        pytest.fail("WsgiToAsgi should not iterate after Content-Length bytes")
        yield b"4567"

    application = WsgiToAsgi(wsgi_application)
    instance = ApplicationCommunicator(
        application,
        {
            "type": "http",
            "http_version": "1.0",
            "method": "GET",
            "path": "/",
            "query_string": b"",
            "headers": [],
        },
    )
    await instance.send_input({"type": "http.request"})
    assert (await instance.receive_output(1)) == {
        "type": "http.response.start",
        "status": 200,
        "headers": [(b"content-length", b"4")],
    }
    assert (await instance.receive_output(1)) == {
        "type": "http.response.body",
        "body": b"0123",
        "more_body": True,
    }
    assert (await instance.receive_output(1)) == {"type": "http.response.body"}
Пример #2
0
    def __init__(self,
                 app: Union[ASGIFramework, 'WSGIApplication'],
                 *,
                 termination_policy: Optional[TerminationPolicy] = None,
                 port: Optional[int] = None):
        if not is_async_callable(app):
            app = WsgiToAsgi(app)

        if termination_policy is None:
            termination_policy = DEFAULT_TERMINATION_POLICY

        if port is None:
            try:
                port = int(os.environ['PORT'])
            except KeyError:
                port = DEFAULT_PORT
            except ValueError:
                raise PortParseError()

        self._app = cast(ASGIFramework, app)
        self._config = Config()
        self._config.bind = [f'0.0.0.0:{port}']
        self._sockets = self._config.create_sockets()
        self._termination_policy = termination_policy
        self._task = None
Пример #3
0
async def test_wsgi_empty_body():
    """
    Makes sure WsgiToAsgi handles an empty body response correctly
    """
    def wsgi_application(environ, start_response):
        start_response("200 OK", [])
        return []

    application = WsgiToAsgi(wsgi_application)
    instance = ApplicationCommunicator(
        application,
        {
            "type": "http",
            "http_version": "1.0",
            "method": "GET",
            "path": "/",
            "query_string": b"",
            "headers": [],
        },
    )
    await instance.send_input({"type": "http.request"})

    # response.start should always be send
    assert (await instance.receive_output(1)) == {
        "type": "http.response.start",
        "status": 200,
        "headers": [],
    }

    assert (await instance.receive_output(1)) == {"type": "http.response.body"}
Пример #4
0
    def __call__(self, scope):
        path = scope["path"]
        root_path = scope.get("root_path", "")

        # Call into a submounted app, if one exists.
        for path_prefix, app in self.apps.items():
            if path.startswith(path_prefix):
                scope["path"] = path[len(path_prefix):]
                scope["root_path"] = root_path + path_prefix
                try:
                    return app(scope)
                except TypeError:
                    app = WsgiToAsgi(app)
                    return app(scope)

        return self.app(scope)
Пример #5
0
async def test_basic_wsgi():
    """
    Makes sure the WSGI wrapper has basic functionality.
    """

    # Define WSGI app
    def wsgi_application(environ, start_response):
        assert environ["HTTP_TEST_HEADER"] == "test value"
        start_response("200 OK", [["X-Colour", "Blue"]])
        yield b"first chunk "
        yield b"second chunk"

    # Wrap it
    application = WsgiToAsgi(wsgi_application)
    # Launch it as a test application
    instance = ApplicationCommunicator(
        application, {
            "type": "http",
            "http_version": "1.0",
            "method": "GET",
            "path": "/foo/",
            "query_string": b"bar=baz",
            "headers": [[b"test-header", b"test value"]],
        })
    await instance.send_input({
        "type": "http.request",
    })
    # Check they send stuff
    assert (await instance.receive_output(1)) == {
        "type": "http.response.start",
        "status": 200,
        "headers": [(b"X-Colour", b"Blue")],
    }
    assert (await instance.receive_output(1)) == {
        "type": "http.response.body",
        "body": b"first chunk ",
        "more_body": True,
    }
    assert (await instance.receive_output(1)) == {
        "type": "http.response.body",
        "body": b"second chunk",
        "more_body": True,
    }
    assert (await instance.receive_output(1)) == {
        "type": "http.response.body",
    }
Пример #6
0
def construct_app():
    flask = App(__name__)
    flask.load()
    flask.load_phase_2()

    api_v2 = APIv2(flask)

    _setup_context(flask)

    routes = [
        Route("/api/v2", endpoint=redirect),
        Mount("/api/v2/", app=api_v2),
        Mount("/", app=WsgiToAsgi(flask)),
    ]

    app = Starlette(routes=routes, debug=True)
    flask.run_hook("asgi-setup", app)
    return app
Пример #7
0
async def test_wsgi_clamped_body():
    """
    Makes sure WsgiToAsgi clamps a body response longer than Content-Length
    """
    def wsgi_application(environ, start_response):
        start_response("200 OK", [("Content-Length", "8")])
        return [b"0123", b"45", b"6789"]

    application = WsgiToAsgi(wsgi_application)
    instance = ApplicationCommunicator(
        application,
        {
            "type": "http",
            "http_version": "1.0",
            "method": "GET",
            "path": "/",
            "query_string": b"",
            "headers": [],
        },
    )
    await instance.send_input({"type": "http.request"})
    assert (await instance.receive_output(1)) == {
        "type": "http.response.start",
        "status": 200,
        "headers": [(b"content-length", b"8")],
    }
    assert (await instance.receive_output(1)) == {
        "type": "http.response.body",
        "body": b"0123",
        "more_body": True,
    }
    assert (await instance.receive_output(1)) == {
        "type": "http.response.body",
        "body": b"45",
        "more_body": True,
    }
    assert (await instance.receive_output(1)) == {
        "type": "http.response.body",
        "body": b"67",
        "more_body": True,
    }
    assert (await instance.receive_output(1)) == {"type": "http.response.body"}
Пример #8
0
    def on_add_routes(self, route_table):
        db = self.app.database

        api = APIv1(db)

        # Register all views in schema
        for tbl in db.entity_names(schema="core_view"):
            if tbl.endswith("_tree"):
                continue
            api.build_route(tbl, schema="core_view")

        for tbl in db.entity_names(schema="lab_view"):
            api.build_route(tbl, schema="lab_view")

        self.api = api
        self._flask = App(self.app, __name__)
        self._flask.register_blueprint(api.blueprint, url_prefix="")
        self._flask.config["RESTFUL_JSON"] = dict(cls=JSONEncoder)
        route_table.append(Mount("/api/v1/", WsgiToAsgi(self._flask)))
        self.app.run_hook("api-v1-initialized", api)
Пример #9
0
async def test_wsgi_path_encoding():
    """
    Makes sure the WSGI wrapper has basic functionality.
    """

    # Define WSGI app
    def wsgi_application(environ, start_response):
        assert environ["SCRIPT_NAME"] == "/中国".encode("utf8").decode("latin-1")
        assert environ["PATH_INFO"] == "/中文".encode("utf8").decode("latin-1")
        start_response("200 OK", [])
        yield b""

    # Wrap it
    application = WsgiToAsgi(wsgi_application)
    # Launch it as a test application
    instance = ApplicationCommunicator(
        application,
        {
            "type": "http",
            "http_version": "1.0",
            "method": "GET",
            "path": "/中文",
            "root_path": "/中国",
            "query_string": b"bar=baz",
            "headers": [],
        },
    )
    await instance.send_input({"type": "http.request"})
    # Check they send stuff
    assert (await instance.receive_output(1)) == {
        "type": "http.response.start",
        "status": 200,
        "headers": [],
    }
    assert (await instance.receive_output(1)) == {
        "type": "http.response.body",
        "body": b"",
        "more_body": True,
    }
    assert (await instance.receive_output(1)) == {"type": "http.response.body"}
Пример #10
0
async def test_receive_nothing():
    """
    Tests ApplicationCommunicator.receive_nothing to return the correct value.
    """

    # Get an ApplicationCommunicator instance
    def wsgi_application(environ, start_response):
        start_response("200 OK", [])
        yield b"content"

    application = WsgiToAsgi(wsgi_application)
    instance = ApplicationCommunicator(
        application,
        {
            "type": "http",
            "http_version": "1.0",
            "method": "GET",
            "path": "/foo/",
            "query_string": b"bar=baz",
            "headers": [],
        },
    )

    # No event
    assert await instance.receive_nothing() is True

    # Produce 3 events to receive
    await instance.send_input({"type": "http.request"})
    # Start event of the response
    assert await instance.receive_nothing() is False
    await instance.receive_output()
    # First body event of the response announcing further body event
    assert await instance.receive_nothing() is False
    await instance.receive_output()
    # Last body event of the response
    assert await instance.receive_nothing() is False
    await instance.receive_output()
    # Response received completely
    assert await instance.receive_nothing(0.01) is True
Пример #11
0
async def test_wsgi_multi_body():
    """
    Verify that multiple http.request events with body parts are all delivered
    to the WSGI application.
    """
    def wsgi_application(environ, start_response):
        infp = environ["wsgi.input"]
        body = infp.read(12)
        assert body == b"Hello World!"
        start_response("200 OK", [])
        return []

    application = WsgiToAsgi(wsgi_application)
    instance = ApplicationCommunicator(
        application,
        {
            "type": "http",
            "http_version": "1.0",
            "method": "POST",
            "path": "/",
            "query_string": b"",
            "headers": [[b"content-length", b"12"]],
        },
    )
    await instance.send_input({
        "type": "http.request",
        "body": b"Hello ",
        "more_body": True
    })
    await instance.send_input({"type": "http.request", "body": b"World!"})

    assert (await instance.receive_output(1)) == {
        "type": "http.response.start",
        "status": 200,
        "headers": [],
    }

    assert (await instance.receive_output(1)) == {"type": "http.response.body"}
Пример #12
0
    def __call__(self, scope):
        path = scope["path"]
        root_path = scope.get("root_path", "")

        # Call into a submounted app, if one exists.
        for path_prefix, app in self.apps.items():
            if path.startswith(path_prefix):
                scope["path"] = path[len(path_prefix):]
                scope["root_path"] = root_path + path_prefix
                try:
                    return app(scope)
                except TypeError:
                    app = WsgiToAsgi(app)
                    return app(scope)

        # Call the main dispatcher.
        async def asgi(receive, send):
            nonlocal scope, self

            req = models.Request(scope, receive=receive)
            resp = await self._dispatch_request(req)
            await resp(receive, send)

        return asgi
Пример #13
0
async def test_wsgi_multiple_start_response():
    """
    Makes sure WsgiToAsgi only keep Content-Length from the last call to start_response
    """
    def wsgi_application(environ, start_response):
        start_response("200 OK", [("Content-Length", "5")])
        try:
            raise ValueError("Application Error")
        except ValueError:
            start_response("500 Server Error", [], sys.exc_info())
            return [b"Some long error message"]

    application = WsgiToAsgi(wsgi_application)
    instance = ApplicationCommunicator(
        application,
        {
            "type": "http",
            "http_version": "1.0",
            "method": "GET",
            "path": "/",
            "query_string": b"",
            "headers": [],
        },
    )
    await instance.send_input({"type": "http.request"})
    assert (await instance.receive_output(1)) == {
        "type": "http.response.start",
        "status": 500,
        "headers": [],
    }
    assert (await instance.receive_output(1)) == {
        "type": "http.response.body",
        "body": b"Some long error message",
        "more_body": True,
    }
    assert (await instance.receive_output(1)) == {"type": "http.response.body"}
Пример #14
0
def padding(request):
    """
    Dynamically generated data, maximum 50MB.
    """
    size = min(50000000, request.path_params["size"])
    return PlainTextResponse("Z" * size)


@app.websocket_route("/ws")
async def ws(websocket):
    """
    WebSocket echo endpoint.
    """
    if "chat" in websocket.scope["subprotocols"]:
        subprotocol = "chat"
    else:
        subprotocol = None
    await websocket.accept(subprotocol=subprotocol)

    try:
        while True:
            message = await websocket.receive_text()
            await websocket.send_text(message)
    except WebSocketDisconnect:
        pass


app.mount("/httpbin", WsgiToAsgi(httpbin.app))

app.mount("/", StaticFiles(directory=os.path.join(ROOT, "htdocs"), html=True))
Пример #15
0
    start_response(status, headers)
    return [body]


@pytest.fixture(scope="module", autouse=True)
def print_title():
    print(f"\n{'Name':^30}", "Average Time", end="", flush=True)


@pytest.mark.parametrize(
    "app, name",
    [
        (asgi_echo, "pure-ASGI"),
        (WSGIMiddleware(wsgi_echo), "a2wsgi-WSGIMiddleware"),
        (UvicornWSGIMiddleware(wsgi_echo), "uvicorn-WSGIMiddleware"),
        (WsgiToAsgi(wsgi_echo), "asgiref-WsgiToAsgi"),
    ],
)
@pytest.mark.asyncio
async def test_convert_wsgi_to_asgi(app, name):
    async with httpx.AsyncClient(app=app,
                                 base_url="http://testserver") as client:
        start_time = time.time_ns()
        await asyncio.gather(
            *[client.post("/", data=b"hello world") for _ in range(100)])
        time_count_100 = time.time_ns() - start_time
        start_time = time.time_ns()
        await asyncio.gather(
            *[client.post("/", data=b"hello world") for _ in range(10100)])
        time_count_100100 = time.time_ns() - start_time
        print(
Пример #16
0

# 定义 WSGI 程序
def wsgi(environ, start_response):
    status = '200 OK'
    output = b'Hello WSGI in WSGI!'

    response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)

    return [output]


# 将 WSGI 包装为 ASGI
wsgi_to_asgi_app = WsgiToAsgi(wsgi)


async def application(scope, receive, send):
    # 获取请求类型
    request_type = scope['type']

    # 如果是 http 类型的请求,则由该程序段处理
    if request_type == 'http':
        # 如果路径以 /socket.io 开始,则使用 socket.io app 进行处理
        if scope['path'].startswith("/socket.io"):
            return await sio_asgi_app(scope, receive, send)

        # 如果路径以 /wsgi 开始,则由 asgiref 将请求转交给wsgi程序处理
        if scope['path'].startswith("/wsgi"):
            return await wsgi_to_asgi_app(scope, receive, send)
Пример #17
0
def create_asgi_app():
    """
    create the asgi appliaction to run the project 
    using any asgi server like uvicorn.
    """
    return WsgiToAsgi(create_wsgi_app())
Пример #18
0
from Statistics import app
from asgiref.wsgi import WsgiToAsgi

app = WsgiToAsgi(app)
Пример #19
0
    return response


with Configurator(settings=settings) as pyramid_config:
    pyramid_config.add_route("employees", "/employees")
    pyramid_config.add_view(employees, route_name="employees")

    engine = db.create_engine("sqlite:///employees.db")
    models.initialize_sql(engine)
    session_factory = get_session_factory(engine)
    pyramid_config.registry['dbsession_factory'] = session_factory

    pyramid_config.include('pyramid_tm')
    pyramid_config.include('pyramid_retry')
    pyramid_config.add_request_method(
        lambda r: get_tm_session(session_factory, r.tm),
        'dbsession',
        reify=True)

    initialize(statsd_host=os.getenv("DATADOG_HOST"),
               statsd_port=8125,
               host_name="pyramid")
    tracer.configure(hostname=os.getenv("DATADOG_HOST"),
                     port=8126,
                     enabled=True)
    trace_pyramid(pyramid_config)
    patch(sqlalchemy=True, logging=True, sqlite3=True)
    wsgi_app = pyramid_config.make_wsgi_app()

app = WsgiToAsgi(wsgi_app)
Пример #20
0
 def on_finalize_routes(self):
     app = Flask(__name__)
     app.register_blueprint(web, url_prefix="/")
     self.app.mount("/", WsgiToAsgi(app))
Пример #21
0
import httpbin
from asgiref.wsgi import WsgiToAsgi

app = WsgiToAsgi(httpbin.app)
Пример #22
0
 def __init__(self, wsgi_app) -> None:
     super().__init__(WsgiToAsgi(wsgi_app))
import os

from asgiref.wsgi import WsgiToAsgi

from asgi_middleware_static_file import ASGIMiddlewareStaticFile

BASE_DIR = os.path.dirname(__name__)
STATIC_DIRS = [os.path.join(BASE_DIR, "example_static")]


def wsgi_app(environ, start_response):
    status = "200 OK"
    response_headers = [("Content-type", "text/plain")]
    start_response(status, response_headers)
    return ["Hello world!"]


app = ASGIMiddlewareStaticFile(WsgiToAsgi(wsgi_app),
                               static_url="static",
                               static_root_paths=STATIC_DIRS)