Skip to content
This repository has been archived by the owner on Dec 31, 2023. It is now read-only.

Commit

Permalink
Add context documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
ahopkins committed Mar 17, 2021
1 parent 33f5697 commit 588aef4
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 5 deletions.
26 changes: 23 additions & 3 deletions src/en/guide/basics/app.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,40 @@
## Instance

---:1


The most basic building block is the `Sanic()` instance. It is not required, but the custom is to instatiate this in a file called `server.py`.

:--:1
```python
# /path/to/server.py

from sanic import Sanic

app = Sanic("My Hello, world app")
```
:---

## Application context
::: new NEW in v21.3
Most applications will have the need to share/reuse data or objects across different parts of the code base. The most common example is DB connections.
:::

---:1
In versions of Sanic prior to v21.3, this was commonly done by attaching an attribute to the application instance
:--:1
```python
# Raises a warning as deprecated feature in 21.3
app = Sanic("MyApp")
app.db = Database()
```
:---

---:1
Because this can create potential problems with name conflicts, and to be consistent with [request context](./request.md#context) objects, v21.3 introduces application level context object.
:--:1
```python
# Correct way to attach objects to the application
app = Sanic("MyApp")
app.ctx.db = Database()
```
:---

## App Registry
Expand Down
40 changes: 38 additions & 2 deletions src/en/guide/basics/request.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,14 @@ Most of the time you will want to use the `.get()` method can be used to access

## Context

### Request context

The `request.ctx` object is your playground to store whatever information you need to about the request.

This is often used to store items like authenticated user details. We will get more into [middleware](./middleware.md) later, but here is a simple example.

```python
@app.middleware("request")
@app.on_request
async def run_before_handler(request):
request.ctx.user = await fetch_user_by_token(request.token)

Expand All @@ -114,10 +116,44 @@ A typical use case would be to store the user object acquired from database in a

Custom context is reserved for applications and extensions. Sanic itself makes no use of it.

## Parameters
### Connection context

---:1
::: new NEW in v21.3
Often times your API will need to serve multiple concurrent (or consecutive) requests to the same client. This happens, for example, very often with progressive web apps that need to query multiple endpoints to get data.

The HTTP protocol calls for an easing of overhead time caused by the connection with the use of [keep alive headers](../deployment/configuration.md#keep-alive-timeout).

When multiple requests share a single connection, Sanic provides a context object to allow those requests to share state.
:::
:--:1
```python
@app.on_request
async def increment_foo(request):
if not hasattr(request.conn_info.ctx, "foo"):
request.conn_info.ctx.foo = 0
request.conn_info.ctx.foo += 1

@app.get("/")
async def count_foo(request):
return text(f"{request.conn_info.ctx.foo=}")
```

```bash
$ curl localhost:8000 localhost:8000 localhost:8000
request.conn_info.ctx.foo=1
request.conn_info.ctx.foo=2
request.conn_info.ctx.foo=3
```
:---

::: warning
Connection level context is an experimental feature, and should be finalized in v21.6.
:::

## Parameters

---:1
Values that are extracted from the path are injected into the handler as parameters, or more specifically as keyword arguments. There is much more detail about this in the [Routing section](./routing.md).
:--:1
```python
Expand Down
50 changes: 50 additions & 0 deletions src/en/guide/release-notes/v21.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,56 @@ Sanic internal testing client has been removed. It is now located in its own rep

If you have `sanic-testing` installed, it will be available and usable on your `Sanic()` application instances as before. So, the **only** change you will need to make is to add `sanic-testing` to your test suite requirements.

### Application and connection level context (`ctx`) objects

Version 19.9 [added ](https://github.com/sanic-org/sanic/pull/1666/files) the `request.ctx` API. This helpful construct easily allows for attaching properties and data to a request object (for example, in middleware), and reusing the information elsewhere int he application.

Similarly, this concept is being extended in two places:

1. the application instance, and
2. a transport connection.

#### Application context

A common use case is to attach properties to the app instance. For the sake of consistency, and to avoid the issue of name collision with Sanic properties, the `ctx` object now exists on `Sanic` instances.

```python
@app.before_server_startup
async def startup_db(app, _):
# WRONG
app.db = await connect_to_db()

# CORRECT
app.ctx.db = await connect_to_db()
```

#### Connection context

When a client sends a keep alive header, Sanic will attempt to keep the transport socket [open for a period of time](../deployment/configuration.md#keep-alive-timeout). That transport object now has a `ctx` object available on it. This effectively means that multiple requests from a single client (where the transport layer is being reused) may share state.

```python
@app.on_request
async def increment_foo(request):
if not hasattr(request.conn_info.ctx, "foo"):
request.conn_info.ctx.foo = 0
request.conn_info.ctx.foo += 1

@app.get("/")
async def count_foo(request):
return text(f"{request.conn_info.ctx.foo=}")
```

```bash
$ curl localhost:8000 localhost:8000 localhost:8000
request.conn_info.ctx.foo=1
request.conn_info.ctx.foo=2
request.conn_info.ctx.foo=3
```

::: warning
Connection level context is an experimental feature, and should be finalized in v21.6.
:::

## News


Expand Down

0 comments on commit 588aef4

Please sign in to comment.