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 ADDED
@@ -0,0 +1,9 @@
1
+ from .app import MenzoAPI
2
+ from .app import Request
3
+ from .server import Server
4
+
5
+ __all__ = [
6
+ "MenzoAPI",
7
+ "Request",
8
+ "Server"
9
+ ]
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
+ Metadata-Version: 2.4
2
+ Name: menzoapi
3
+ Version: 0.0.2
4
+ Summary: FastAPI-inspired micro framework
5
+ Author: Menzo
6
+ Dynamic: author
7
+ Dynamic: summary
@@ -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,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ menzoapi