🚧 progress
This commit is contained in:
parent
7f88c01156
commit
738adee6c2
@ -27,3 +27,7 @@ class ParseError(SpiderwebException):
|
||||
|
||||
class GeneralException(SpiderwebException):
|
||||
pass
|
||||
|
||||
|
||||
class UnusedMiddleware(SpiderwebException):
|
||||
pass
|
||||
|
@ -12,6 +12,7 @@ from typing import Callable, Any
|
||||
|
||||
from spiderweb.converters import * # noqa: F403
|
||||
from spiderweb.exceptions import APIError, ConfigError, ParseError, GeneralException
|
||||
from spiderweb.request import Request
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -95,7 +96,7 @@ class APIServer(HTTPServer):
|
||||
self.add_route(route, method)
|
||||
|
||||
try:
|
||||
super().__init__(server_address, HandlerClass)
|
||||
super().__init__(server_address, self.handler_class)
|
||||
except OSError:
|
||||
raise GeneralException("Port already in use.")
|
||||
|
||||
@ -137,21 +138,32 @@ class APIHandler(BaseHTTPRequestHandler):
|
||||
# BaseHTTPRequestHandler uses for some weird reason
|
||||
_routes = {}
|
||||
|
||||
def get_request(self):
|
||||
return Request(
|
||||
content="",
|
||||
body="",
|
||||
method=self.command,
|
||||
headers=self.headers,
|
||||
path=self.path
|
||||
)
|
||||
|
||||
def do_GET(self):
|
||||
self.do_action()
|
||||
request = self.get_request()
|
||||
self.handle_request(request)
|
||||
|
||||
def do_POST(self):
|
||||
content = "{}"
|
||||
if self.headers["Content-Length"]:
|
||||
length = int(self.headers["Content-Length"])
|
||||
content = self.rfile.read(length)
|
||||
info = None
|
||||
request = self.get_request()
|
||||
request.content = content
|
||||
if content:
|
||||
try:
|
||||
info = json.loads(content)
|
||||
request.json()
|
||||
except json.JSONDecodeError:
|
||||
raise APIError(400, "Invalid JSON", content)
|
||||
self.do_action(info)
|
||||
self.handle_request(request)
|
||||
|
||||
def get_route(self, path) -> tuple[Callable, dict[str, Any]]:
|
||||
for option in self._routes.keys():
|
||||
@ -161,23 +173,22 @@ class APIHandler(BaseHTTPRequestHandler):
|
||||
)
|
||||
raise APIError(404, "No route found")
|
||||
|
||||
def do_action(self, info=None):
|
||||
info = info or {}
|
||||
def handle_request(self, request):
|
||||
try:
|
||||
url = urlparse.urlparse(self.path)
|
||||
request.url = urlparse.urlparse(request.path)
|
||||
|
||||
handler, additional_args = self.get_route(url.path)
|
||||
handler, additional_args = self.get_route(request.url.path)
|
||||
|
||||
if url.query:
|
||||
params = urlparse.parse_qs(url.query)
|
||||
if request.url.query:
|
||||
params = urlparse.parse_qs(request.url.query)
|
||||
else:
|
||||
params = {}
|
||||
|
||||
info.update(params)
|
||||
request.query_params = params
|
||||
|
||||
if handler:
|
||||
try:
|
||||
response = handler(info, **additional_args)
|
||||
response = handler(request, **additional_args)
|
||||
self.send_response(200)
|
||||
if response is None:
|
||||
response = ""
|
||||
|
@ -0,0 +1,31 @@
|
||||
from typing import Optional, NoReturn
|
||||
|
||||
from spiderweb.request import Request
|
||||
from spiderweb.response import HttpResponse
|
||||
|
||||
|
||||
class SpiderwebMiddleware:
|
||||
"""
|
||||
All middleware should inherit from this class and have the following
|
||||
(optional!) methods:
|
||||
|
||||
process_request(self, request) -> None or Response
|
||||
process_response(self, request, response) -> None
|
||||
|
||||
Middleware can be used to modify requests and responses in a variety of ways.
|
||||
If one of the two methods is not defined, the request or response will be passed
|
||||
through unmodified.
|
||||
|
||||
If `process_request` returns
|
||||
|
||||
"""
|
||||
def process_request(self, request: Request) -> HttpResponse | None:
|
||||
# example of a middleware that sets a flag on the request
|
||||
request.spiderweb = True
|
||||
|
||||
|
||||
def process_response(self, request: Request, response: HttpResponse) -> NoReturn:
|
||||
# example of a middleware that sets a header on the response
|
||||
if hasattr(request, 'spiderweb'):
|
||||
response['X-Spiderweb'] = 'true'
|
||||
return response
|
17
spiderweb/request.py
Normal file
17
spiderweb/request.py
Normal file
@ -0,0 +1,17 @@
|
||||
import json
|
||||
|
||||
|
||||
class Request:
|
||||
def __init__(self, content=None, body=None, method=None, headers=None, path=None, url=None, query_params=None):
|
||||
self.content: str = content
|
||||
self.body: str = body
|
||||
self.method: str = method
|
||||
self.headers: dict[str] = headers
|
||||
self.path: str = path
|
||||
self.url = url
|
||||
self.query_params = query_params
|
||||
|
||||
def json(self):
|
||||
return json.loads(self.content)
|
||||
|
||||
|
14
spiderweb/response.py
Normal file
14
spiderweb/response.py
Normal file
@ -0,0 +1,14 @@
|
||||
class HttpResponse:
|
||||
...
|
||||
|
||||
|
||||
class JsonResponse(HttpResponse):
|
||||
...
|
||||
|
||||
|
||||
class RedirectResponse(HttpResponse):
|
||||
...
|
||||
|
||||
|
||||
class TemplateResponse(HttpResponse):
|
||||
...
|
Loading…
Reference in New Issue
Block a user