-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathwebpylike.py
58 lines (47 loc) · 1.64 KB
/
webpylike.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
"""Implements web.py like dispatching. What this module does not
implement is a stream system that hooks into sys.stdout like web.py
provides.
"""
import re
from werkzeug.exceptions import HTTPException
from werkzeug.exceptions import MethodNotAllowed
from werkzeug.exceptions import NotFound
from werkzeug.exceptions import NotImplemented
from werkzeug.wrappers import Request
from werkzeug.wrappers import Response # noqa: F401
class View:
"""Baseclass for our views."""
def __init__(self, app, req):
self.app = app
self.req = req
def GET(self):
raise MethodNotAllowed()
POST = DELETE = PUT = GET
def HEAD(self):
return self.GET()
class WebPyApp:
"""
An interface to a web.py like application. It works like the web.run
function in web.py
"""
def __init__(self, urls, views):
self.urls = [
(re.compile(f"^{urls[i]}$"), urls[i + 1]) for i in range(0, len(urls), 2)
]
self.views = views
def __call__(self, environ, start_response):
try:
req = Request(environ)
for regex, view in self.urls:
match = regex.match(req.path)
if match is not None:
view = self.views[view](self, req)
if req.method not in ("GET", "HEAD", "POST", "DELETE", "PUT"):
raise NotImplemented() # noqa: F901
resp = getattr(view, req.method)(*match.groups())
break
else:
raise NotFound()
except HTTPException as e:
resp = e
return resp(environ, start_response)