Integracja z Pythonem

Python można w pełni zabezpieczyć — bez pakietu i bez zależności. Sprawdzenie to jedno wywołanie HTTPS.

Nie udostępniamy SDK dla Pythona. To informacja o naszej dystrybucji, a nie o Państwa ochronie: to, co robią SDK, wykonuje poniższe wywołanie za pomocą biblioteki standardowej.

1. Osadzenie widgetu

Skrypt mierzy zachowanie w przeglądarce i umieszcza ukryte pole w każdym formularzu. Wystarczy dodać go raz w nagłówku stron.

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. Weryfikacja po stronie serwera

Przy wysyłce proszę odczytać ukryte pole i zapytać nas, zanim przyjmą Państwo zgłoszenie. Bez tego kroku decyduje wyłącznie przeglądarka — a bot bez JavaScriptu przechodzi obok.

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 i FastAPI

Powyższa funkcja jest niezależna od frameworka. Trzy miejsca wywołania są w komentarzu na końcu fragmentu: Flask czyta słownik formularza, Django dane POST, FastAPI parametr formularza.

Gdy jesteśmy nieosiągalni

Fragment przepuszcza wtedy odwiedzającego. Niesłusznie odrzucony klient kosztuje więcej niż przepuszczony bot. Jeśli wolą Państwo odwrotnie, proszę zwrócić fałsz w gałęzi błędu — wtedy awaria kosztuje utracone zgłoszenia.

Agenci AI

Obserwacje agentów proszę zgłaszać tym samym wzorcem do punktu telemetrii: jeden POST i ten sam nagłówek.

Lokalnego egzekwowania reguł nie da się wykonać z Pythona — wymaga weryfikacji podpisu Ed25519 nad pakietem reguł. Proszę umieścić enforcer przed aplikacją jako sidecar albo użyć Cloudflare Worker.