Inject app into request object

Allows for injection of the app object into the request object through
the request handler.

This allows for users to setup things like database connections etc. in
listeners and then utilize them throughout the their various route
handlers.

Usage is fairly simple like so:
```python
@app.get('/')
async def handler(request):
    request.app.anything
```

Name is up in the air but I'll leave this up for a few days and I'll
change it if we get a consensus
This commit is contained in:
Eli Uriegas 2017-02-22 11:34:14 -06:00
parent 64f73f624f
commit 56ecb6a3ea
3 changed files with 25 additions and 2 deletions

View File

@ -360,6 +360,8 @@ class Sanic:
# Request Middleware
# -------------------------------------------- #
request.app = self
response = False
# The if improves speed. I don't know why
if self.request_middleware:

View File

@ -36,7 +36,7 @@ class RequestParameters(dict):
class Request(dict):
"""Properties of an HTTP request such as URL, headers, etc."""
__slots__ = (
'url', 'headers', 'version', 'method', '_cookies', 'transport',
'app', 'url', 'headers', 'version', 'method', '_cookies', 'transport',
'query_string', 'body',
'parsed_json', 'parsed_args', 'parsed_form', 'parsed_files',
'_ip',
@ -45,6 +45,7 @@ class Request(dict):
def __init__(self, url_bytes, headers, version, method, transport):
# TODO: Content-Encoding detection
url_parsed = parse_url(url_bytes)
self.app = None
self.url = url_parsed.path.decode('utf-8')
self.headers = headers
self.version = version

View File

@ -1,3 +1,5 @@
import random
from sanic import Sanic
from sanic.response import json
from ujson import loads
@ -14,10 +16,28 @@ def test_storage():
@app.route('/')
def handler(request):
return json({ 'user': request.get('user'), 'sidekick': request.get('sidekick') })
return json({'user': request.get('user'), 'sidekick': request.get('sidekick')})
request, response = app.test_client.get('/')
response_json = loads(response.text)
assert response_json['user'] == 'sanic'
assert response_json.get('sidekick') is None
def test_app_injection():
app = Sanic('test_app_injection')
expected = random.choice(range(0, 100))
@app.listener('after_server_start')
async def inject_data(app, loop):
app.injected = expected
@app.get('/')
async def handler(request):
return json({'injected': request.app.injected})
request, response = app.test_client.get('/')
response_json = loads(response.text)
assert response_json['injected'] == expected