Build & Publish Package / publish (push) Successful in 49s
- Add opt-in SESSION_REDIS_JSON storage for asyncio Redis backends. - Check JSON command support at startup and reject JSON mode on Trio. - Read legacy strings and migrate sessions on their next save. - Validate JSON objects before transactional replacement and expiry. - Preserve tagged serialization for datetime, tuple, and other types. - Cover command contracts, error handling, and session round-trips. - Document server requirements, permissions, and migration limits. - Normalize indentation and whitespace across code, tests, and examples. - Bump the package and lockfile to 4.1.0 and update the changelog. - Refresh the locked pycparser dependency to 3.12.
46 lines
1.1 KiB
Python
46 lines
1.1 KiB
Python
from typing import Optional
|
|
|
|
import pytest
|
|
from quart import Quart, session
|
|
|
|
from quart_session import Session
|
|
|
|
@pytest.fixture
|
|
def app_factory():
|
|
"""Builds a Quart app backed by an in-memory session store."""
|
|
|
|
def _factory(**config) -> Quart:
|
|
app = Quart(__name__)
|
|
app.secret_key = "test-secret-key"
|
|
app.config["SESSION_TYPE"] = "null"
|
|
app.config.update(config)
|
|
Session(app)
|
|
|
|
# 'null' interface is a no-op store, give it a dict so that
|
|
# open_session() can actually find data again.
|
|
store: dict = {}
|
|
interface = app.session_interface
|
|
|
|
async def _get(key: str, app: Optional[Quart] = None):
|
|
return store.get(key)
|
|
|
|
async def _set(key: str, value, expiry: Optional[int] = None,
|
|
app: Optional[Quart] = None):
|
|
store[key] = value
|
|
|
|
async def _delete(key: str, app: Optional[Quart] = None):
|
|
store.pop(key, None)
|
|
|
|
interface.get = _get
|
|
interface.set = _set
|
|
interface.delete = _delete
|
|
|
|
@app.route("/")
|
|
async def index():
|
|
session["hits"] = session.get("hits", 0) + 1
|
|
return {"hits": session["hits"], "sid": session.sid}
|
|
|
|
return app
|
|
|
|
return _factory
|