Metadata-Version: 2.4
Name: sanic_sessions
Version: 0.9.0
Summary: Server-backed sessions for Sanic with InMemory, Redis, Memcache, and MongoDB support
Home-page: https://github.com/aime-labs/sanic-sessions
Author: Khaled Abdel Moezz
Author-email: Khaled Abdel Moezz <khaled.a.moezz@gmail.com>
License: MIT
Project-URL: Source, https://github.com/aime-labs/sanic-sessions
Project-URL: Tracker, https://github.com/aime-labs/sanic-sessions
Keywords: sanic,sessions,async,redis,memcache,mongodb
Classifier: Framework :: AsyncIO
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Internet :: WWW/HTTP :: Session
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: sanic>=21.12.0
Requires-Dist: ujson>=5.4.0
Provides-Extra: aioredis
Requires-Dist: aioredis>=2.0.0; extra == "aioredis"
Provides-Extra: redis
Requires-Dist: asyncio_redis>=0.16.0; extra == "redis"
Provides-Extra: mongo
Requires-Dist: sanic_motor>=2.1.0; extra == "mongo"
Requires-Dist: pymongo>=4.0.0; extra == "mongo"
Provides-Extra: memcache
Requires-Dist: aiomcache>=0.7.0; extra == "memcache"
Provides-Extra: full
Requires-Dist: aioredis>=2.0.0; extra == "full"
Requires-Dist: asyncio_redis>=0.16.0; extra == "full"
Requires-Dist: sanic_motor>=2.1.0; extra == "full"
Requires-Dist: pymongo>=4.0.0; extra == "full"
Requires-Dist: aiomcache>=0.7.0; extra == "full"
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.20.0; extra == "dev"
Requires-Dist: pytest-cov>=3.0.0; extra == "dev"
Requires-Dist: black>=22.0.0; extra == "dev"
Requires-Dist: isort>=5.10.0; extra == "dev"
Requires-Dist: mypy>=0.950; extra == "dev"
Requires-Dist: flake8>=4.0.0; extra == "dev"
Requires-Dist: wheel>=0.37.0; extra == "dev"
Requires-Dist: twine>=4.0.0; extra == "dev"
Provides-Extra: docs
Requires-Dist: sphinx>=5.0.0; extra == "docs"
Requires-Dist: sphinx-rtd-theme>=1.0.0; extra == "docs"
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# Sanic Session Management
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)

> ⚠️ **This package is a forked and updated version of [`sanic-session` 0.8.0](https://pypi.org/project/sanic-session/0.8.0/).**  
> It includes important fixes such as resolving the "Cookies Initializing" warning.  
> Updated and maintained by **Khaled Abdel Moezz** from **AIME GmbH**.

`sanic_sessions` is a session management extension for [Sanic](https://sanic.dev) that integrates server-backed sessions with a convenient API.

`sanic_sessions` provides a number of *session interfaces* for storing client session data. The available interfaces include:

- **Redis** (supports both `aioredis` and `asyncio_redis`)
- **Memcache** (via `aiomcache`)
- **MongoDB** (via `sanic_motor` and `pymongo`)
- **In-Memory** (suitable for testing and development environments)

---

## Installation

Install with `pip` (additional options available for different drivers — check documentation):

```bash
pip install sanic_sessions
```

---

## Usage Examples

### In-Memory Session Example

A simple example using the in-memory session interface:

```python
from sanic import Sanic
from sanic.response import text
from sanic_sessions import Session, InMemorySessionInterface

app = Sanic(name="ExampleApp")
session = Session(app, interface=InMemorySessionInterface())

@app.route("/")
async def index(request):
    # Interact with the session like a normal dict
    if not request.ctx.session.get('foo'):
        request.ctx.session['foo'] = 0

    request.ctx.session['foo'] += 1
    return text(str(request.ctx.session["foo"]))

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)
```

---

### Memcache Session Example

```python
from sanic import Sanic
from sanic.response import text
from sanic_sessions import Session
from sanic_sessions.memcache import MemcacheSessionInterface
import aiomcache

app = Sanic(name="MemcacheExample")

# Set up a Memcache client
memcache_client = aiomcache.Client("127.0.0.1", 11211)

# Bind Memcache session interface
session = Session(app, interface=MemcacheSessionInterface(
    cookie_name="session_id",
    memcache_connection=memcache_client,
    expiry=3600  # 1 hour
))

@app.route("/")
async def index(request):
    if not request.ctx.session.get('visits'):
        request.ctx.session['visits'] = 0

    request.ctx.session['visits'] += 1
    return text(f"Memcache session visit: {request.ctx.session['visits']}")

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)
```

> 💡 **Note:** To use Memcache sessions, make sure:
>
> - `aiomcache` is installed:
>   ```bash
>   pip install aiomcache
>   ```
> - Memcached server is running locally:
>   ```bash
>   sudo apt install memcached
>   sudo systemctl start memcached
>   sudo systemctl status memcached
>   ```


---

### Redis Session Example

```python
from sanic import Sanic
from sanic.response import text
from sanic_sessions import Session
from sanic_sessions.redis import RedisSessionInterface
from redis.asyncio import Redis

app = Sanic(name="RedisExample")

# Setup Redis connection
@app.before_server_start
async def setup_redis(app, _):
    app.ctx.redis = Redis(host="127.0.0.1", port=6379)
    await app.ctx.redis.ping()
    print("✅ Redis connection established")

@app.after_server_stop
async def close_redis(app, _):
    await app.ctx.redis.close()

# Attach Redis session interface
session = Session(app, interface=RedisSessionInterface(
    redis_getter=lambda: app.ctx.redis,
    cookie_name="redis_session",
    expiry=3600
))

@app.route("/")
async def index(request):
    if not request.ctx.session.get('hits'):
        request.ctx.session['hits'] = 0

    request.ctx.session['hits'] += 1
    return text(f"Redis session hits: {request.ctx.session['hits']}")

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)
```

> 💡 **Note:** Make sure `redis` is installed and running:
>
> - Install Python driver:
>   ```bash
>   pip install redis
>   ```
> - Start Redis server:
>   ```bash
>   sudo apt install redis
>   sudo systemctl start redis
>   sudo systemctl status redis
>   ```

