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 Middleware
# -------------------------------------------- # # -------------------------------------------- #
request.app = self
response = False response = False
# The if improves speed. I don't know why # The if improves speed. I don't know why
if self.request_middleware: if self.request_middleware:

View File

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

View File

@ -1,3 +1,5 @@
import random
from sanic import Sanic from sanic import Sanic
from sanic.response import json from sanic.response import json
from ujson import loads from ujson import loads
@ -14,10 +16,28 @@ def test_storage():
@app.route('/') @app.route('/')
def handler(request): 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('/') request, response = app.test_client.get('/')
response_json = loads(response.text) response_json = loads(response.text)
assert response_json['user'] == 'sanic' assert response_json['user'] == 'sanic'
assert response_json.get('sidekick') is None 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