Metadata-Version: 2.4
Name: gemini-web-client
Version: 0.5.0
Summary: A Python package for automating Google Gemini web UI via Playwright
Author: Developer
License: GPL-3.0-or-later
Classifier: Programming Language :: Python :: 3
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: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Operating System :: OS Independent
Classifier: Topic :: Communications :: Chat
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: playwright>=1.40.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: rich>=12.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Dynamic: license-file

# Gemini Web Client (`gemini-web-client`)

[![PyPI version](https://img.shields.io/pypi/v/gemini-web-client.svg)](https://pypi.org/project/gemini-web-client/)
[![Python Version](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue.svg)](https://pypi.org/project/gemini-web-client/)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

A modern Python client package for automating [Google Gemini Web UI](https://gemini.google.com/) using Playwright.

## ✨ Features

- **Google Account Authentication**: Login helper tool (`gemini-login`) to save persistent sessions securely in a local browser profile.
- **ModelInterface Bridge Architecture**: Structured Model ↔ CLI bridge with model-driven content classification (`chat` vs `working`), topic tracking, and local device tool execution (`LocalToolRegistry`).
- **`Modelfile` System Pre-Knowledge**: Embedded prompt contract instructing the model on available local tools and metadata output formats.
- **Model Discovery & Switching**: List available models (`list_models()`) and switch active model (`select_model()`) or use `/model <number>`.
- **Async & Sync API**: Simple Python interface to send messages, stream responses, and manage multi-turn chat sessions.
- **Multimodal Support**: Attach images (PNG/JPG/WEBP) or documents (PDF, TXT, CSV, Python files) to your prompts.
- **Image Generation Extraction**: Detects inline generated images (Imagen / Gemini Web) and downloads them to disk.
- **HTML Table & Markdown Parsing**: Renders clean Markdown tables and code blocks directly in your terminal.
- **Interactive Terminal CLI**: Built-in CLI runner (`gemini-web`) with Rich syntax highlighting, slash commands, and real-time streaming.

---

## 🚀 Quick Start

### 1. Installation

Install directly from PyPI:

```bash
pip install gemini-web-client
playwright install chromium
```

*(For local development from source)*:
```bash
git clone https://github.com/hpnquoc/gemini-web-client.git
cd gemini-web-client
pip install -e .
playwright install chromium
```

### 2. Login to Google Account

Run the login assistant to sign in to your Google Account once:

```bash
gemini-login
```

Follow the prompt to log in in the opened browser window. Your session will be saved locally to `./.user_data`.

---

## 💡 Code Examples

### Basic Prompt Execution
```python
import asyncio
from gemini_web import GeminiWebClient

async def main():
    async with GeminiWebClient(headless=True) as client:
        response = await client.send_message("Explain quantum computing in simple terms.")
        print(response.text)

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

### Model Discovery & Switching
```python
import asyncio
from gemini_web import GeminiWebClient

async def main():
    async with GeminiWebClient(headless=True) as client:
        # List models in UI
        models = await client.list_models()
        print("Available Models:", models)

        # Switch to a specific model
        if models:
            await client.select_model("3.5 Flash-Lite")
            response = await client.send_message("What model are you?")
            print(response.text)

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

### Real-Time Response Streaming
```python
import asyncio
from gemini_web import GeminiWebClient

async def main():
    async with GeminiWebClient(headless=True) as client:
        async for chunk in client.send_message_stream("Write a short story about an AI."):
            print(chunk, end="", flush=True)

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

### Multi-Turn Chat Session
```python
import asyncio
from gemini_web import GeminiWebClient

async def main():
    async with GeminiWebClient(headless=True) as client:
        chat = client.start_chat()
        
        r1 = await chat.send_message("Hi, my name is Alice.")
        print(r1.text)
        
        r2 = await chat.send_message("What is my name?")
        print(r2.text)

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

### Chat History & Thread Navigation
```python
import asyncio
from gemini_web import GeminiWebClient

async def main():
    async with GeminiWebClient(headless=True) as client:
        # List all past chats in sidebar
        chats = await client.list_chats()
        for chat in chats:
            print(f"ID: {chat['id']} | Title: {chat['title']}")

        # Switch to a specific thread
        if chats:
            await client.switch_chat(chats[0]['id'])
            turns = await client.get_conversation_turns()
            print(f"Extracted {len(turns)} messages.")

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

---

## 🛠️ CLI Usage

Interactive Chat REPL:
```bash
gemini-web --user-data-dir ./.user_data
```

Login Assistant:
```bash
gemini-login --user-data-dir ./.user_data
```

---

## 📜 Changelog

See **[CHANGELOG.md](CHANGELOG.md)** for release history and version release notes.

---

## 📄 License

GNU General Public License v3.0 (GPL-3.0)
