Skip to content

Instantly share code, notes, and snippets.

@ddribin
Last active July 3, 2026 14:44
Show Gist options
  • Select an option

  • Save ddribin/b5cb7ac049a83a62c1e67ecb570601d2 to your computer and use it in GitHub Desktop.

Select an option

Save ddribin/b5cb7ac049a83a62c1e67ecb570601d2 to your computer and use it in GitHub Desktop.
Mock API for testing HTTP auth using a Bearer token or Basic username and password.
#!/usr/bin/env python3
"""Mock API for testing HTTP auth using a Bearer token or Basic username and password."""
import base64
import json
import os
import time
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
TOKEN = os.environ.get("API_TOKEN", "token123")
USER = os.environ.get("API_USER", "user")
PASS = os.environ.get("API_PASS", "pass123")
PORT = int(os.environ.get("PORT", "8000"))
# Seconds to wait before replying, to simulate network/server latency.
DELAY = float(os.environ.get("DELAY", "0"))
def is_authorized(header):
scheme, _, rest = header.partition(" ")
if scheme.lower() == "bearer":
return rest == TOKEN
if scheme.lower() == "basic":
try:
user, _, pw = base64.b64decode(rest).decode().partition(":")
except ValueError:
return False
return user == USER and pw == PASS
return False
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
delay = float(self.headers.get("X-Delay", DELAY))
self.log_message("delaying %ss", delay)
time.sleep(delay)
authorized = is_authorized(self.headers.get("Authorization", ""))
status = 200 if authorized else 401
payload = {"msg": "success"} if authorized else {"errors": [{"reason": "Invalid Token"}]}
body = (json.dumps(payload) + "\n").encode()
self.send_response(status)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
if __name__ == "__main__":
print(f"http://127.0.0.1:{PORT} (Bearer {TOKEN}; Basic {USER}:{PASS}; Delay {DELAY})")
try:
ThreadingHTTPServer(("127.0.0.1", PORT), Handler).serve_forever()
except KeyboardInterrupt:
print()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment