From: Rafał Pitoń Date: Fri, 14 Jun 2019 10:53:17 +0000 (+0200) Subject: Simplify example apps code to plain functions X-Git-Tag: 0.12.2~13^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F543%2Fhead;p=thirdparty%2Fstarlette.git Simplify example apps code to plain functions --- diff --git a/docs/index.md b/docs/index.md index ed40fb22..ec23b6e1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -97,20 +97,16 @@ an ASGI toolkit. You can use any of its components independently. from starlette.responses import PlainTextResponse -class App: - def __init__(self, scope): - assert scope['type'] == 'http' - self.scope = scope - - async def __call__(self, receive, send): - response = PlainTextResponse('Hello, world!') - await response(self.scope, receive, send) +async def app(scope, receive, send): + assert scope['type'] == 'http' + response = PlainTextResponse('Hello, world!') + await response(scope, receive, send) ``` -Run the `App` application in `example.py`: +Run the `app` application in `example.py`: ```shell -$ uvicorn example:App +$ uvicorn example:app INFO: Started server process [11509] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` diff --git a/docs/requests.md b/docs/requests.md index e432793a..5c9caa61 100644 --- a/docs/requests.md +++ b/docs/requests.md @@ -11,16 +11,12 @@ from starlette.requests import Request from starlette.responses import Response -class App: - def __init__(self, scope): - assert scope['type'] == 'http' - self.scope = scope - - async def __call__(self, receive, send): - request = Request(self.scope, receive) - content = '%s %s' % (request.method, request.url.path) - response = Response(content, media_type='text/plain') - await response(self.scope, receive, send) +async def app(scope, receive, send): + assert scope['type'] == 'http' + request = Request(scope, receive) + content = '%s %s' % (request.method, request.url.path) + response = Response(content, media_type='text/plain') + await response(scope, receive, send) ``` Requests present a mapping interface, so you can use them in the same @@ -93,19 +89,15 @@ You can also access the request body as a stream, using the `async for` syntax: from starlette.requests import Request from starlette.responses import Response - -class App: - def __init__(self, scope): - assert scope['type'] == 'http' - self.scope = scope - - async def __call__(self, receive, send): - request = Request(self.scope, receive) - body = b'' - async for chunk in request.stream(): - body += chunk - response = Response(body, media_type='text/plain') - await response(self.scope, receive, send) + +async def app(scope, receive, send): + assert scope['type'] == 'http' + request = Request(scope, receive) + body = b'' + async for chunk in request.stream(): + body += chunk + response = Response(body, media_type='text/plain') + await response(scope, receive, send) ``` If you access `.stream()` then the byte chunks are provided without storing diff --git a/docs/responses.md b/docs/responses.md index 91a5734f..ff4574c4 100644 --- a/docs/responses.md +++ b/docs/responses.md @@ -22,14 +22,10 @@ ASGI application instance. from starlette.responses import Response -class App: - def __init__(self, scope): - assert scope['type'] == 'http' - self.scope = scope - - async def __call__(self, receive, send): - response = Response('Hello, world!', media_type='text/plain') - await response(self.scope, receive, send) +async def app(scope, receive, send): + assert scope['type'] == 'http' + response = Response('Hello, world!', media_type='text/plain') + await response(scope, receive, send) ``` #### Set Cookie @@ -61,14 +57,10 @@ Takes some text or bytes and returns an HTML response. from starlette.responses import HTMLResponse -class App: - def __init__(self, scope): - assert scope['type'] == 'http' - self.scope = scope - - async def __call__(self, receive, send): - response = HTMLResponse('

Hello, world!

') - await response(self.scope, receive, send) +async def app(scope, receive, send): + assert scope['type'] == 'http' + response = HTMLResponse('

Hello, world!

