Gemx
Drive the Gemini web UI from Python. A play on "Gemini" — Gemx treats
gemini.google.com as if it were an API, using Playwright to enter a prompt,
submit it, and capture the structured reply.
It exists because the obvious approaches don't work: Gemini's editor is
Quill, which keeps its own document model and ignores
DOM surgery, Playwright fill(), and synthetic input events — those leave the
model empty and the turn errors with "I encountered an error." Gemx injects
text via execCommand('insertText') (the same trusted input pipeline a manual
paste uses), reads the reply from message-content .markdown, and retains the
peak streamed text because Gemini re-mounts the response node mid-stream.
Install
uv add gemx
# Playwright needs a browser the first time:
uv run playwright install chromium
CLI
# JSON (default)
gemx "List 3 NBA teams as a JSON array"
# XML
gemx --format xml "Describe the solar system as XML"
# Plain text, reading the prompt from stdin
echo "Summarize the plot of Dune in one sentence" | gemx --format txt
# Watch the browser while it works
gemx --no-headless --verbose "Hello there"
The chosen --format (json, xml, or txt) is appended to the prompt as an
instruction and drives how Gemx parses the reply.
| Option | Description |
|---|---|
-f, --format {json,xml,txt} |
Output format (default: json). |
-p, --profile-dir PATH |
Chrome profile dir (default: ~/.gemx/profile). |
--no-headless |
Show the browser window. |
--browser-channel |
Playwright browser channel to launch; defaults to chrome with --no-headless. |
--response-timeout SECONDS |
Wait for a response to start (default: 180). |
--max-retries COUNT |
Retry transient Gemini response failures up to COUNT times. Omitted means no retries. |
-v, --verbose |
Log DEBUG progress to stderr. |
Library
import asyncio
from pathlib import Path
from gemx import Gemx, GemxConfig, OutputFormat
async def main() -> None:
config = GemxConfig(profile_dir=Path("~/.gemx/profile"), log_level="INFO")
async with Gemx(config) as gemx:
data = await gemx.ask("List 3 fruits as JSON", OutputFormat.JSON)
print(data)
asyncio.run(main())
Set log_level="DEBUG" for full browser automation diagnostics, or
log_level="WARNING" to emit only problems.
Authentication
Gemx drives a real, signed-in Gemini session. Point --profile-dir at a Chrome
profile that is already logged into your Google account (run once with
--no-headless to sign in); subsequent runs reuse that profile.
Development
uv sync
uv run ruff check .
uv run mypy
uv run pylint src/gemx
uv run pytest
The browser-console debugging scripts used to discover and verify the current
Gemini selectors live in tests/scripts/.
License
MIT © ra0x3 — Stonehedge Labs
Release files for gemx 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gemx-0.2.0.tar.gz | 20.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gemx-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.4 kB
Release files / gemx-0.2.0.tar.gz
| Download URL | gemx-0.2.0.tar.gz |
|---|---|
| Size | 20.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
176074d52d38fd1f21bee47e3cfb1de9948bc827a91d0fa6cd04b543e44621b0
|
|
BLAKE2b-256 checksum How to use checksums |
a86dc64a3f4327ca1e46d67200e7c329272c0ebe7cfb30e2543b2b0af8488952
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.22
|
Release files / gemx-0.2.0-py3-none-any.whl
| Download URL | gemx-0.2.0-py3-none-any.whl |
|---|---|
| Size | 14.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
01580907738513c4a6e27e82015981fb6aa9c67480d01efc3fda787b1eff56b4
|
|
BLAKE2b-256 checksum How to use checksums |
81fc57bf97404542de1147fe451a9e5849cd37f756be76f7b0a5ba68c6e03d52
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.22
|