# -*- coding: utf-8 -*- """ Helper module which exposes abstractions to write webservers easily """ from abc import ABC, abstractmethod import socket import http.server as http from http import HTTPStatus from urllib.parse import parse_qs, urlparse import json class Response(): """ Represents a HTTP `Response` object """ def __init__(self, status, body=None, headers=None): if not isinstance(status, HTTPStatus): raise TypeError('status has to be of type http.HTTPStatus') if body and not isinstance(body, (str, dict)): raise TypeError('body has to be of type str or dict') if headers and not isinstance(headers, dict): raise TypeError('headers has to be of type dict') self.status = status self.body = body self.headers = headers def get_body(self): if not self.body: return '' if isinstance(self.body, dict): return json.dumps(self.body) return self.body class Request(): """ Represents a HTTP `Request` object """ def __init__(self, path, qs=None, body=None, json=None, headers=None): self.path = path self.qs = qs self.body = body self.json = json self.headers = headers class RequestHandler(ABC): """ The class that users should sub-class and provide implementation. Each of these functions **should** return an instance of the `Response` class """ @abstractmethod def get(self, request): pass @abstractmethod def post(self, request): pass def MkHandlers(handlers): class HTTPHandler(http.BaseHTTPRequestHandler): def not_found(self): self.send_response(HTTPStatus.NOT_FOUND) self.end_headers() self.wfile.write('