Skip to content

Commit

Permalink
add aioredis backend and examples for redis
Browse files Browse the repository at this point in the history
  • Loading branch information
auredentan committed Aug 27, 2020
1 parent 8cc5d84 commit 250dcd9
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 25 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

# mkdocs
site/

# Vscode
.vscode

Expand Down
45 changes: 45 additions & 0 deletions examples/aioredis_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import aioredis
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse
from starlette.routing import Route

from starlette_session import SessionMiddleware
from starlette_session.backends import BackendType


async def setup_session(request: Request) -> JSONResponse:
request.session.update({"data": "session_data"})
return JSONResponse({"session": request.session})


async def clear_session(request: Request):
request.session.clear()
return JSONResponse({"session": request.session})


def view_session(request: Request) -> JSONResponse:
print(request.scope)
return JSONResponse({"session": request.session})


routes = [
Route("/setup_session", endpoint=setup_session),
Route("/clear_session", endpoint=clear_session),
Route("/view_session", endpoint=view_session),
]


app = Starlette(debug=True, routes=routes)


@app.on_event("startup")
async def on_startup():
redis_client = await aioredis.create_redis_pool(("localhost", 6379))
app.add_middleware(
SessionMiddleware,
secret_key="secret",
cookie_name="cookie22",
backend_type=BackendType.aioRedis,
backend_client=redis_client,
)
40 changes: 40 additions & 0 deletions examples/redis_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from redis import Redis
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse
from starlette.routing import Route

from starlette_session import SessionMiddleware
from starlette_session.backends import BackendType


async def setup_session(request: Request) -> JSONResponse:
request.session.update({"data": "session_data"})
return JSONResponse({"session": request.session})


async def clear_session(request: Request):
request.session.clear()
return JSONResponse({"session": request.session})


def view_session(request: Request) -> JSONResponse:
print(request.scope)
return JSONResponse({"session": request.session})


routes = [
Route("/setup_session", endpoint=setup_session),
Route("/clear_session", endpoint=clear_session),
Route("/view_session", endpoint=view_session),
]

redis_client = Redis(host="localhost", port=6379)
app = Starlette(debug=True, routes=routes)
app.add_middleware(
SessionMiddleware,
secret_key="secret",
cookie_name="cookie22",
backend_type=BackendType.redis,
backend_client=redis_client,
)
122 changes: 118 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "starlette-session"
version = "0.3.0"
version = "0.3.7"
description = "A library for backend side session with starlette"
authors = ["Aurélien Dentan <aurelien.dentan@gmail.com>"]
maintainers = ["Aurélien Dentan <aurelien.dentan@gmail.com>"]
Expand All @@ -19,13 +19,13 @@ classifiers = [
[tool.poetry.dependencies]
python = "^3.6"
starlette = "^0.13.8"
redis = {version = "^3.5.3", optional = true}
itsdangerous = "^1.1.0"
redis = {version = "^3.5.3", optional = true}
aioredis = {version = "^1.3.1", optional = true}

[tool.poetry.dev-dependencies]
pytest = "^6.0.1"
black = "^19.10b0"
fakeredis = "^1.4.3"
requests = "^2.24.0"
pytest-mock = "^3.3.0"
pytest-cov = "^2.10.1"
Expand All @@ -34,6 +34,10 @@ mkdocstrings = "^0.13.0"
mkdocs-material = "^5.5.9"
git-changelog = "^0.4.0"
isort = "^5.4.2"
pytest-asyncio = "^0.14.0"
aioredis = "^1.3.1"
fakeredis = "^1.4.3"
async-generator = "^1.10"

[tool.black]
line-length = 88
Expand Down
21 changes: 11 additions & 10 deletions starlette_session/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
from starlette.requests import HTTPConnection
from starlette.types import ASGIApp, Message, Receive, Scope, Send

from starlette_session.backends import BackendType, RedisSessionBackend
from starlette_session.backends import (AioRedisSessionBackend, BackendType,
RedisSessionBackend)
from starlette_session.interfaces import ISessionBackend


Expand Down Expand Up @@ -71,7 +72,8 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
session_key = json.loads(b64decode(data)).get(
self._cookie_session_id_field
)
scope["session"] = self.session_backend.get(session_key)
scope["session"] = await self.session_backend.get(session_key)
scope["__session_key"] = session_key

initial_session_was_empty = False
except (BadTimeSignature, SignatureExpired):
Expand All @@ -81,14 +83,15 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:

async def send_wrapper(message: Message, **kwargs) -> None:
if message["type"] == "http.response.start":
if scope["session"]:

session_key = str(uuid4())
session_key = scope.pop("__session_key", str(uuid4()))

if scope["session"]:

if self.backend_type == BackendType.cookie:
cookie_data = scope["session"]
else:
self.session_backend.set(
await self.session_backend.set(
session_key, scope["session"], self.max_age
)
cookie_data = {self._cookie_session_id_field: session_key}
Expand All @@ -103,11 +106,7 @@ async def send_wrapper(message: Message, **kwargs) -> None:
elif not initial_session_was_empty:

if self.backend_type != BackendType.cookie:
data = connection.cookies[self.cookie_name].encode("utf-8")
session_key = json.loads(b64decode(data)).get(
self._cookie_session_id_field
)
self.session_backend.delete(session_key)
await self.session_backend.delete(session_key)

headers = MutableHeaders(scope=message)
header_value = self._construct_cookie(clear=True)
Expand All @@ -122,6 +121,8 @@ def _get_predefined_session_backend(self, backend_db_client) -> ISessionBackend:
return RedisSessionBackend(backend_db_client)
elif self.backend_type == BackendType.cookie:
return
elif self.backend_type == BackendType.aioRedis:
return AioRedisSessionBackend(backend_db_client)
else:
raise UnknownPredefinedBackend()

Expand Down
Loading

0 comments on commit 250dcd9

Please sign in to comment.