Skip to main content

Drive ChatGPT and Gemini from Python — no API keys, no billing, just the free web UI.

Project description

Hermex
Drive ChatGPT and Gemini from Python — no API keys, no billing, just the free web UI.

PyPI Python 3.11+ MIT License GitHub Repo Docs


ChatGPT and Gemini are incredibly capable — but their official APIs are expensive, and for many tasks you simply don't need them. If you want to run OCR on an image, generate artwork, extract text from a screenshot, or just ask a quick question in a script, paying per-token for API access is overkill when the free web UI can do the same thing.

Hermex lets you drive ChatGPT and Gemini from Python just like a human would: it opens a real Chrome browser, types your message, uploads your files, waits for the response, and hands it back to you as a Python object. No API keys, no billing, no rate-limit tiers.

from hermex import ChatGPT

response = ChatGPT.simple_query("What does this receipt say?", attachments=["receipt.jpg"])
print(response.text)

It uses undetected-chromedriver under the hood to avoid bot detection, and reuses a persistent browser profile so your login session survives across runs.

Installation

pip install hermex

Requires Python 3.11+ and Google Chrome 130+.

First-time setup

Hermex reuses a persistent Chrome profile so you only need to log in once:

from hermex import Gemini

Gemini.setup()  # opens a browser — log in, browse briefly, then close the window

After setup, all future runs reuse the saved session automatically. Repeat this if your session expires.

Guest mode (no login) works for basic text queries on Gemini but file upload requires a logged-in session. ChatGPT works without login for text queries and file upload, but image generation requires a logged-in session.

Usage

Single query

from hermex import Gemini, ChatGPT

# Gemini
gemini = Gemini()
gemini.open_url()
response = gemini.query("Summarize the history of the internet.")
print(response.text)
gemini.close()

# ChatGPT
chatgpt = ChatGPT()
chatgpt.open_url()
response = chatgpt.query("Summarize the history of the internet.")
print(response.text)
chatgpt.close()

Attaching files

response = gemini.query(
    "Describe what's in this image.",
    attachments=["photo.jpg"],
)
print(response.text)

Supported formats: .jpg, .jpeg, .png, .gif, .webp, .pdf, .csv, .txt, .json. Each platform exposes its allowed types via Gemini.SUPPORTED_ATTACHMENTS and ChatGPT.SUPPORTED_ATTACHMENTS.

One-shot query

from hermex import Gemini, ChatGPT

response = Gemini.simple_query("What is the capital of France?")
print(response.text)

response = ChatGPT.simple_query("What is the capital of France?")
print(response.text)

# With an attachment
response = Gemini.simple_query("Describe this image.", attachments=["photo.jpg"])
print(response.text)

AssistantMessage object

query() and get_last_response() return an AssistantMessage dataclass:

@dataclass
class AssistantMessage:
    text: str | None   # plain text (or markdown if get_markdown=True)
    image: Path | None # path to downloaded image, or None

API reference

Both Gemini and ChatGPT share the same interface — all methods below apply to both unless noted.

Method Description
open_url(url, timeout) Open the chat interface in the browser
send_message(message, submit, attachments, paste, fake_typing, typing_delay) Type and optionally submit a message
query(message, timeout, attachments, paste, get_markdown, remove_watermark) Send a message, wait for the response, and return it
get_last_response(get_markdown, remove_watermark) Retrieve the most recent response
wait_until_idle(timeout) Block until the chatbot finishes generating
get_state() Return the current UI state (State.IDLE, GENERATING, TYPING, UPLOADING)
simple_query(prompt, attachments, timeout) Class method — open, query, close in one call
short_wait() Sleep ~7 seconds
long_wait() Sleep ~5 minutes
refresh_page() Reload the current page
close() Close the browser
setup() One-time login setup (class method)

See the full documentation for detailed guides on Gemini and ChatGPT.

Constructor options

Gemini(
    chrome_version=None,      # auto-detected from installed Chrome
    download_dir=Path("."),   # where generated images are saved
    headless=False,
    typing_delay=0.025,       # seconds between keystrokes
    disable_web_security=True,
)
# ChatGPT accepts the same parameters

Watermark removal

Gemini watermarks its generated images. Pass remove_watermark=True to strip it:

response = gemini.query("Generate an image of a sunset.", remove_watermark=True)

Notes

  • Bot detection is mitigated through per-character typing delays, fake typing before paste, a persistent browser profile, and a spoofed user agent. Avoid running headless for sensitive sessions.
  • Browser profile and session data are stored in the platform data directory (~/Library/Application Support/hermex on macOS).
  • This library relies on browser automation and may break if the UI changes. Use responsibly and be aware of each platform's terms of service.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hermex-0.2.1.tar.gz (29.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hermex-0.2.1-py3-none-any.whl (29.8 kB view details)

Uploaded Python 3

File details

Details for the file hermex-0.2.1.tar.gz.

File metadata

  • Download URL: hermex-0.2.1.tar.gz
  • Upload date:
  • Size: 29.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for hermex-0.2.1.tar.gz
Algorithm Hash digest
SHA256 87fd5fed0187eada4cb40c2dfcd3cfc90707d98957ec208e7e49b99798bc95ef
MD5 5b880cc30f4dc379d2fd6f12741ea99e
BLAKE2b-256 4c20d12908b1c04aa7c0a947f7d16d5061c22efb481cca3f47194d67c2760954

See more details on using hashes here.

Provenance

The following attestation bundles were made for hermex-0.2.1.tar.gz:

Publisher: publish.yml on pseudo-usama/hermex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hermex-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: hermex-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 29.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for hermex-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2a5df068995b92381d11f07411832fa35c7dfddf622af196bbc47e59bb100980
MD5 56fb9d4d69ba3575800872d7c9899e8f
BLAKE2b-256 db5f28db9308a3b1639ab9c81a77207e33f8523c7a1ea0b6b13cf8ed557c84b5

See more details on using hashes here.

Provenance

The following attestation bundles were made for hermex-0.2.1-py3-none-any.whl:

Publisher: publish.yml on pseudo-usama/hermex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page