From 61a1e2feac2bb3b58fbba56f9e0be1969544e317 Mon Sep 17 00:00:00 2001 From: erm Date: Sat, 1 Sep 2018 03:47:46 +1000 Subject: [PATCH 1/6] Rename View -> HTTPEndpoint --- docs/applications.md | 6 +++--- docs/views.md | 22 +++++++++++----------- starlette/__init__.py | 4 ++-- starlette/app.py | 2 +- starlette/{views.py => endpoints.py} | 2 +- tests/test_app.py | 13 +++++++------ tests/{test_views.py => test_endpoints.py} | 4 ++-- 7 files changed, 27 insertions(+), 26 deletions(-) rename starlette/{views.py => endpoints.py} (98%) rename tests/{test_views.py => test_endpoints.py} (92%) diff --git a/docs/applications.md b/docs/applications.md index cf08883f9..736b2ec91 100644 --- a/docs/applications.md +++ b/docs/applications.md @@ -1,13 +1,13 @@ -Starlette also includes an `App` class that nicely ties together all of +Starlette also includes an app class `Starlette` that nicely ties together all of its other functionality. ```python -from starlette.app import App +from starlette.app import Starlette from starlette.response import PlainTextResponse from starlette.staticfiles import StaticFiles -app = App() +app = Starlette() app.debug = True app.mount("/static", StaticFiles(directory="static")) diff --git a/docs/views.md b/docs/views.md index 82b8c4f41..28e3eadc1 100644 --- a/docs/views.md +++ b/docs/views.md @@ -1,44 +1,44 @@ -Starlette includes a `View` class that provides a class-based view pattern which +Starlette includes an `HTTPEndpoint` class that provides a class-based view pattern which handles HTTP method dispatching. -The `View` class can be used as an other ASGI application: +The `HTTPEndpoint` class can be used as an ASGI application: ```python from starlette.response import PlainTextResponse -from starlette.views import View +from starlette.endpoints import HTTPEndpoint -class App(View): +class App(HTTPEndpoint): async def get(self, request): return PlainTextResponse(f"Hello, world!") ``` If you're using a Starlette application instance to handle routing, you can -dispatch to a View class by using the `@app.route()` decorator, or the +dispatch to an `HTTPEndpoint` class by using the `@app.route()` decorator, or the `app.add_route()` function. Make sure to dispatch to the class itself, rather than to an instance of the class: ```python -from starlette.app import App +from starlette.app import Starlette from starlette.response import PlainTextResponse -from starlette.views import View +from starlette.views import HTTPEndpoint -app = App() +app = Starlette() @app.route("/") -class Homepage(View): +class Homepage(HTTPEndpoint): async def get(self, request): return PlainTextResponse(f"Hello, world!") @app.route("/{username}") -class User(View): +class User(HTTPEndpoint): async def get(self, request, username): return PlainTextResponse(f"Hello, {username}") ``` -Class-based views will respond with "405 Method not allowed" responses for any +HTTP endpoint classes will respond with "405 Method not allowed" responses for any request methods which do not map to a corresponding handler. diff --git a/starlette/__init__.py b/starlette/__init__.py index 542ee9e01..76feb3ff8 100644 --- a/starlette/__init__.py +++ b/starlette/__init__.py @@ -1,4 +1,4 @@ -from starlette.app import App +from starlette.app import Starlette from starlette.response import ( FileResponse, HTMLResponse, @@ -13,7 +13,7 @@ __all__ = ( - "App", + "Starlette", "FileResponse", "HTMLResponse", "JSONResponse", diff --git a/starlette/app.py b/starlette/app.py index ffb3e8f16..647bd6de4 100644 --- a/starlette/app.py +++ b/starlette/app.py @@ -45,7 +45,7 @@ async def awaitable(receive: Receive, send: Send) -> None: return app -class App: +class Starlette: def __init__(self, debug=False) -> None: self.router = Router(routes=[]) self.exception_middleware = ExceptionMiddleware(self.router, debug=debug) diff --git a/starlette/views.py b/starlette/endpoints.py similarity index 98% rename from starlette/views.py rename to starlette/endpoints.py index 341645313..e0b4058a4 100644 --- a/starlette/views.py +++ b/starlette/endpoints.py @@ -5,7 +5,7 @@ import asyncio -class View: +class HTTPEndpoint: def __init__(self, scope: Scope): self.scope = scope diff --git a/tests/test_app.py b/tests/test_app.py index 8d045aca0..88c00502d 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -1,13 +1,13 @@ -from starlette import App +from starlette import Starlette from starlette.exceptions import HTTPException from starlette.response import JSONResponse, PlainTextResponse from starlette.staticfiles import StaticFiles from starlette.testclient import TestClient -from starlette.views import View +from starlette.endpoints import HTTPEndpoint import os -app = App() +app = Starlette() @app.exception_handler(Exception) @@ -31,7 +31,7 @@ async def async_homepage(request): @app.route("/class") -class Homepage(View): +class Homepage(HTTPEndpoint): def get(self, request): return PlainTextResponse("Hello, world!") @@ -114,8 +114,9 @@ def test_app_mount(tmpdir): with open(path, "w") as file: file.write("") - app = App() + app = Starlette() app.mount("/static", StaticFiles(directory=tmpdir), methods=["GET", "HEAD"]) + client = TestClient(app) response = client.get("/static/example.txt") @@ -128,7 +129,7 @@ def test_app_mount(tmpdir): def test_app_debug(): - app = App() + app = Starlette() app.debug = True @app.route("/") diff --git a/tests/test_views.py b/tests/test_endpoints.py similarity index 92% rename from tests/test_views.py rename to tests/test_endpoints.py index bcb5ecd1a..d77d2de53 100644 --- a/tests/test_views.py +++ b/tests/test_endpoints.py @@ -2,10 +2,10 @@ from starlette.response import PlainTextResponse from starlette.routing import Router, Path from starlette.testclient import TestClient -from starlette.views import View +from starlette.endpoints import HTTPEndpoint -class Homepage(View): +class Homepage(HTTPEndpoint): async def get(self, request, username=None): if username is None: return PlainTextResponse("Hello, world!") From 2eb9587746bdc7cd3ff2c5392eb78728c4f3f6fa Mon Sep 17 00:00:00 2001 From: erm Date: Mon, 3 Sep 2018 23:52:01 +1000 Subject: [PATCH 2/6] Rename views doc file -> endpoints --- docs/{views.md => endpoints.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{views.md => endpoints.md} (100%) diff --git a/docs/views.md b/docs/endpoints.md similarity index 100% rename from docs/views.md rename to docs/endpoints.md From 0578fd56f0ffffc7bb529a37322384b70dc5c7ff Mon Sep 17 00:00:00 2001 From: erm Date: Tue, 4 Sep 2018 23:44:52 +1000 Subject: [PATCH 3/6] Rename request/response files -> requests/responses, update imports, update docs --- README.md | 2 +- docs/applications.md | 2 +- docs/endpoints.md | 4 ++-- docs/exceptions.md | 2 +- docs/index.md | 2 +- docs/requests.md | 6 +++--- docs/responses.md | 14 +++++++------- docs/routing.md | 2 +- docs/test_client.md | 2 +- mkdocs.yml | 2 +- starlette/__init__.py | 4 ++-- starlette/app.py | 2 +- starlette/debug.py | 4 ++-- starlette/endpoints.py | 4 ++-- starlette/exceptions.py | 4 ++-- starlette/{request.py => requests.py} | 0 starlette/{response.py => responses.py} | 0 starlette/routing.py | 2 +- tests/test_app.py | 2 +- tests/test_endpoints.py | 2 +- tests/test_exceptions.py | 2 +- tests/test_request.py | 2 +- tests/test_response.py | 2 +- 23 files changed, 34 insertions(+), 34 deletions(-) rename starlette/{request.py => requests.py} (100%) rename starlette/{response.py => responses.py} (100%) diff --git a/README.md b/README.md index 4b970bb93..5d287a692 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ $ pip3 install starlette ## Example ```python -from starlette.response import Response +from starlette.responses import Response class App: diff --git a/docs/applications.md b/docs/applications.md index 736b2ec91..792cf1df2 100644 --- a/docs/applications.md +++ b/docs/applications.md @@ -3,7 +3,7 @@ its other functionality. ```python from starlette.app import Starlette -from starlette.response import PlainTextResponse +from starlette.responses import PlainTextResponse from starlette.staticfiles import StaticFiles diff --git a/docs/endpoints.md b/docs/endpoints.md index 28e3eadc1..96f71a98b 100644 --- a/docs/endpoints.md +++ b/docs/endpoints.md @@ -5,7 +5,7 @@ handles HTTP method dispatching. The `HTTPEndpoint` class can be used as an ASGI application: ```python -from starlette.response import PlainTextResponse +from starlette.responses import PlainTextResponse from starlette.endpoints import HTTPEndpoint @@ -22,7 +22,7 @@ than to an instance of the class: ```python from starlette.app import Starlette from starlette.response import PlainTextResponse -from starlette.views import HTTPEndpoint +from starlette.endpoints import HTTPEndpoint app = Starlette() diff --git a/docs/exceptions.md b/docs/exceptions.md index 9253a2e68..09de6e833 100644 --- a/docs/exceptions.md +++ b/docs/exceptions.md @@ -26,7 +26,7 @@ instead: ```python from starlette.exceptions import ExceptionMiddleware, HTTPException -from starlette.response import JSONResponse +from starlette.responses import JSONResponse class App: diff --git a/docs/index.md b/docs/index.md index 412233292..a4c07916d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -39,7 +39,7 @@ $ pip3 install starlette ## Example ```python -from starlette.response import Response +from starlette.responses import Response class App: diff --git a/docs/requests.md b/docs/requests.md index 497e22b40..da6c4d01c 100644 --- a/docs/requests.md +++ b/docs/requests.md @@ -7,7 +7,7 @@ the incoming request, rather than accessing the ASGI scope and receive channel d Signature: `Request(scope, receive=None)` ```python -from starlette.request import Request +from starlette.requests import Request from starlette.response import Response @@ -66,8 +66,8 @@ The request body, parsed as JSON: `await request.json()` You can also access the request body as a stream, using the `async for` syntax: ```python -from starlette.request import Request -from starlette.response import Response +from starlette.requests import Request +from starlette.responses import Response class App: diff --git a/docs/responses.md b/docs/responses.md index 63e743fbf..43abecd1c 100644 --- a/docs/responses.md +++ b/docs/responses.md @@ -19,7 +19,7 @@ Once you've instantiated a response, you can send it by calling it as an ASGI application instance. ```python -from starlette.response import Response +from starlette.responses import Response class App: @@ -36,7 +36,7 @@ class App: Takes some text or bytes and returns an HTML response. ```python -from starlette.response import HTMLResponse +from starlette.responses import HTMLResponse class App: @@ -53,7 +53,7 @@ class App: Takes some text or bytes and returns an plain text response. ```python -from starlette.response import PlainTextResponse +from starlette.responses import PlainTextResponse class App: @@ -70,7 +70,7 @@ class App: Takes some data and returns an `application/json` encoded response. ```python -from starlette.response import JSONResponse +from starlette.responses import JSONResponse class App: @@ -87,7 +87,7 @@ class App: Returns an HTTP redirect. Uses a 302 status code by default. ```python -from starlette.response import PlainTextResponse, RedirectResponse +from starlette.responses import PlainTextResponse, RedirectResponse class App: @@ -107,7 +107,7 @@ class App: Takes an async generator and streams the response body. ```python -from starlette.response import StreamingResponse +from starlette.responses import StreamingResponse import asyncio @@ -143,7 +143,7 @@ Takes a different set of arguments to instantiate than the other response types: File responses will include appropriate `Content-Length`, `Last-Modified` and `ETag` headers. ```python -from starlette.response import FileResponse +from starlette.responses import FileResponse class App: diff --git a/docs/routing.md b/docs/routing.md index 7fc26d77a..3db97a648 100644 --- a/docs/routing.md +++ b/docs/routing.md @@ -51,7 +51,7 @@ You can also route based on the incoming protocol, using the `ProtocolRouter` class. ```python -from starlette.response import Response +from starlette.responses import Response from starlette.routing import ProtocolRouter from starlette.websockets import WebSocketSession diff --git a/docs/test_client.md b/docs/test_client.md index ae7b99498..12e756754 100644 --- a/docs/test_client.md +++ b/docs/test_client.md @@ -3,7 +3,7 @@ The test client allows you to make requests against your ASGI application, using the `requests` library. ```python -from starlette.response import HTMLResponse +from starlette.responses import HTMLResponse from starlette.testclient import TestClient diff --git a/mkdocs.yml b/mkdocs.yml index 546dbc8ec..453bb2d7d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -19,7 +19,7 @@ nav: - Applications: 'applications.md' - Test Client: 'test_client.md' - Debugging: 'debugging.md' - - Views: 'views.md' + - Endpoints: 'endpoints.md' markdown_extensions: - markdown.extensions.codehilite: diff --git a/starlette/__init__.py b/starlette/__init__.py index 76feb3ff8..e8aa34082 100644 --- a/starlette/__init__.py +++ b/starlette/__init__.py @@ -1,5 +1,5 @@ from starlette.app import Starlette -from starlette.response import ( +from starlette.responses import ( FileResponse, HTMLResponse, JSONResponse, @@ -8,7 +8,7 @@ PlainTextResponse, StreamingResponse, ) -from starlette.request import Request +from starlette.requests import Request from starlette.testclient import TestClient diff --git a/starlette/app.py b/starlette/app.py index 647bd6de4..38a82f65c 100644 --- a/starlette/app.py +++ b/starlette/app.py @@ -1,5 +1,5 @@ from starlette.exceptions import ExceptionMiddleware -from starlette.request import Request +from starlette.requests import Request from starlette.routing import Path, PathPrefix, Router from starlette.types import ASGIApp, ASGIInstance, Receive, Scope, Send from starlette.websockets import WebSocketSession diff --git a/starlette/debug.py b/starlette/debug.py index e08695ea3..cc6e84674 100644 --- a/starlette/debug.py +++ b/starlette/debug.py @@ -1,5 +1,5 @@ -from starlette.request import Request -from starlette.response import HTMLResponse, PlainTextResponse +from starlette.requests import Request +from starlette.responses import HTMLResponse, PlainTextResponse import html import traceback diff --git a/starlette/endpoints.py b/starlette/endpoints.py index e0b4058a4..e27198910 100644 --- a/starlette/endpoints.py +++ b/starlette/endpoints.py @@ -1,6 +1,6 @@ from starlette.exceptions import HTTPException -from starlette.request import Request -from starlette.response import Response, PlainTextResponse +from starlette.requests import Request +from starlette.responses import Response, PlainTextResponse from starlette.types import Receive, Send, Scope import asyncio diff --git a/starlette/exceptions.py b/starlette/exceptions.py index c1fcf1776..63270cd6b 100644 --- a/starlette/exceptions.py +++ b/starlette/exceptions.py @@ -1,6 +1,6 @@ from starlette.debug import get_debug_response -from starlette.request import Request -from starlette.response import PlainTextResponse, Response +from starlette.requests import Request +from starlette.responses import PlainTextResponse, Response import asyncio import http diff --git a/starlette/request.py b/starlette/requests.py similarity index 100% rename from starlette/request.py rename to starlette/requests.py diff --git a/starlette/response.py b/starlette/responses.py similarity index 100% rename from starlette/response.py rename to starlette/responses.py diff --git a/starlette/routing.py b/starlette/routing.py index f97c9375a..07378346f 100644 --- a/starlette/routing.py +++ b/starlette/routing.py @@ -1,5 +1,5 @@ from starlette.exceptions import HTTPException -from starlette.response import PlainTextResponse +from starlette.responses import PlainTextResponse from starlette.types import Scope, ASGIApp, ASGIInstance from starlette.websockets import WebSocketClose import re diff --git a/tests/test_app.py b/tests/test_app.py index 88c00502d..bec50d35f 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -1,6 +1,6 @@ from starlette import Starlette from starlette.exceptions import HTTPException -from starlette.response import JSONResponse, PlainTextResponse +from starlette.responses import JSONResponse, PlainTextResponse from starlette.staticfiles import StaticFiles from starlette.testclient import TestClient from starlette.endpoints import HTTPEndpoint diff --git a/tests/test_endpoints.py b/tests/test_endpoints.py index d77d2de53..4b5a39edd 100644 --- a/tests/test_endpoints.py +++ b/tests/test_endpoints.py @@ -1,5 +1,5 @@ import pytest -from starlette.response import PlainTextResponse +from starlette.responses import PlainTextResponse from starlette.routing import Router, Path from starlette.testclient import TestClient from starlette.endpoints import HTTPEndpoint diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 54d0af2dc..f53d0281a 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -1,5 +1,5 @@ from starlette.exceptions import ExceptionMiddleware, HTTPException -from starlette.response import PlainTextResponse +from starlette.responses import PlainTextResponse from starlette.routing import Router, Path from starlette.testclient import TestClient import pytest diff --git a/tests/test_request.py b/tests/test_request.py index 82adeba91..9c258c5ab 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -1,5 +1,5 @@ from starlette import Request, JSONResponse, TestClient -from starlette.request import ClientDisconnect +from starlette.requests import ClientDisconnect import asyncio import pytest diff --git a/tests/test_response.py b/tests/test_response.py index 0cf9f32a6..e0f841e2a 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -1,4 +1,4 @@ -from starlette.response import ( +from starlette.responses import ( FileResponse, RedirectResponse, Response, From 8952bb3330d613192ffcc2b19ac08bf9305b40a7 Mon Sep 17 00:00:00 2001 From: erm Date: Wed, 5 Sep 2018 00:03:32 +1000 Subject: [PATCH 4/6] Rename WebSocketSession -> WebSocket, rename session -> websocket in docs --- docs/applications.md | 10 ++++---- docs/routing.md | 10 ++++---- docs/test_client.md | 16 ++++++------ docs/websockets.md | 55 ++++++++++++++++++++-------------------- starlette/app.py | 4 +-- starlette/websockets.py | 2 +- tests/test_routing.py | 4 +-- tests/test_websockets.py | 32 +++++++++++------------ 8 files changed, 66 insertions(+), 67 deletions(-) diff --git a/docs/applications.md b/docs/applications.md index 792cf1df2..a80a78907 100644 --- a/docs/applications.md +++ b/docs/applications.md @@ -23,15 +23,15 @@ def user(request, username): @app.websocket_route('/ws') -async def websocket_endpoint(session): - await session.accept() - await session.send_text('Hello, websocket!') - await session.close() +async def websocket_endpoint(websocket): + await websocket.accept() + await websocket.send_text('Hello, websocket!') + await websocket.close() ``` ### Instantiating the application -* `App(debug=False)` - Create a new Starlette application. +* `Starlette(debug=False)` - Create a new Starlette application. ### Adding routes to the application diff --git a/docs/routing.md b/docs/routing.md index 3db97a648..67d225ad1 100644 --- a/docs/routing.md +++ b/docs/routing.md @@ -53,7 +53,7 @@ class. ```python from starlette.responses import Response from starlette.routing import ProtocolRouter -from starlette.websockets import WebSocketSession +from starlette.websockets import WebSocket def http_endpoint(scope): @@ -62,10 +62,10 @@ def http_endpoint(scope): def websocket_endpoint(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) - await session.accept() - await session.send_json({"hello": "world"}) - await session.close() + websocket = WebSocket(scope, receive, send) + await websocket.accept() + await websocket.send_json({"hello": "world"}) + await websocket.close() return asgi diff --git a/docs/test_client.md b/docs/test_client.md index 12e756754..c8a9d2d4b 100644 --- a/docs/test_client.md +++ b/docs/test_client.md @@ -22,7 +22,7 @@ def test_app(): assert response.status_code == 200 ``` -The test client exposes the same interface as any other `requests` session. +The test client exposes the same interface as any other `requests` websocket. In particular, note that the calls to make a request are just standard function calls, not awaitables. @@ -44,7 +44,7 @@ websocket testing. ```python from starlette.testclient import TestClient -from starlette.websockets import WebSocketSession +from starlette.websockets import WebSocket class App: @@ -52,16 +52,16 @@ class App: self.scope = scope async def __call__(self, receive, send): - session = WebSocketSession(self.scope, receive=receive, send=send) - await session.accept() - await session.send_text('Hello, world!') - await session.close() + websocket = WebSocket(self.scope, receive=receive, send=send) + await websocket.accept() + await websocket.send_text('Hello, world!') + await websocket.close() def test_app(): client = TestClient(App) - with client.websocket_connect('/') as session: - data = session.receive_text() + with client.websocket_connect('/') as websocket: + data = websocket.receive_text() assert data == 'Hello, world!' ``` diff --git a/docs/websockets.md b/docs/websockets.md index c7b3bcb04..8d9245fee 100644 --- a/docs/websockets.md +++ b/docs/websockets.md @@ -1,14 +1,13 @@ -Starlette includes a `WebSocketSessions` class that fulfils a similar role -to the HTTP request, but that allows sending and receiving data on a websocket -session. +Starlette includes a `WebSocket` class that fulfils a similar role +to the HTTP request, but that allows sending and receiving data on a websocket. -### WebSocketSession +### WebSocket -Signature: `WebSocketSession(scope, receive=None, send=None)` +Signature: `WebSocket(scope, receive=None, send=None)` ```python -from starlette.websockets import WebSocketSession +from starlette.websockets import WebSocket class App: @@ -16,66 +15,66 @@ class App: self.scope = scope async def __call__(self, receive, send): - session = WebSocketSession(self.scope, receive=receive, send=send) - await session.accept() - await session.send_text('Hello, world!') - await session.close() + websocket = WebSocket(self.scope, receive=receive, send=send) + await websocket.accept() + await websocket.send_text('Hello, world!') + await websocket.close() ``` -Sessions present a mapping interface, so you can use them in the same +WebSockets present a mapping interface, so you can use them in the same way as a `scope`. -For instance: `session['path']` will return the ASGI path. +For instance: `websocket['path']` will return the ASGI path. #### URL -The session URL is accessed as `session.url`. +The websocket URL is accessed as `websocket.url`. The property is actually a subclass of `str`, and also exposes all the components that can be parsed out of the URL. -For example: `session.url.path`, `session.url.port`, `session.url.scheme`. +For example: `websocket.url.path`, `websocket.url.port`, `websocket.url.scheme`. #### Headers Headers are exposed as an immutable, case-insensitive, multi-dict. -For example: `session.headers['sec-websocket-version']` +For example: `websocket.headers['sec-websocket-version']` #### Query Parameters Headers are exposed as an immutable multi-dict. -For example: `session.query_params['abc']` +For example: `websocket.query_params['abc']` ### Accepting the connection -* `await session.accept(subprotocol=None)` +* `await websocket.accept(subprotocol=None)` ### Sending data -* `await session.send_text(data)` -* `await session.send_bytes(data)` -* `await session.send_json(data)` +* `await websocket.send_text(data)` +* `await websocket.send_bytes(data)` +* `await websocket.send_json(data)` ### Receiving data -* `await session.receive_text()` -* `await session.receive_bytes()` -* `await session.receive_json()` +* `await websocket.receive_text()` +* `await websocket.receive_bytes()` +* `await websocket.receive_json()` May raise `starlette.websockets.Disconnect()`. ### Closing the connection -* `await session.close(code=1000)` +* `await websocket.close(code=1000)` ### Sending and receiving messages If you need to send or receive raw ASGI messages then you should use -`session.send()` and `session.receive()` rather than using the raw `send` and -`receive` callables. This will ensure that the session's state is kept +`websocket.send()` and `websocket.receive()` rather than using the raw `send` and +`receive` callables. This will ensure that the websocket's state is kept correctly updated. -* `await session.send(message)` -* `await session.receive()` +* `await websocket.send(message)` +* `await websocket.receive()` diff --git a/starlette/app.py b/starlette/app.py index 38a82f65c..3edbd810b 100644 --- a/starlette/app.py +++ b/starlette/app.py @@ -2,7 +2,7 @@ from starlette.requests import Request from starlette.routing import Path, PathPrefix, Router from starlette.types import ASGIApp, ASGIInstance, Receive, Scope, Send -from starlette.websockets import WebSocketSession +from starlette.websockets import WebSocket import asyncio import inspect @@ -36,7 +36,7 @@ def websocket_session(func): def app(scope: Scope) -> ASGIInstance: async def awaitable(receive: Receive, send: Send) -> None: - session = WebSocketSession(scope, receive=receive, send=send) + session = WebSocket(scope, receive=receive, send=send) kwargs = scope.get("kwargs", {}) await func(session, **kwargs) diff --git a/starlette/websockets.py b/starlette/websockets.py index 4df07e6e6..a7467ae12 100644 --- a/starlette/websockets.py +++ b/starlette/websockets.py @@ -17,7 +17,7 @@ def __init__(self, code=1000): self.code = code -class WebSocketSession(Mapping): +class WebSocket(Mapping): def __init__(self, scope, receive=None, send=None): assert scope["type"] == "websocket" self._scope = scope diff --git a/tests/test_routing.py b/tests/test_routing.py index a9c5fd229..d02e1de6b 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -1,7 +1,7 @@ from starlette import Response, TestClient from starlette.exceptions import ExceptionMiddleware from starlette.routing import Path, PathPrefix, Router, ProtocolRouter -from starlette.websockets import WebSocketSession, WebSocketDisconnect +from starlette.websockets import WebSocket, WebSocketDisconnect import pytest @@ -71,7 +71,7 @@ def http_endpoint(scope): def websocket_endpoint(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) await session.accept() await session.send_json({"hello": "world"}) await session.close() diff --git a/tests/test_websockets.py b/tests/test_websockets.py index ed528fecd..0061c8547 100644 --- a/tests/test_websockets.py +++ b/tests/test_websockets.py @@ -1,12 +1,12 @@ import pytest from starlette.testclient import TestClient -from starlette.websockets import WebSocketSession, WebSocketDisconnect +from starlette.websockets import WebSocket, WebSocketDisconnect def test_session_url(): def app(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) await session.accept() await session.send_json({"url": session.url}) await session.close() @@ -22,7 +22,7 @@ async def asgi(receive, send): def test_session_query_params(): def app(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) query_params = dict(session.query_params) await session.accept() await session.send_json({"params": query_params}) @@ -39,7 +39,7 @@ async def asgi(receive, send): def test_session_headers(): def app(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) headers = dict(session.headers) await session.accept() await session.send_json({"headers": headers}) @@ -65,7 +65,7 @@ async def asgi(receive, send): def test_session_port(): def app(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) await session.accept() await session.send_json({"port": session.url.port}) await session.close() @@ -81,7 +81,7 @@ async def asgi(receive, send): def test_session_send_and_receive_text(): def app(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) await session.accept() data = await session.receive_text() await session.send_text("Message was: " + data) @@ -99,7 +99,7 @@ async def asgi(receive, send): def test_session_send_and_receive_bytes(): def app(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) await session.accept() data = await session.receive_bytes() await session.send_bytes(b"Message was: " + data) @@ -117,7 +117,7 @@ async def asgi(receive, send): def test_session_send_and_receive_json(): def app(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) await session.accept() data = await session.receive_json() await session.send_json({"message": data}) @@ -138,7 +138,7 @@ def test_client_close(): def app(scope): async def asgi(receive, send): nonlocal close_code - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) await session.accept() try: data = await session.receive_text() @@ -156,7 +156,7 @@ async def asgi(receive, send): def test_application_close(): def app(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) await session.accept() await session.close(1001) @@ -172,7 +172,7 @@ async def asgi(receive, send): def test_rejected_connection(): def app(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) await session.close(1001) return asgi @@ -186,7 +186,7 @@ async def asgi(receive, send): def test_subprotocol(): def app(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) assert session["subprotocols"] == ["soap", "wamp"] await session.accept(subprotocol="wamp") await session.close() @@ -213,7 +213,7 @@ async def asgi(receive, send): def test_duplicate_close(): def app(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) await session.accept() await session.close() await session.close() @@ -229,7 +229,7 @@ async def asgi(receive, send): def test_duplicate_disconnect(): def app(scope): async def asgi(receive, send): - session = WebSocketSession(scope, receive, send) + session = WebSocket(scope, receive, send) await session.accept() message = await session.receive() assert message["type"] == "websocket.disconnect" @@ -245,10 +245,10 @@ async def asgi(receive, send): def test_session_scope_interface(): """ - A WebSocketSession can be instantiated with a scope, and presents a `Mapping` + A WebSocket can be instantiated with a scope, and presents a `Mapping` interface. """ - session = WebSocketSession({"type": "websocket", "path": "/abc/", "headers": []}) + session = WebSocket({"type": "websocket", "path": "/abc/", "headers": []}) assert session["type"] == "websocket" assert dict(session) == {"type": "websocket", "path": "/abc/", "headers": []} assert len(session) == 3 From 6dcb1de68eff2035adb1c965e2fc9e0a38f773a9 Mon Sep 17 00:00:00 2001 From: erm Date: Wed, 5 Sep 2018 00:16:40 +1000 Subject: [PATCH 5/6] Full module imports in tests and source, removing imports from __init__ file --- starlette/__init__.py | 26 -------------------------- starlette/staticfiles.py | 2 +- tests/test_app.py | 2 +- tests/test_debug.py | 3 ++- tests/test_request.py | 5 +++-- tests/test_routing.py | 3 ++- tests/test_staticfiles.py | 2 +- 7 files changed, 10 insertions(+), 33 deletions(-) diff --git a/starlette/__init__.py b/starlette/__init__.py index e8aa34082..d31c31eae 100644 --- a/starlette/__init__.py +++ b/starlette/__init__.py @@ -1,27 +1 @@ -from starlette.app import Starlette -from starlette.responses import ( - FileResponse, - HTMLResponse, - JSONResponse, - RedirectResponse, - Response, - PlainTextResponse, - StreamingResponse, -) -from starlette.requests import Request -from starlette.testclient import TestClient - - -__all__ = ( - "Starlette", - "FileResponse", - "HTMLResponse", - "JSONResponse", - "PlainTextResponse", - "RedirectResponse", - "Response", - "StreamingResponse", - "Request", - "TestClient", -) __version__ = "0.2.3" diff --git a/starlette/staticfiles.py b/starlette/staticfiles.py index daf8a25d8..07cafe5a6 100644 --- a/starlette/staticfiles.py +++ b/starlette/staticfiles.py @@ -1,4 +1,4 @@ -from starlette import PlainTextResponse, FileResponse +from starlette.responses import PlainTextResponse, FileResponse from aiofiles.os import stat as aio_stat import os import stat diff --git a/tests/test_app.py b/tests/test_app.py index bec50d35f..7d32019ab 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -1,4 +1,4 @@ -from starlette import Starlette +from starlette.app import Starlette from starlette.exceptions import HTTPException from starlette.responses import JSONResponse, PlainTextResponse from starlette.staticfiles import StaticFiles diff --git a/tests/test_debug.py b/tests/test_debug.py index 1bb11f567..a93b27770 100644 --- a/tests/test_debug.py +++ b/tests/test_debug.py @@ -1,4 +1,5 @@ -from starlette import Request, Response, TestClient +from starlette.responses import Response +from starlette.testclient import TestClient from starlette.debug import DebugMiddleware import pytest diff --git a/tests/test_request.py b/tests/test_request.py index 9c258c5ab..af0749b99 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -1,5 +1,6 @@ -from starlette import Request, JSONResponse, TestClient -from starlette.requests import ClientDisconnect +from starlette.responses import JSONResponse +from starlette.testclient import TestClient +from starlette.requests import Request, ClientDisconnect import asyncio import pytest diff --git a/tests/test_routing.py b/tests/test_routing.py index d02e1de6b..2adf520a3 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -1,4 +1,5 @@ -from starlette import Response, TestClient +from starlette.responses import Response +from starlette.testclient import TestClient from starlette.exceptions import ExceptionMiddleware from starlette.routing import Path, PathPrefix, Router, ProtocolRouter from starlette.websockets import WebSocket, WebSocketDisconnect diff --git a/tests/test_staticfiles.py b/tests/test_staticfiles.py index 7ea955a2e..c5a2a66f7 100644 --- a/tests/test_staticfiles.py +++ b/tests/test_staticfiles.py @@ -1,4 +1,4 @@ -from starlette import TestClient +from starlette.testclient import TestClient from starlette.staticfiles import StaticFile, StaticFiles import os import pytest From 4479efe7584deffeb281bdaa224b57a22a61360a Mon Sep 17 00:00:00 2001 From: erm Date: Wed, 5 Sep 2018 18:24:00 +1000 Subject: [PATCH 6/6] Fix name in testclient doc --- docs/test_client.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/test_client.md b/docs/test_client.md index c8a9d2d4b..d8749a397 100644 --- a/docs/test_client.md +++ b/docs/test_client.md @@ -22,7 +22,7 @@ def test_app(): assert response.status_code == 200 ``` -The test client exposes the same interface as any other `requests` websocket. +The test client exposes the same interface as any other `requests` session. In particular, note that the calls to make a request are just standard function calls, not awaitables.