geminpy
Automated OAuth wrapper for Google's Gemini CLI on macOS
geminpy eliminates the manual authentication steps required by Google's gemini CLI tool. It automatically handles the entire OAuth flow - from browser management to account selection - letting you use Gemini programmatically without interruption.
Why It Exists
Google's official gemini CLI requires manual OAuth authentication through a web browser each time you use it. This makes automation impossible and interrupts workflows. geminpy solves this by:
- Automating the OAuth dance - No manual clicking through Google's authentication screens
- Managing browser contexts - Uses isolated Chrome for Testing to avoid conflicts
- Handling rate limits gracefully - Automatically retries with flash model when rate limited
- Providing clean outputs - Filters authentication noise from responses
What It Does
geminpy acts as a transparent wrapper around the official gemini CLI, adding automation capabilities:
- Drop-in CLI replacement: Use it exactly like the original
geminicommand - Programmatic API: Call Gemini from Python code with
ask()function - Multi-language support: Handles OAuth pages in 9+ languages
- Smart user detection: Remembers your preferred Google account
- Rate limit resilience: Automatic fallback to
gemini-2.5-flashwhen quota exceeded - Browser isolation: Uses Chrome for Testing to avoid disrupting your main browser
How It Works
Technical Architecture
The package orchestrates several components to achieve seamless automation:
User Request → GeminiClient → Browser Setup → OAuth Automation → Gemini CLI → Response
↓ ↓ ↓ ↓
BrowserManager ChromeManager OAuthAutomator GeminiExecutor
↓ ↓ ↓ ↓
macdefaultbrowsy Chrome CDP Playwright subprocess
Automation Flow
-
Browser Preparation
- Installs Chrome for Testing if needed (via
@puppeteer/browsers) - Saves current default browser
- Temporarily switches to Chrome for Testing
- Installs Chrome for Testing if needed (via
-
OAuth Automation
- Launches Chrome with remote debugging (
--remote-debugging-port=9222) - Starts
geminiCLI which opens OAuth URL - Playwright connects via Chrome DevTools Protocol
- Automatically clicks your Google account
- Detects and clicks sign-in button (multi-language, multi-strategy)
- Waits for authentication success
- Launches Chrome with remote debugging (
-
Execution & Monitoring
- Monitors gemini process output in real-time
- Detects rate limits (429, quota exceeded, etc.)
- Automatically retries with fallback model if needed
- Extracts clean response from CLI output
-
Cleanup
- Restores original default browser
- Optionally quits Chrome
- Returns pure response text
Key Components
browser.manager: Controls macOS default browser viamacdefaultbrowsybrowser.chrome: Manages Chrome for Testing installation and lifecyclebrowser.automation: Playwright-based OAuth flow automationgemini.client: Main orchestrator coordinating all componentsgemini.executor: Subprocess management with real-time monitoringgemini.parser: Response extraction and cleaning
Installation
Prerequisites
macOS only - Browser automation requires macOS-specific tools.
Install geminpy
uv pip install geminpy
One-time setup: Install Playwright browsers
playwright install chromium
Usage
CLI Usage
Use exactly like the original gemini CLI:
# Ask a question
geminpy -p "Explain Python decorators"
# Use specific model with new shortcuts
geminpy -P -p "Write a Python function" # Uses gemini-2.5-pro
geminpy -F -p "Quick question" # Uses gemini-2.5-flash
# Traditional model selection still works
geminpy -m "gemini-pro" -p "Complex analysis"
# Enable verbose logging
geminpy --verbose -p "Debug this"
# Quit Chrome after completion
geminpy --quit-chrome -p "One-off query"
Programmatic Usage
from geminpy import ask
# Simple question-answer
response = ask("Explain quantum computing")
print(response)
# Async usage with full control
import asyncio
from geminpy import call_gemini_cli
async def main():
response = await call_gemini_cli(
gemini_args=["-m", "gemini-pro", "-p", "Your prompt"],
user="your.email@gmail.com",
verbose=True,
quit_browser=True
)
print(response)
asyncio.run(main())
Configuration
User Account Resolution
geminpy determines which Google account to use in this priority order:
- CLI argument:
--user="you@gmail.com" - Environment variable:
GEMINI_CLI_USER="you@gmail.com" - Stored settings: From previous successful authentication
- First available: Uses first Google account found
Settings Storage
Settings are automatically persisted to:
~/Library/Application Support/com.twardoch.chrometesting/settings.json
Contains:
- Chrome for Testing executable path
- Last used Google account email
Advanced Features
Multi-Language OAuth Support
Detects sign-in buttons in multiple languages:
- English, Polish, French, German, Spanish
- Italian, Russian, Japanese, Chinese
- Falls back to attribute and style-based detection
Rate Limit Handling
Automatic detection and retry logic:
Original request → Rate limit detected → Retry with gemini-2.5-flash → Final response
Browser Isolation
- Uses dedicated Chrome for Testing instance
- Preserves your regular browser state
- No profile contamination
- Clean OAuth every time
Troubleshooting
Common Issues
"Chrome CDP did not become available"
- Check if port 9222 is available:
lsof -i :9222 - Look at Chrome logs:
/tmp/gemini_chrome_stderr.log
"Could not find sign-in button"
- Enable verbose mode:
--verbose - Check screenshots:
oauth_error.png,oauth_error_no_signin.png - Ensure your Google account has Gemini access
Debug Mode
Enable comprehensive logging:
geminpy --verbose -p "Your question"
Shows:
- Chrome installation progress
- Browser switching operations
- OAuth automation steps
- Gemini CLI interactions
- Response parsing details
Development
Project Structure
src/geminpy/
├── browser/ # Browser automation components
│ ├── automation.py # OAuth flow automation
│ ├── chrome.py # Chrome for Testing management
│ └── manager.py # Default browser control
├── gemini/ # Gemini CLI integration
│ ├── client.py # Main orchestrator
│ ├── executor.py # Process management
│ └── parser.py # Response extraction
├── core/ # Core utilities
│ ├── config.py # Configuration
│ ├── constants.py # Constants
│ └── exceptions.py # Custom exceptions
├── utils/ # Utilities
│ ├── platform.py # Platform checks
│ └── storage.py # Settings persistence
├── api.py # Public API
└── cli.py # CLI interface
Running Tests
# Run all tests
uvx hatch run test
# Run with coverage
uvx hatch run test-cov
# Type checking
uvx hatch run type-check
# Linting
uvx hatch run lint
Building
# Build package
uvx hatch build
# Install locally
uv pip install --system -e .
Security
- No credential storage - Only stores email preference
- Local automation only - All OAuth happens on your machine
- Temporary browser access - Restored after each use
- Process isolation - Chrome runs in separate process
Requirements
- Platform: macOS (Darwin) only
- Python: 3.10, 3.11, or 3.12
- Browser: Chrome for Testing (auto-installed)
License
MIT License - see LICENSE file for details.
Metadata
Release files for geminpy 1.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| geminpy-1.4.1.tar.gz | 25.4 kB | Without provenance | Details for geminpy-1.4.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| geminpy-1.4.1-py3-none-any.whl | Python 3 | none | any | Details for geminpy-1.4.1-py3-none-any.whl |
Total release size: 53.2 kB
Release files / geminpy-1.4.1.tar.gz
| Download URL | geminpy-1.4.1.tar.gz |
|---|---|
| Size | 25.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
45ef173d1fa2928a7ab89a8f6523802288dfb155ceee7e128db13f960ec992e7
|
|
BLAKE2b-256 checksum How to use checksums |
1013f46cc4fc0d9e64330d2fe6ac060f8af2f3f3e818d33de68ce7b496a57713
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-httpx/0.28.1
|
Release files / geminpy-1.4.1-py3-none-any.whl
| Download URL | geminpy-1.4.1-py3-none-any.whl |
|---|---|
| Size | 27.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
295c717dfb840294d5051984dcbbba8abede6a1058324ef81ca72bd9058ee429
|
|
BLAKE2b-256 checksum How to use checksums |
9107a65a3aaa2b38eed2f6cad3b133fdb139b5b733667c613901d3c790da4fca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-httpx/0.28.1
|
Security for geminpy 1.4.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.