Close the API loop by receiving inbound HTTP payloads from external services — without a web framework. Build a webhook server using Python's stdlib http.server, read POST bodies from the raw socket stream, validate GitHub-style HMAC-SHA256 signatures with hmac.compare_digest, and respond with correct HTTP status codes (200, 400, 401, 411). The lesson closes with webhook_receiver.py: a self-contained server that loads the shared secret from .env, routes events by type, and emits structured log output — all patterns used daily in DevOps event pipelines.
Create the lesson-404 working directory, copy the .env and config files from lesson 403, add WEBHOOK_SECRET to .env, and confirm that http.server, hmac, and hashlib are available in the Python stdlib — no pip install needed.
mkdir -p ~/devops-python/lesson-404cd ~/devops-python/lesson-404source ~/devops-python/lesson-101/devops-env/bin/activatecp ~/devops-python/lesson-403/.env ~/devops-python/lesson-404/.envcp ~/devops-python/lesson-403/config.yaml ~/devops-python/lesson-404/config.yamlcp ~/devops-python/lesson-403/.gitignore ~/devops-python/lesson-404/.gitignoreecho 'WEBHOOK_SECRET=dev-secret-12345' >> ~/devops-python/lesson-404/.envgrep 'WEBHOOK_SECRET' ~/devops-python/lesson-404/.envpython3 -c "from http.server import BaseHTTPRequestHandler, HTTPServer; import hmac, hashlib; print('stdlib imports OK'); print(' http.server.BaseHTTPRequestHandler'); print(' http.server.HTTPServer'); print(' hmac.new, hmac.compare_digest'); print(' hashlib.sha256')"The three stdlib modules used in this lesson require no pip install. http.server provides BaseHTTPRequestHandler — the class you subclass to define how each HTTP method is handled — and HTTPServer — the class that binds a port and dispatches incoming connections to your handler. hmac provides hmac.new(key, msg, digestmod) to compute a keyed hash and hmac.compare_digest(a, b) to compare signatures without timing leaks. hashlib provides hashlib.sha256 as the digest algorithm argument.
WEBHOOK_SECRET=dev-secret-12345 is a placeholder secret for local development.
In production the value would be a random string of at least 32 characters set by the service that sends the webhook.
The grep command prints one line: WEBHOOK_SECRET=dev-secret-12345.
The python3 import check prints stdlib imports OK followed by the four symbol names — no ModuleNotFoundError.