Все статьи
Иллюстрация обложки: Локальное тестирование вебхуков FastAPI: Request.body, подписи и async-безопасность
FastAPIPythonwebhook debuggingasynclocal testing

Локальное тестирование вебхуков FastAPI: Request.body, подписи и async-безопасность

FastAPI makes webhook endpoints easy to write, but easy is not the same as safe. The critical details are reading raw bytes exactly once, verifying provider signatures before parsing, and structuring async handlers so slow tasks do not trigger retries.

Read raw bytes with Request.body()

In FastAPI, call await request.body() to get the exact incoming payload bytes for signature verification. Avoid parsing JSON first if your provider signs raw payloads. Verification must be done against untouched bytes.

Signature verification flow

Extract provider headers, build the signed payload string expected by that provider, compute HMAC or asymmetric validation, and return 401 on mismatch. Keep verification deterministic and close to route entry so failures are obvious in logs.

raw_body = await request.body()
expected = compute_signature(secret, timestamp, raw_body)
if not timing_safe_compare(expected, signature_header):
    raise HTTPException(status_code=401, detail='invalid signature')

Design async handlers for quick acknowledgements

Webhook providers expect fast 2xx responses. In FastAPI, acknowledge quickly, then offload expensive work to a queue, background worker, or task system. This reduces retry storms and keeps latency stable under traffic spikes.

Local tunnel workflow for realistic tests

  1. Run your FastAPI app locally (Uvicorn or Hypercorn).
  2. Expose the port with npx portpreview 8000.
  3. Set provider webhook URLs to the generated HTTPS endpoint.
  4. Trigger test events and inspect headers, body, and response timing.
  5. Replay the same event ID to confirm idempotent behavior.

Idempotency is non-negotiable

Even perfectly verified requests can be delivered more than once. Use durable deduplication keys, transactional writes, and safe side-effect guards so duplicate deliveries do not create duplicate invoices, emails, or state transitions.

Further reading and implementation references

For fundamentals, read what localhost tunneling is and how to debug webhooks locally. For signature mechanics, use the verification guide. For retry-safe design, continue with retry and idempotency patterns. If you want to test faster with a single workflow, join the PortPreview waitlist.

Часто задаваемые вопросы

How do I keep FastAPI signature verification reliable?
Read the raw bytes once with await request.body(), verify the signature against those bytes, then decode or parse JSON only after verification succeeds.
Can FastAPI webhook handlers stay async end to end?
Yes. Keep verification lightweight, acknowledge quickly, and move slow work to background tasks or queues so webhook retries do not pile up.
What causes duplicate webhook side effects in FastAPI apps?
Provider retries, worker restarts, and race conditions. Use idempotency keys and durable deduplication storage so the same event is processed exactly once.