Python¶
The myra-eucaptcha package verifies the token on the server. It supplies a synchronous interface and an asynchronous interface.
Requirements¶
The following requirements must be met:
| Requirement | Value |
|---|---|
| Package manager | pip or uv |
| Credentials | Public sitekey and secret from the Details view |
Install the package¶
Install the package from PyPI:
With the uv package manager, the command is as follows:
Embed the widget¶
Add the widget to the form to protect:
Add the script link to the page:
The script renders the widget, does the challenge, and adds the token to the form.
Thus, a full page is as follows:
<html>
<head>
<title>captcha integration sample</title>
</head>
<body>
<form action="/login" method="post">
<table>
<tr>
<td>user</td>
<td>
<input type=text name="username" />
</td>
</tr>
<tr>
<td>pass</td>
<td>
<input type=password name="password" />
</td>
</tr>
<tr>
<td colspan="2">
<div class="eu-captcha" data-sitekey="EUCAPTCHA_SITE_KEY"></div>
</td>
</tr>
<tr><td colspan="2"><input type="submit" name="submit" /></td></tr>
</table>
</form>
<script src="https://cdn.eu-captcha.eu/verify.js" async defer></script>
</body>
</html>
Verify the token¶
This example shows the verification on the server with FastAPI:
from myra_eucaptcha import MyraEuCaptchaClient, MyraEuCaptchaClientConfig
@app.post("/login", response_class=HTMLResponse)
async def login(
request:Request,
username: str = Form(...),
password: str = Form(...),
eu_captcha_response: str = Form(..., alias="eu-captcha-response"),
):
# configure the captcha settings and behaviour
captcha_config = MyraEuCaptchaClientConfig(
sitekey="EUCAPTCHA_SITE_KEY",
secret="EUCAPTCHA_SECRET_KEY",
)
client = MyraEuCaptchaClient(config=captcha_config)
# this is depending on your webserver-setup and whether we're behind
# a reverse-proxy (nginx, apache, traefik, or something similar.)
remote_addr = request.headers.get('x-real-ip','')
validationresult = await client.avalidate(
token=eu_captcha_response,
remote_addr=remote_addr)
if validationresult.success:
# yay - all good.
# <your-code-here>
pass
else:
# validation failed, check validationresult.errors
# <your-code-here>
pass
The asynchronous verification uses avalidate(), the synchronous verification uses validate().
The source of the IP address of the visitor depends on your web server. If the application is behind an upstream system such as nginx, Apache, or Traefik, read the address from the applicable header.
Behaviour for errors¶
By default, the package is fault-tolerant: for a timeout, an API error, or a network error, the verification gives the True result. No exception occurs. The errors that occurred are given in MyraEuCaptchaResult.errors.
You change this behaviour with MyraEuCaptchaClientConfig:
captcha_config = MyraEuCaptchaClientConfig(
sitekey="EUCAPTCHA_SITE_KEY",
secret="EUCAPTCHA_SECRET_KEY",
connect_timeout: int = 3
read_timeout: int = 10
write_timeout: int = 10
pool_timeout: int = 3
default_result_on_error:bool = True ## this is the validation result, that is returned on exceptions
suppress_exceptions:bool = True ## if you want exceptions to be raised, set this to False
)
| Setting | Default | Effect |
|---|---|---|
connect_timeout |
3 |
Time limit for the connection setup in seconds. |
read_timeout |
10 |
Time limit to read the response in seconds. |
write_timeout |
10 |
Time limit to send the request in seconds. |
pool_timeout |
3 |
Time limit for an available connection from the connection pool in seconds. |
default_result_on_error |
True |
Result of the verification when an exception occurs. |
suppress_exceptions |
True |
Set to False, the package causes the exception instead of suppressing it. |
For Django, see Django.
Full example¶
See Vue and Python.