support POST

This commit is contained in:
Adam Wilson
2025-04-22 20:58:16 -06:00
parent eecd577eba
commit 66371bf208
2 changed files with 42 additions and 17 deletions
+32 -9
View File
@@ -1,22 +1,45 @@
import cgi
import json
class PathDispatcher:
def __init__(self):
self.routes = {}
self.response_headers = [('Content-Type', 'application/json')]
def __http_415_notsupported(self, env, start_response):
start_response('415 Unsupported Media Type', self.response_headers)
return [json.dumps({'error': 'Unsupported Content-Type'}).encode('utf-8')]
def __http_200_ok(self, env, start_response):
try:
request_body_size = int(env.get('CONTENT_LENGTH', 0))
except (ValueError):
request_body_size = 0
request_body = env['wsgi.input'].read(request_body_size)
data = json.loads(request_body.decode('utf-8'))
start_response('200 OK', self.response_headers)
return [json.dumps({'received': data}).encode('utf-8')]
def notfound_404(self, env, start_response):
start_response('404 Not Found', [ ('Content-Type', 'text/plain') ])
return [b'Not Found']
def __call__(self, env, start_response):
method = env.get('REQUEST_METHOD').upper()
path = env.get('PATH_INFO')
params = cgi.FieldStorage(env.get('wsgi.output'), environ=env)
method = env.get('REQUEST_METHOD').lower()
env['params'] = { key: params.getvalue(key) for key in params }
handler = self.routes.get((method,path), self.notfound_404)
return handler(env, start_response)
if not method == 'POST':
self.__http_415_notsupported(env, start_response)
try:
handler = self.routes.get((method,path), self.__http_200_ok)
return handler(env, start_response)
except json.JSONDecodeError:
start_response('400 Bad Request', self.response_headers)
return [json.dumps({'error': 'Invalid JSON'}).encode('utf-8')]
def register(self, method, path, function):
self.routes[method.lower(), path] = function
return function
+10 -8
View File
@@ -1,3 +1,5 @@
import json
from PathDispatcher import PathDispatcher
from wsgiref.simple_server import make_server
@@ -6,19 +8,19 @@ class RestApiServer:
def __init__(self):
pass
def response_function(self, environ, start_response):
start_response('200 OK', [('Content-Type','text/html')])
yield str(f'testing...\n').encode('utf-8')
def post_response(self, env, start_response):
start_response('200 OK', [('Content-Type', 'application/json')])
yield [json.dumps({'received': 'data'}).encode('utf-8')]
def listen(self):
port = 9999
dispatcher = PathDispatcher()
dispatcher.register('GET', '/hello', self.response_function)
wsgi_srv = make_server('', port, dispatcher)
print(f'listening on port {port}...')
wsgi_srv.serve_forever()
dispatcher.register('POST', '/', self.post_response)
with make_server('', port, dispatcher) as wsgi_srv:
print(f'listening on port {port}...')
wsgi_srv.serve_forever()
if __name__ == '__main__':
srv = RestApiServer()
srv.listen()
srv.listen()