Add dotted endpoint notation and additional tests

This commit is contained in:
Adam Hopkins 2018-12-31 13:40:07 +02:00
commit 4d527035ae
No known key found for this signature in database
GPG Key ID: 7028135130579DF1
5 changed files with 116 additions and 14 deletions

View File

@ -126,3 +126,40 @@ args.get('titles') # => 'Post 1'
args.getlist('titles') # => ['Post 1', 'Post 2']
```
## Accessing the handler name with the request.endpoint attribute
The `request.endpoint` attribute holds the handler's name. For instance, the below
route will return "hello".
```python
from sanic.response import text
from sanic import Sanic
app = Sanic()
@app.get("/")
def hello(request):
return text(request.endpoint)
```
Or, with a blueprint it will be include both, separated by a period. For example,
the below route would return foo.bar:
```python
from sanic import Sanic
from sanic import Blueprint
from sanic.response import text
app = Sanic(__name__)
blueprint = Blueprint('foo')
@blueprint.get('/')
async def bar(request):
return text(request.endpoint)
app.blueprint(blueprint)
app.run(host="0.0.0.0", port=8000, debug=True)
```

View File

@ -454,6 +454,13 @@ class Sanic:
def response(handler):
async def websocket_handler(request, *args, **kwargs):
request.app = self
if not getattr(handler, "__blueprintname__", False):
request.endpoint = handler.__name__
else:
request.endpoint = (
getattr(handler, "__blueprintname__", "")
+ handler.__name__
)
try:
protocol = request.transport.get_protocol()
except AttributeError:
@ -888,6 +895,16 @@ class Sanic:
"handler from the router"
)
)
else:
if not getattr(handler, "__blueprintname__", False):
request.endpoint = self._build_endpoint_name(
handler.__name__
)
else:
request.endpoint = self._build_endpoint_name(
getattr(handler, "__blueprintname__", ""),
handler.__name__,
)
# Run response handler
response = handler(request, *args, **kwargs)
@ -1276,3 +1293,7 @@ class Sanic:
logger.info("Goin' Fast @ {}://{}:{}".format(proto, host, port))
return server_settings
def _build_endpoint_name(self, *parts):
parts = [self.name, *parts]
return ".".join(parts)

View File

@ -69,26 +69,27 @@ class Request(dict):
"""Properties of an HTTP request such as URL, headers, etc."""
__slots__ = (
"app",
"headers",
"version",
"method",
"__weakref__",
"_cookies",
"transport",
"body",
"parsed_json",
"parsed_args",
"parsed_form",
"parsed_files",
"_ip",
"_parsed_url",
"uri_template",
"stream",
"_port",
"_remote_addr",
"_socket",
"_port",
"__weakref__",
"app",
"body",
"endpoint",
"headers",
"method",
"parsed_args",
"parsed_files",
"parsed_form",
"parsed_json",
"raw_url",
"stream",
"transport",
"uri_template",
"version",
)
def __init__(self, url_bytes, headers, version, method, transport):
@ -111,6 +112,7 @@ class Request(dict):
self.uri_template = None
self._cookies = None
self.stream = None
self.endpoint = None
def __repr__(self):
if self.method is None or not self.path:

View File

@ -5,6 +5,7 @@ from sanic.config import BASE_LOGO
try:
import uvloop # noqa
ROW = 0
except BaseException:
ROW = 1

View File

@ -7,6 +7,8 @@ from urllib.parse import urlparse
import pytest
from sanic import Sanic
from sanic import Blueprint
from sanic.exceptions import ServerError
from sanic.request import DEFAULT_HTTP_CONTENT_TYPE
from sanic.response import json, text
@ -698,3 +700,42 @@ def test_request_form_invalid_content_type(app):
request, response = app.test_client.post("/", json={"test": "OK"})
assert request.form == {}
def test_endpoint_basic():
app = Sanic()
@app.route("/")
def my_unique_handler(request):
return text("Hello")
request, response = app.test_client.get("/")
assert request.endpoint == "test_requests.my_unique_handler"
def test_endpoint_named_app():
app = Sanic("named")
@app.route("/")
def my_unique_handler(request):
return text("Hello")
request, response = app.test_client.get("/")
assert request.endpoint == "named.my_unique_handler"
def test_endpoint_blueprint():
bp = Blueprint("my_blueprint", url_prefix="/bp")
@bp.route("/")
async def bp_root(request):
return text("Hello")
app = Sanic("named")
app.blueprint(bp)
request, response = app.test_client.get("/bp")
assert request.endpoint == "named.my_blueprint.bp_root"