menzoapi 0.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- menzoapi/__init__.py +9 -0
- menzoapi/app.py +39 -0
- menzoapi/server.py +179 -0
- menzoapi-0.0.2.dist-info/METADATA +7 -0
- menzoapi-0.0.2.dist-info/RECORD +7 -0
- menzoapi-0.0.2.dist-info/WHEEL +5 -0
- menzoapi-0.0.2.dist-info/top_level.txt +1 -0
menzoapi/__init__.py
ADDED
menzoapi/app.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class Request:
|
|
2
|
+
def __init__(self, handler, params=None, json_data=None):
|
|
3
|
+
self.handler = handler
|
|
4
|
+
self.params = params or {}
|
|
5
|
+
self.json = json_data or {}
|
|
6
|
+
self.headers = dict(handler.headers)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class MenzoAPI:
|
|
10
|
+
def __init__(self):
|
|
11
|
+
self.routes = {
|
|
12
|
+
"GET": [],
|
|
13
|
+
"POST": []
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
self.middlewares = []
|
|
17
|
+
self.error_handlers = {}
|
|
18
|
+
|
|
19
|
+
def get(self, path):
|
|
20
|
+
def decorator(func):
|
|
21
|
+
self.routes["GET"].append((path, func))
|
|
22
|
+
return func
|
|
23
|
+
return decorator
|
|
24
|
+
|
|
25
|
+
def post(self, path):
|
|
26
|
+
def decorator(func):
|
|
27
|
+
self.routes["POST"].append((path, func))
|
|
28
|
+
return func
|
|
29
|
+
return decorator
|
|
30
|
+
|
|
31
|
+
def middleware(self, func):
|
|
32
|
+
self.middlewares.append(func)
|
|
33
|
+
return func
|
|
34
|
+
|
|
35
|
+
def exception(self, exc):
|
|
36
|
+
def decorator(func):
|
|
37
|
+
self.error_handlers[exc] = func
|
|
38
|
+
return func
|
|
39
|
+
return decorator
|
menzoapi/server.py
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
from http.server import HTTPServer, BaseHTTPRequestHandler
|
|
2
|
+
from .app import Request
|
|
3
|
+
import json
|
|
4
|
+
import traceback
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Server:
|
|
8
|
+
|
|
9
|
+
def __init__(self, app):
|
|
10
|
+
self.app = app
|
|
11
|
+
|
|
12
|
+
def _match_route(self, path, routes):
|
|
13
|
+
|
|
14
|
+
for pattern, func in routes:
|
|
15
|
+
|
|
16
|
+
if "{" not in pattern:
|
|
17
|
+
if pattern == path:
|
|
18
|
+
return func, {}
|
|
19
|
+
|
|
20
|
+
p1 = pattern.strip("/").split("/")
|
|
21
|
+
p2 = path.strip("/").split("/")
|
|
22
|
+
|
|
23
|
+
if len(p1) != len(p2):
|
|
24
|
+
continue
|
|
25
|
+
|
|
26
|
+
params = {}
|
|
27
|
+
matched = True
|
|
28
|
+
|
|
29
|
+
for a, b in zip(p1, p2):
|
|
30
|
+
|
|
31
|
+
if a.startswith("{") and a.endswith("}"):
|
|
32
|
+
key = a[1:-1]
|
|
33
|
+
params[key] = b
|
|
34
|
+
|
|
35
|
+
elif a != b:
|
|
36
|
+
matched = False
|
|
37
|
+
break
|
|
38
|
+
|
|
39
|
+
if matched:
|
|
40
|
+
return func, params
|
|
41
|
+
|
|
42
|
+
return None, {}
|
|
43
|
+
|
|
44
|
+
def run(self, host="127.0.0.1", port=8000):
|
|
45
|
+
|
|
46
|
+
app = self.app
|
|
47
|
+
|
|
48
|
+
class Handler(BaseHTTPRequestHandler):
|
|
49
|
+
|
|
50
|
+
def send_json(self, data, status=200):
|
|
51
|
+
|
|
52
|
+
self.send_response(status)
|
|
53
|
+
self.send_header(
|
|
54
|
+
"Content-Type",
|
|
55
|
+
"application/json"
|
|
56
|
+
)
|
|
57
|
+
self.end_headers()
|
|
58
|
+
|
|
59
|
+
self.wfile.write(
|
|
60
|
+
json.dumps(data).encode()
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
def handle_request(self, method):
|
|
64
|
+
|
|
65
|
+
if self.path == "/docs":
|
|
66
|
+
|
|
67
|
+
docs = []
|
|
68
|
+
|
|
69
|
+
for m, routes in app.routes.items():
|
|
70
|
+
|
|
71
|
+
for route, _ in routes:
|
|
72
|
+
|
|
73
|
+
docs.append({
|
|
74
|
+
"method": m,
|
|
75
|
+
"path": route
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
return self.send_json({
|
|
79
|
+
"framework": "MenzoAPI",
|
|
80
|
+
"version": "0.0.2",
|
|
81
|
+
"routes": docs
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
routes = app.routes[method]
|
|
85
|
+
|
|
86
|
+
func, params = (
|
|
87
|
+
Server._match_route(
|
|
88
|
+
None,
|
|
89
|
+
self.path,
|
|
90
|
+
routes
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
if not func:
|
|
95
|
+
return self.send_json(
|
|
96
|
+
{"error": "Not Found"},
|
|
97
|
+
404
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
body = {}
|
|
101
|
+
|
|
102
|
+
if method == "POST":
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
length = int(
|
|
106
|
+
self.headers.get(
|
|
107
|
+
"Content-Length",
|
|
108
|
+
0
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
raw = self.rfile.read(
|
|
113
|
+
length
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
body = json.loads(raw)
|
|
117
|
+
|
|
118
|
+
except:
|
|
119
|
+
body = {}
|
|
120
|
+
|
|
121
|
+
request = Request(
|
|
122
|
+
self,
|
|
123
|
+
params=params,
|
|
124
|
+
json_data=body
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
try:
|
|
128
|
+
|
|
129
|
+
for mw in app.middlewares:
|
|
130
|
+
mw(request)
|
|
131
|
+
|
|
132
|
+
result = func(request)
|
|
133
|
+
|
|
134
|
+
self.send_json(result)
|
|
135
|
+
|
|
136
|
+
except Exception as e:
|
|
137
|
+
|
|
138
|
+
handler = (
|
|
139
|
+
app.error_handlers.get(
|
|
140
|
+
type(e)
|
|
141
|
+
)
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
if handler:
|
|
145
|
+
|
|
146
|
+
result = handler(e)
|
|
147
|
+
|
|
148
|
+
self.send_json(
|
|
149
|
+
result,
|
|
150
|
+
500
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
else:
|
|
154
|
+
|
|
155
|
+
traceback.print_exc()
|
|
156
|
+
|
|
157
|
+
self.send_json(
|
|
158
|
+
{
|
|
159
|
+
"error":
|
|
160
|
+
str(e)
|
|
161
|
+
},
|
|
162
|
+
500
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
def do_GET(self):
|
|
166
|
+
self.handle_request("GET")
|
|
167
|
+
|
|
168
|
+
def do_POST(self):
|
|
169
|
+
self.handle_request("POST")
|
|
170
|
+
|
|
171
|
+
print(
|
|
172
|
+
f"MenzoAPI v0.0.2 running on "
|
|
173
|
+
f"http://{host}:{port}"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
HTTPServer(
|
|
177
|
+
(host, port),
|
|
178
|
+
Handler
|
|
179
|
+
).serve_forever()
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
menzoapi/__init__.py,sha256=58r5cDuEtbFxITXXHmN5GbwUSQDPpQkKGfSd656yFj8,144
|
|
2
|
+
menzoapi/app.py,sha256=oG7Fm4tWv3yUwXMiUBUouGnxvyopyUItXqJk_m3OiZY,1005
|
|
3
|
+
menzoapi/server.py,sha256=b5RsH9eRAnIhA9FjK4Uk9Uif14SpYl4Ez54O5J40Po8,4554
|
|
4
|
+
menzoapi-0.0.2.dist-info/METADATA,sha256=IWbdXbnjg1GwHQ3AZaYCHPLjrxFkkkeQyJFKDlu6pi4,148
|
|
5
|
+
menzoapi-0.0.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
6
|
+
menzoapi-0.0.2.dist-info/top_level.txt,sha256=_hQ2xCUULu4vbcRdTJ1hFWA6fgqpfUzBPoX7m5U8350,9
|
|
7
|
+
menzoapi-0.0.2.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
menzoapi
|