2020-01-05 15:13:03 +01:00
# Quart-Session
2020-01-04 23:31:28 +01:00
2020-01-05 17:00:46 +01:00
 [](https://pypi.org/project/Quart-Session/) 
2020-01-07 18:49:13 +01:00
Quart-Session is an extension for [Quart ](https://gitlab.com/pgjones/quart/blob/master/README.rst ) that adds support for
2020-01-04 23:31:28 +01:00
server-side sessions to your application.
Based on [flask-session ](https://pypi.org/project/Flask-Session/ ).
## Quick start
2020-01-15 09:22:11 +01:00
Quart-Session can be installed via pipenv or pip,
2020-01-04 23:31:28 +01:00
```bash
$ pipenv install quart-session
$ pip install quart-session
```
2022-03-10 14:46:22 +02:00
and requires Python 3.7.0 or higher. A minimal Quart-Session example is:
2020-01-04 23:31:28 +01:00
```python3
from quart import Quart , session
from quart_session import Session
app = Quart ( __name__ )
app . config [ 'SESSION_TYPE' ] = 'redis'
Session ( app )
@app.route ( '/' )
async def hello ():
session [ "foo" ] = "bar"
2022-03-10 14:46:22 +02:00
return "session key 'foo' set"
@app.route ( '/foo' )
async def foo ():
return session . get ( "foo" , "session key 'foo' not found" )
2020-01-04 23:31:28 +01:00
app . run ()
```
## Features
2022-03-10 14:46:22 +02:00
### Redis
2020-01-04 23:31:28 +01:00
2023-01-15 21:42:18 +01:00
via `redis>=4.4.0` .
2020-01-04 23:31:28 +01:00
```python3
app = Quart ( __name__ )
app . config [ 'SESSION_TYPE' ] = 'redis'
Session ( app )
```
2022-03-10 14:46:22 +02:00
By default, Quart-session connects to Redis at `127.0.0.1:6379` . If you
have a different location, use `SESSION_URI`
```python3
app = Quart ( __name__ )
app . config [ 'SESSION_TYPE' ] = 'redis'
app . config [ 'SESSION_URI' ] = 'redis://:password@localhost:6379'
```
Alternatively, for extra control, you may provide your own `aioredis.Client` instance altogether.
2020-01-04 23:31:28 +01:00
```python3
app = Quart ( __name__ )
app . config [ 'SESSION_TYPE' ] = 'redis'
@app.before_serving
async def setup ():
2022-03-10 14:46:22 +02:00
cache = await aioredis . Redis (
host = "foobar.com" ,
port = 6379 ,
password = "foobar"
)
2020-01-04 23:31:28 +01:00
app . config [ 'SESSION_REDIS' ] = cache
Session ( app )
```
2022-03-10 14:46:22 +02:00
#### Trio
2020-01-04 23:31:28 +01:00
2020-01-05 15:13:03 +01:00
Quart-Session comes with [an (experimental) Redis client ](quart_session/redis_trio ) for use with the [Trio ](https://trio.readthedocs.io/en/stable/ ) eventloop.
2020-01-04 23:31:28 +01:00
2020-01-05 15:10:16 +01:00
```python3
from quart_trio import QuartTrio
from quart_session.redis_trio.client import RedisTrio
app = QuartTrio ( __name__ )
app . config [ 'SESSION_TYPE' ] = 'redis'
Session ( app )
```
2020-01-04 23:31:28 +01:00
2022-03-10 14:46:22 +02:00
### Memcached
2020-01-04 23:31:28 +01:00
via `aiomcache` .
```python3
app = Quart ( __name__ )
app . config [ 'SESSION_TYPE' ] = 'memcached'
Session ( app )
```
2022-03-17 15:51:45 -04:00
### MongoDB
via `motor` .
```python3
app = Quart ( __name__ )
app . config [ 'SESSION_TYPE' ] = 'mongodb'
app . config [ 'SESSION_MONGODB_URI' ] = 'mongodb://localhost:27017/my_database'
app . config [ 'SESSION_MONGODB_COLLECTION' ] = 'sessions'
Session ( app )
```
2020-01-04 23:31:28 +01:00
### JSON serializer
[flask-session ](https://pypi.org/project/Flask-Session/ ) uses `pickle`
2020-01-15 09:22:11 +01:00
for session data while Quart-Session uses [a JSON serializer ](https://gitlab.com/pgjones/quart/blob/37e249b9b146824a8668eaa1daa12392aeb00256/src/quart/json/tag.py#L141 )
capable of serializing the usual JSON types, as well as: `Tuple` , `Bytes` ,
2020-01-04 23:31:28 +01:00
`Markup` , `UUID` , and `DateTime` .
JSON as session data allows for greater interoperability with other
programs/languages that might want to read session data straight
2020-01-05 15:10:16 +01:00
from a back-end.
2020-01-04 23:31:28 +01:00
2020-01-05 15:10:16 +01:00
If ~~for some unholy reason~~ you prefer `pickle` or your own serializer,
2020-01-04 23:31:28 +01:00
```python3
app = Quart ( __name__ )
app . config [ 'SESSION_TYPE' ] = 'redis'
Session ( app )
try :
import cPickle as pickle
except ImportError :
import pickle
app . session_interface . serialize = pickle
```
2020-01-15 09:22:11 +01:00
### Back-end usage
2020-01-04 23:31:28 +01:00
2020-01-15 09:22:11 +01:00
At any point you may interface with the session back-end directly:
2020-01-04 23:31:28 +01:00
```python3
2022-11-13 02:12:23 +02:00
from quart_session.sessions import SessionInterface
2020-01-15 09:22:11 +01:00
@app.route ( "/" )
async def hello ():
2022-11-13 02:12:23 +02:00
cache : SessionInterface = app . session_interface
2020-01-15 09:22:11 +01:00
await cache . set ( "random_key" , "val" , expiry = 3600 )
data = await cache . get ( "random_key" )
```
2020-01-04 23:31:28 +01:00
2020-01-15 09:22:11 +01:00
The interface will have the `get` , `set` , and `delete` methods available (regardless of
back-end - similar to how [aiocache ](https://github.com/argaen/aiocache ) works).
2020-01-04 23:31:28 +01:00
2020-01-15 09:22:11 +01:00
### Performance
2020-01-04 23:31:28 +01:00
2020-01-15 09:22:11 +01:00
[flask-session ](https://pypi.org/project/Flask-Session/ ) sets a
session for each incoming request, including static files. From experience,
this often puts unneeded load on underlying session infrastructure,
especially in high-traffic environments.
2020-01-04 23:31:28 +01:00
2020-01-15 09:22:11 +01:00
Quart-Session only contacts the back-end when a session changed (or created). In addition,
static file serves never emit a `Set-Cookie` header. If you'd like to enable
this though, set `SESSION_STATIC_FILE` to `True` .
2020-01-04 23:31:28 +01:00
2020-01-05 15:13:03 +01:00
### Session pinning
2020-01-04 23:31:28 +01:00
2020-01-05 15:13:03 +01:00
Associates an user's session to his/her IP address. This mitigates cookie stealing via XSS etc, and is handy
2020-01-15 09:22:11 +01:00
for web applications that require extra security.
2020-01-04 23:31:28 +01:00
```python3
app = Quart ( __name__ )
app . config [ 'SESSION_TYPE' ] = 'redis'
2020-01-15 09:22:11 +01:00
app . config [ 'SESSION_PROTECTION' ] = True
2020-01-04 23:31:28 +01:00
Session ( app )
```
2020-01-05 15:13:03 +01:00
Session reuse from a different IP will now result in the creation of a new session, and the deletion of the old.
2020-01-04 23:31:28 +01:00
**Important:** If your application is behind a reverse proxy, it most
likely provides the `X-Forwarded-For` header which you **must** make use of
2020-01-15 09:22:11 +01:00
by explicitly setting `SESSION_REVERSE_PROXY` to `True` .
2020-01-04 23:31:28 +01:00
## Future development
- `FileSystemSessionInterface`
- `GoogleCloudDatastoreSessionInterface`
2020-01-15 09:22:11 +01:00
- Pytest
2020-01-04 23:31:28 +01:00
2020-01-15 09:22:11 +01:00
## Flask-Session
2020-01-04 23:31:28 +01:00
This library works very similarly to [flask-session ](https://pypi.org/project/Flask-Session/ ).
2020-01-15 09:22:11 +01:00
The changes are specified below:
2020-01-04 23:31:28 +01:00
2020-01-15 09:22:11 +01:00
- Quart-Session does not emit a `Set-Cookie` on every request.
- Quart-Session does not emit a `Set-Cookie` on static file serves.
2020-01-04 23:31:28 +01:00
- Quart-Session uses a different serializer: `quart.json.tag.TaggedJSONSerializer` instead of `pickle` .
2020-01-05 15:13:03 +01:00
- Quart-Session disallows the client to supply their own made up `sid` cookie value.
2020-01-15 09:22:11 +01:00
- Quart-Session can do session protection.
- Quart-Session might not have all the back-end interfaces implemented (yet), such as "filesystem".
2020-01-04 23:31:28 +01:00
## Help
Find the Quart folk on [gitter ](https://gitter.im/python-quart/lobby ) or open an issue.
## License
2020-01-07 18:49:13 +01:00
BSD