Integración con Python

Python se puede proteger por completo, sin paquete ni dependencia. La comprobación es una sola llamada HTTPS.

No publicamos un SDK de Python. Eso habla de nuestra distribución, no de su protección: lo que hacen los SDK lo hace la llamada de abajo con la biblioteca estándar.

1. Añadir el widget

El script mide el comportamiento en el navegador y coloca un campo oculto en cada formulario. Añádalo una vez en la cabecera de sus páginas.

HTMLhtml
<!-- Add to <head> with SRI for security -->
(function () {
  var KEY = "YOUR_API_KEY";
  var SITE = location.hostname;
  var V = "2025.09.1";
  var s = document.createElement('script');
  s.src = "https://api.silentshield.io/client.js?k=" + encodeURIComponent(KEY)
    + "&v=" + encodeURIComponent(V)
    + "&site=" + encodeURIComponent(SITE);
  s.async = true;
  s.crossOrigin = "anonymous";
  document.head.appendChild(s);
})();

2. Verificar en su servidor

Al enviar, lea el campo oculto y consúltenos antes de aceptar el envío. Sin este paso decide solo el navegador, y un bot sin JavaScript lo esquiva.

Pythonpython
# No package required — the check is one HTTPS POST.
# Standard library only: nothing to install, nothing to keep updated.
import json
import os
import urllib.error
import urllib.request

VERIFY_URL = "https://api.silentshield.io/api/v1/captcha/verify-nonce"
API_KEY = os.environ["SILENTSHIELD_KEY"]  # never hard-code it


def is_human(nonce: str) -> bool:
    """Ask SilentShield about one submission.

    The hidden field `behavior_nonce` is injected by client.js;
    read it from the posted form and hand it over unchanged.
    """
    if not nonce:
        return False

    request = urllib.request.Request(
        VERIFY_URL,
        data=json.dumps({"nonce": nonce}).encode(),
        headers={
            "Content-Type": "application/json",
            "X-Api-Key": API_KEY,
            # Tells us which integration is in use, exactly like the SDKs do.
            "X-SS-SDK": "python-inline/1",
        },
        method="POST",
    )

    try:
        with urllib.request.urlopen(request, timeout=5) as response:
            data = json.loads(response.read())
    except (urllib.error.URLError, TimeoutError, ValueError):
        # We are unreachable. Let the visitor through: a real customer turned
        # away costs more than a bot let in. Flip this to False only if you
        # would rather lose submissions than accept one unchecked.
        return True

    return (
        data.get("ok") is True
        and data.get("verdict") == "human"
        and data.get("confidence", 0) >= 0.7
    )


# --- Flask ---------------------------------------------------------------
# @app.post("/contact")
# def contact():
#     if not is_human(request.form.get("behavior_nonce", "")):
#         abort(400, "Please submit the form again.")
#     ...

# --- Django --------------------------------------------------------------
# def contact(request):
#     if not is_human(request.POST.get("behavior_nonce", "")):
#         return HttpResponseBadRequest("Please submit the form again.")
#     ...

# --- FastAPI -------------------------------------------------------------
# @app.post("/contact")
# async def contact(behavior_nonce: str = Form("")):
#     if not is_human(behavior_nonce):
#         raise HTTPException(status_code=400, detail="Please submit the form again.")
#     ...

Flask, Django y FastAPI

La función anterior es independiente del framework. Los tres puntos de llamada aparecen como comentarios al final del fragmento: Flask lee el diccionario del formulario, Django los datos POST, FastAPI un parámetro de formulario.

Si no estamos disponibles

El fragmento deja pasar al visitante. Un cliente rechazado por error cuesta más que un bot admitido. Si prefiere lo contrario, devuelva falso en la rama de error: entonces una caída le costará envíos.

Agentes de IA

Comunique los avistamientos de agentes con el mismo patrón al punto de telemetría: un POST y la misma cabecera.

Aplicar las reglas localmente no es posible desde Python: requiere verificar una firma Ed25519 sobre un paquete de reglas. Coloque el enforcer delante de su aplicación como sidecar o use el Worker de Cloudflare.