# ADK MongoDB Session Service

[![PyPI version](https://badge.fury.io/py/adk-mongodb-session.svg)](https://badge.fury.io/py/adk-mongodb-session)
[![Python Package CI](https://github.com/your-username/adk-mongodb-session/actions/workflows/python-package.yml/badge.svg)](https://github.com/your-username/adk-mongodb-session/actions/workflows/python-package.yml)

A session management library for the Google ADK framework that uses MongoDB as a backend.

This package provides a `MongodbSessionService` that implements the `google.adk.sessions.base_session_service.BaseSessionService` abstract base class. It allows you to store and manage session state in a MongoDB database, fully replicating the three-tiered state management (`app`, `user`, and `session`) found in the core ADK session services.

## Features

-   **MongoDB Backend**: Persist session and state data in a MongoDB database.
-   **Tiered State Management**: Automatically manage state at the application, user, and session levels.
-   **ADK Integration**: Implements the `BaseSessionService` for seamless integration with the Google ADK framework.
-   **Async Support**: All service methods are asynchronous.

## Installation

You can install the package from PyPI:

```bash
pip install adk-mongodb-session
```

For development, clone the repository and install it in editable mode with the testing dependencies:

```bash
git clone https://github.com/your-username/adk-mongodb-session.git
cd adk-mongodb-session
pip install -e ".[test]"
```

## Usage

First, instantiate the `MongodbSessionService` with your MongoDB connection details.

```python
import asyncio
from adk_mongodb_session.mongodb.sessions import MongodbSessionService

# Initialize the service
session_service = MongodbSessionService(
    db_url="mongodb://localhost:27017/",
    database="my_adk_app",
    collection_prefix="sessions"  # This will create sessions_sessions, sessions_app_states, etc.
)

async def main():
    # Use the service to create, retrieve, and manage sessions
    new_session = await session_service.create_session(
        app_name="my_app",
        user_id="user_123",
    )
    print(f"Created session with ID: {new_session.id}")

if __name__ == "__main__":
    asyncio.run(main())
```

### Tiered State Management

The service automatically handles the three-tiered state. When you create a session, you can provide state keys with the prefixes `app:` and `user:` to store data at the corresponding level. This state is automatically merged and made available in the `session.state` attribute.

```python
import asyncio
from google.adk.sessions.state import State

# ... (service initialization)

async def main():
    # Create a session with tiered state
    session = await session_service.create_session(
        app_name="my_app",
        user_id="user_123",
        state={
            f"{State.APP_PREFIX}theme": "dark",
            f"{State.USER_PREFIX}language": "en",
            "session_specific_data": "foo"
        }
    )
    
    # The session object will have a merged view of the state
    print(session.state)
    # Expected output:
    # {
    #     'app:theme': 'dark',
    #     'user:language': 'en',
    *     'session_specific_data': 'foo'
    # }

    # Retrieve the session later
    retrieved_session = await session_service.get_session(
        app_name="my_app",
        user_id="user_id_123",
        session_id=session.id
    )
    print(retrieved_session.state) # Will also contain the merged state

if __name__ == "__main__":
    asyncio.run(main())
```

## Running Tests

To run the tests, first install the testing dependencies:

```bash
pip install -e ".[test]"
```

Then, run the tests using `unittest`:

```bash
python -m unittest discover tests
```

## Contributing

Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for details on how to report bugs, suggest enhancements, and submit pull requests.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
