Metadata-Version: 2.3
Name: nicegui-hcaptcha
Version: 0.1.0
Summary: Provides a NiceGUI `Element` wrapper for integrating hCaptcha (https://www.hcaptcha.com/) into a NiceGUI application.
Requires-Dist: httpx>=0.28.1
Requires-Dist: nicegui>=3.8.0
Requires-Python: >=3.12
Description-Content-Type: text/markdown

# NiceGUI hCaptcha Element

Reusable hCaptcha integration for NiceGUI applications.

Features:

* Async token retrieval
* Server-side verification
* Hook-based extensibility

---

## Installation

```bash
pip install nicegui-hcaptcha
```

You also need:

* hCaptcha **site key**
* hCaptcha **secret key**

Both are available in the hCaptcha dashboard.

---

## Quick Start

```python
from nicegui import ui
from nicegui_hcaptcha import HCaptcha

captcha = HCaptcha(site_key="your_site_key_here")

async def submit():
    result = await captcha.verify(secret="your_secret_key_here")

    if not result.success:
        ui.notify(f"Captcha failed: {result.error_codes}")
        return

    ui.notify("Captcha verified")

ui.button("Submit", on_click=submit)
```

That is sufficient for basic usage.

---

## Verification Result

`verify()` returns:

```python
HCaptchaResult(
    success: bool,
    error_codes: Sequence[HCaptchaErrorCode] | None,
    token: str | None,
)
```

You are responsible for handling UI behavior.

---

## Error Codes

### Official hCaptcha Codes

* `missing-input-secret`
* `invalid-input-secret`
* `missing-input-response`
* `invalid-input-response`
* `expired-input-response`
* `already-seen-response`
* `bad-request`
* `missing-remoteip`
* `invalid-remoteip`
* `not-using-dummy-passcode`
* `sitekey-secret-mismatch`

### Custom Integration Codes

* `captcha-not-completed`
  Returned if `verify()` is called before user completion.

* `verification-request-failed`
  Returned if the verification request fails or response parsing fails.

---

## Registering Hooks

You can register async callbacks:

```python
async def on_captcha(result: HCaptchaResult) -> None:
    if result.success:
        print("Verified")
    else:
        print("Failed:", result.error_codes)

captcha.on_verified(on_captcha)
```

Hooks are executed after each verification.

---

## Resetting the Widget

```python
await captcha.reset()
```

This forces the user to complete a new challenge.

---

## Minimal Pattern for Forms

Typical pattern:

```python
result = await captcha.verify(secret)

if not result.success:
    return

# continue form processing
```
