Skip to content

Instantly share code, notes, and snippets.

@aenglander
Last active February 24, 2023 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aenglander/e653985ea3c6336daad9b032b6f438b7 to your computer and use it in GitHub Desktop.
Save aenglander/e653985ea3c6336daad9b032b6f438b7 to your computer and use it in GitHub Desktop.
Example WSGI app and middleware for What the Heck is a WSGI Presentation
from io import BytesIO
from wsgiref.simple_server import make_server
def app(environ, start_response):
try:
content_length = int(environ["CONTENT_LENGTH"])
name = environ["wsgi.input"].read(content_length)
except (KeyError, ValueError):
name = b"World"
status = "200 OK"
response_headers = [("Content-Type", "text/plain")]
start_response(status, response_headers)
return [b"Hello, ", name, b"!"]
class StartResponseCapture:
def __init__(self):
self.status = None
self.headers = {}
def __call__(self, status, headers):
self.status = status
self.headers = headers
class CachingMiddleware:
def __init__(self, next_):
self.__next = next_
self.__cache = {}
def __call__(self, environ, start_response):
try:
content_length = int(environ["CONTENT_LENGTH"])
wsgi_input = environ["wsgi.input"].read(content_length)
environ["wsgi.input"] = BytesIO(wsgi_input)
except (KeyError, ValueError):
wsgi_input = b""
if wsgi_input in self.__cache:
cached = True
cached_data = self.__cache[wsgi_input]
status = cached_data["status"]
headers = cached_data["headers"]
response = cached_data["response"]
else:
cached = False
start_response_capture = StartResponseCapture()
result = self.__next(environ, start_response_capture)
status = start_response_capture.status
headers = start_response_capture.headers
response = [chunk for chunk in result]
self.__cache[wsgi_input] = {
"status": status,
"headers": headers,
"response": response,
}
start_response(status, headers + [("X-Cache-Hit", str(cached))])
return response
caching_app = CachingMiddleware(app)
if __name__ == '__main__':
with make_server('127.0.0.1', 5000, caching_app) as httpd:
print("Serving HTTP on port 5000...")
httpd.serve_forever()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment