Python との連携

Python は完全に保護できます。パッケージも依存関係も不要で、確認は HTTPS 呼び出し 1 回だけです。

当社は Python の SDK を提供していません。これは配布方法の話であり、保護の可否ではありません。SDK が行うことは、下記の呼び出しが標準ライブラリだけで行います。

1. ウィジェットの読み込み

スクリプトがブラウザ上の挙動を計測し、各フォームに隠しフィールドを追加します。ページのヘッダーに一度だけ追加してください。

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. サーバー側での確認

送信時に隠しフィールドを読み取り、送信を受け入れる前に当社へ問い合わせてください。この手順がないとブラウザだけで判断することになり、JavaScript を実行しないボットはそのまま通過します。

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

上記の関数はフレームワークに依存しません。呼び出し箇所は抜粋の末尾にコメントとして 3 つ記載しています。Flask はフォーム辞書、Django は POST データ、FastAPI はフォームパラメータから読み取ります。

当社に接続できない場合

この抜粋では訪問者を通過させます。誤って拒否された顧客の損失は、通過したボットより大きいためです。逆の動作を望む場合はエラー分岐で偽を返してください。その場合、障害時には送信が失われます。

AI エージェント

エージェントの観測も同じ方法でテレメトリ用エンドポイントへ報告します。POST 1 回、ヘッダーも同じです。

ルールのローカル適用は Python からは行えません。ルール一式に対する Ed25519 署名の検証が必要なためです。エンフォーサーをサイドカーとしてアプリケーションの前段に置くか、Cloudflare Worker をご利用ください。