') + await response(scope, receive, send) ``` ### PlainTextResponse @@ -79,14 +71,10 @@ Takes some text or bytes and returns an plain text response. from starlette.responses import PlainTextResponse -class App: - def __init__(self, scope): - assert scope['type'] == 'http' - self.scope = scope - - async def __call__(self, receive, send): - response = PlainTextResponse('Hello, world!') - await response(self.scope, receive, send) +async def app(scope, receive, send): + assert scope['type'] == 'http' + response = PlainTextResponse('Hello, world!') + await response(scope, receive, send) ``` ### JSONResponse @@ -97,14 +85,10 @@ Takes some data and returns an `application/json` encoded response. from starlette.responses import JSONResponse -class App: - def __init__(self, scope): - assert scope['type'] == 'http' - self.scope = scope - - async def __call__(self, receive, send): - response = JSONResponse({'hello': 'world'}) - await response(self.scope, receive, send) +async def app(scope, receive, send): + assert scope['type'] == 'http' + response = JSONResponse({'hello': 'world'}) + await response(scope, receive, send) ``` ### UJSONResponse @@ -121,14 +105,10 @@ you are micro-optimising a particular endpoint. from starlette.responses import UJSONResponse -class App: - def __init__(self, scope): - assert scope['type'] == 'http' - self.scope = scope - - async def __call__(self, receive, send): - response = UJSONResponse({'hello': 'world'}) - await response(self.scope, receive, send) +async def app(scope, receive, send): + assert scope['type'] == 'http' + response = UJSONResponse({'hello': 'world'}) + await response(scope, receive, send) ``` ### RedirectResponse @@ -139,17 +119,13 @@ Returns an HTTP redirect. Uses a 302 status code by default. from starlette.responses import PlainTextResponse, RedirectResponse -class App: - def __init__(self, scope): - assert scope['type'] == 'http' - self.scope = scope - - async def __call__(self, receive, send): - if self.scope['path'] != '/': - response = RedirectResponse(url='/') - else: - response = PlainTextResponse('Hello, world!') - await response(self.scope, receive, send) +async def app(scope, receive, send): + assert scope['type'] == 'http' + if scope['path'] != '/': + response = RedirectResponse(url='/') + else: + response = PlainTextResponse('Hello, world!') + await response(scope, receive, send) ``` ### StreamingResponse @@ -169,15 +145,11 @@ async def slow_numbers(minimum, maximum): yield('') -class App: - def __init__(self, scope): - assert scope['type'] == 'http' - self.scope = scope - - async def __call__(self, receive, send): - generator = slow_numbers(1, 10) - response = StreamingResponse(generator, media_type='text/html') - await response(self.scope, receive, send) +async def app(scope, receive, send): + assert scope['type'] == 'http' + generator = slow_numbers(1, 10) + response = StreamingResponse(generator, media_type='text/html') + await response(scope, receive, send) ``` Have in mind that file-like objects (like those created by `open()`) are normal iterators. So, you can return them directly in a `StreamingResponse`. @@ -199,12 +171,8 @@ File responses will include appropriate `Content-Length`, `Last-Modified` and `E from starlette.responses import FileResponse -class App: - def __init__(self, scope): - assert scope['type'] == 'http' - self.scope = scope - - async def __call__(self, receive, send): - response = FileResponse('statics/favicon.ico') - await response(self.scope, receive, send) +async def app(scope, receive, send): + assert scope['type'] == 'http' + response = FileResponse('statics/favicon.ico') + await response(scope, receive, send) ``` diff --git a/docs/testclient.md b/docs/testclient.md index 97a39a60..0b4e78e7 100644 --- a/docs/testclient.md +++ b/docs/testclient.md @@ -7,18 +7,14 @@ from starlette.responses import HTMLResponse from starlette.testclient import TestClient -class App: - def __init__(self, scope): - assert scope['type'] == 'http' - self.scope = scope - - async def __call__(self, receive, send): - response = HTMLResponse('Hello, world!') - await response(self.scope, receive, send) +async def app(scope, receive, send): + assert scope['type'] == 'http' + response = HTMLResponse('Hello, world!') + await response(scope, receive, send) def test_app(): - client = TestClient(App) + client = TestClient(app) response = client.get('/') assert response.status_code == 200 ``` @@ -48,20 +44,16 @@ from starlette.testclient import TestClient from starlette.websockets import WebSocket -class App: - def __init__(self, scope): - assert scope['type'] == 'websocket' - self.scope = scope - - async def __call__(self, receive, send): - websocket = WebSocket(self.scope, receive=receive, send=send) - await websocket.accept() - await websocket.send_text('Hello, world!') - await websocket.close() +async def app(scope, receive, send): + assert scope['type'] == 'websocket' + websocket = WebSocket(scope, receive=receive, send=send) + await websocket.accept() + await websocket.send_text('Hello, world!') + await websocket.close() def test_app(): - client = TestClient(App) + client = TestClient(app) with client.websocket_connect('/') as websocket: data = websocket.receive_text() assert data == 'Hello, world!'