Metadata-Version: 2.4
Name: PyQt6-extensions
Version: 0.2.0
Summary: Read a question from a .txt file and turn it into a good looking PyQt5 desktop app that solves it, using Gemini (directly or through a Cloudflare Worker). The interface is generated as a Qt Designer .ui file and the logic as a test.py that loads it.
Author-email: hackclub39 <hackclub39@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/PrinceYadav78/PyQt6-extensions
Keywords: gemini,code generation,cli,beginner,python
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Environment :: Console
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PyQt5>=5.15
Provides-Extra: direct
Requires-Dist: google-genai>=0.3.0; extra == "direct"
Dynamic: license-file

# PyQt6-extensions

A command line tool named `extend`. You put a question in a `.txt` file, run one
command, and it uses Google's **Gemini** model to write a **good looking PyQt5
desktop app** that actually solves the question. The interface comes back as a Qt
Designer file (`designer.ui`) and the logic as a Python file (`test.py`) that
loads it with `PyQt5.uic` — the same clean split you would get from Qt Designer by
hand. It launches the app to check it starts without crashing, asks Gemini to fix
anything that breaks, and saves both files.

The clever part: instead of putting a Gemini key on every user's machine, the
tool can talk to a small **Cloudflare Worker** that you deploy once. Your Gemini
key lives only inside that Worker as a secret, so people can use the tool on your
key **without ever seeing it**.

```
extend question.txt
```

## What it does

1. Reads the question from the `.txt` file you point it at.
2. Asks how big you want the program (a hint for the model).
3. Sends the question to Gemini (through your Worker, or directly) and asks for
   **two files**: a `designer.ui` (a Qt Designer XML layout) for the interface and
   a `test.py` that loads it with `PyQt5.uic` and adds the logic that solves the
   task.
4. Launches the generated app headless — with `designer.ui` sitting next to
   `test.py` so the load path works — to make sure it starts. The `.ui` is also
   checked as valid XML. If anything crashes, the error goes back to Gemini for a
   fix (up to `--attempts` times).
5. Saves both `designer.ui` and `test.py` next to your question file.

> With `--plain` there is no interface, so it stays a single `test.py` file.

## Install

```bash
pip install .                 # the tool + PyQt5 (needed to run the apps)
pip install ".[direct]"       # also add this if you will call Gemini directly
```

Once published you would instead run `pip install PyQt6-extensions`.

## Two ways to run it

### A) Through your Cloudflare Worker (recommended — your key stays hidden)

Deploy the Worker in `cloudflare-worker/` once (steps below), then point the tool
at it. Users need **no** Gemini key of their own.

The easiest way to share it: after you deploy, paste your Worker URL into
`pyqt6_extensions/config.py`:

```python
DEFAULT_WORKER_URL = "https://pyqt6-extensions-worker.YOURNAME.workers.dev"
```

Now anyone you give these files to can just run `extend question.txt` with no
setup — no key, no URL, no access code. (You can also override per run with
`--worker-url` or the `EXTEND_WORKER_URL` environment variable.)

### B) Directly with your own Gemini key (good for local development)

```bash
pip install ".[direct]"
export GEMINI_API_KEY="your_key_here"
extend question.txt --lines 60
```

If both are set, the Worker wins.

## Deploy the Cloudflare Worker

The Worker is the piece that holds your key and calls Gemini. Everything is in
`cloudflare-worker/`.

```bash
npm install -g wrangler          # Cloudflare's CLI
cd cloudflare-worker
wrangler login

# store your key as a SECRET (it never lives in the code)
wrangler secret put GEMINI_API_KEY      # paste your Gemini key

wrangler deploy
```

`wrangler deploy` prints a URL like
`https://pyqt6-extensions-worker.YOURNAME.workers.dev`. Paste that into
`pyqt6_extensions/config.py` (or share it as `EXTEND_WORKER_URL`).

- The `GEMINI_API_KEY` is a **secret**, set only with `wrangler secret put`. It
  never appears in the code, the repo, or the files you hand out.
- `wrangler.toml` ships with `ALLOW_OPEN = "true"`, which means **no access
  code**: anyone with the URL can use it. That is what you asked for.
- If you ever want to lock it down later, delete the `ALLOW_OPEN` line and run
  `wrangler secret put ACCESS_CODE`; callers then pass it with `--access-code`.

**Because it is open, you pay for everyone who has the URL.** If usage or cost
ever becomes a worry, add an access code or rate limiting.

## Use it

Put your question in a text file:

```text
# question.txt
A tip calculator: enter the bill and a tip percent, show the tip and the total.
```

Then run:

```bash
extend question.txt --lines 60
```

This writes two files next to the question: `designer.ui` and `test.py`. Open the
result with `python test.py` (keep `designer.ui` in the same folder — `test.py`
loads it from next to itself) and you get a styled PyQt5 window that does the job.
You can also open `designer.ui` in Qt Designer to tweak the look by hand.

### Run it truly in the background

```bash
extend question.txt --lines 60 --background
# returns immediately, keeps working while you use your editor,
# and writes a progress log next to test.py
```

### Make a plain text program instead of a GUI

```bash
extend question.txt --lines 20 --plain
```

## Options

| Option | What it does |
| --- | --- |
| `--lines N` | Rough size hint for the model. Asked for if left out. |
| `--worker-url URL` | Your Cloudflare Worker URL. Falls back to `EXTEND_WORKER_URL`. |
| `--access-code CODE` | Access code for the Worker. Falls back to `EXTEND_ACCESS_CODE`. |
| `--api-key KEY` | Gemini key for direct calls. Falls back to `GEMINI_API_KEY`. |
| `--model NAME` | Gemini model for direct calls. Default `gemini-3.1-pro-preview`. |
| `--plain` | Make a simple text program instead of a PyQt5 app. |
| `--output PATH`, `-o PATH` | Where to save `test.py`. Default next to the question. `designer.ui` is written in the same folder. |
| `--attempts N` | How many times to auto-fix bugs. Default 4. |
| `--background` | Detach and keep working even if you close the terminal. Needs `--lines`. |
| `--quiet` | Print nothing while it works. |

## How the checking works

- The code is parsed first, so syntax errors are caught immediately.
- The `designer.ui` file is checked as valid XML with a `<ui>` root before
  anything runs, so a broken layout is caught early and sent back for a fix.
- For a **GUI** app both files are written to a temporary folder together and the
  app is launched headless (`QT_QPA_PLATFORM=offscreen`), so `PyQt5.uic` really
  loads `designer.ui`. The Qt event loop is short circuited so a healthy app builds
  its whole window and then exits cleanly. If it crashes while starting, or hangs
  before the window opens, the error is sent back to Gemini for a fix. This
  confirms the app really runs, but it cannot prove the answer is correct, so still
  check the result yourself.
- If PyQt5 or a display is not available on your machine, the launch step is
  skipped (the code is still syntax checked) and you are told so.
- For a `--plain` program it is run with sample input and a time limit, and any
  crash or endless loop is sent back for a fix.

## A note on the model name

You asked for "Gemini 3.1 pro preview". The real id is `gemini-3.1-pro-preview`
(the older `gemini-3-pro-preview` was retired). It is the default. If your key is
not allow listed for it, both the tool and the Worker fall back to
`gemini-2.5-pro`.

## A note on the package name

`PyQt6-extensions` is the name you chose, so it is what this uses, even though the
generated apps use **PyQt5**. If you ever publish to public PyPI, that name may be
flagged as misleading; renaming is just the `name` field in `pyproject.toml`.

## License

MIT.
