Рубрики
Без рубрики

Создайте свой WebFrameWork в Python

В этом мире написано много действительно хороших WebFrameWorks. Вы знаете эти веб -структуры … Tagged с Python.

В этом мире написано много действительно хороших WebFrameWorks. Вы знаете эти веб -фреймворки на WSGI, так что давайте сейчас создадим свою оригинальную веб -структуру!

Если вы хотите узнать подробную информацию о спецификации WSGI, пожалуйста, обратитесь к PEP3333 Анкет Этот пост не заботится о каких -либо деталях, просто реализуя.

К счастью, у вас уже есть сервер WSGI, определенный по адресу wsgiref модуль. Все, что вам нужно, это создание точки записи приложения WSGI.

Самое простое приложение похоже на ниже.

# app.py
from wsgiref.simple_server import make_server


def app(environ, start_response):
    start_response('200 OK', headers=[('Content-Type', 'text/plain:charset=utf-8')])
    response = [b'my toy app']
    return response


with make_server('', 8088, app) as server:
    server.serve_forever()

Хм, это так скучно. Как правило, в WebFramework должна быть обработчики HTTP -запросов и системы маршрутизации. Так что я должен иметь это. Сначала я должен подумать о том, как использовать в реальном мире.

from wsgiref.simple_server import make_server


things = {x: x.upper()  for x in ('a', 'b', 'c')}


def get_all_things(request):
    return ','.join(things.keys())


def create_things(request):
    # do something
    return 'ok'


class App:
    def get(self, path, handler):
        # TODO
        return self

    def post(self, path, handler):
        # TODO
        return self

    def __call__(self, environment, start_response):
        # TODO
        return response

    def start(self):
        with make_server('', 8088, self) as server:
            server.serve_forever()


app = App().get('/things', get_all_things).post('/things', create_things)
app.start()

У этой веб -рамки есть

  • Маршрутинг
  • Строка запроса
  • Параметр пути
  • Только получить и публиковать обработчики
  • Класс приложений включает в себя стартер WSGI Server

и нет

  • Промежуточное программное обеспечение
  • Любая обработка ошибок
  • Статическая порция
  • Шаблон
  • Гибкий тип контента
  • Перенаправить
  • Еще еще еще..

Это реализует пример.

from urllib.parse import parse_qs
from collections import defaultdict
import re
from wsgiref.simple_server import make_server


class App:
    handler_map = defaultdict(dict)

    def _register(self, method_name, path, handler):
        self.handler_map[fr'^{path}$'].update({method_name: handler})
        return self

    def get(self, path, handler):
        return self._register('get', path, handler)

    def post(self, path, handler):
        return self._register('post', path, handler)

    def _find_handler(self, path, method):
        for pattern, info in self.handler_map.items():
            matched = re.match(pattern, path)
            if matched:
                return info[method], matched.groupdict()

    def __call__(self, environment, start_response):
        method = environment['REQUEST_METHOD'].lower()
        path = environment['PATH_INFO']
        status = {
            'get': '200 OK',
            'post': '201 Created',
        }[method]
        start_response(status, headers=[('Content-Type', 'text/plain:charset=utf-8')])
        request_body = {
            'get': lambda: environment['QUERY_STRING'],
            'post': lambda: environment['wsgi.input'].read(int(environment.get('CONTENT_LENGTH', 0))).decode(),
        }[method]
        handler, path_params = self._find_handler(path, method)
        response = handler(parse_qs(request_body), **path_params)
        return [response.encode()]

    def start(self):
        with make_server('', 8088, self) as server:
            server.serve_forever()

Пути маршрутизации и картирование обработчиков являются важными вещами.

Приложение Пути маршрутизации воспоминаний и соответствующие обработчики в handler_map Анкет

Смотрите _ Регистрация Анкет

    def _register(self, method_name, path, handler):
        self.handler_map[fr'^{path}$'].update({method_name: handler})
        return self

    def get(self, path, handler):
        return self._register('get', path, handler)

    def post(self, path, handler):
        return self._register('post', path, handler)

Это справедливая обертка метода против каждого метода HTTP. Так Приложение Получает запрашиваемый обратный путь.

Я выбор Re модуль для обнаружения пути, такого как Джанго и т. Д.

Запрос на обработку в __call__ Анкет

    def __call__(self, environment, start_response):
        method = environment['REQUEST_METHOD'].lower()
        path = environment['PATH_INFO']
        status = {
            'get': '200 OK',
            'post': '201 Created',
        }[method]
        start_response(status, headers=[('Content-Type', 'text/plain:charset=utf-8')])
        request_body = {
            'get': lambda: environment['QUERY_STRING'],
            'post': lambda: environment['wsgi.input'].read(int(environment.get('CONTENT_LENGTH', 0))).decode(),
        }[method]()
        handler, path_params = self._find_handler(path, method)
        response = handler(parse_qs(request_body), **path_params)
        return [response.encode()]

__call__ делает простые процессы.

  • получает метод HTTP
  • получает путь запроса
  • Создает тело запроса, соответствующее методу HTTP
  • Приносит обработчик
  • вызывает обработчик

Хорошо, теперь я получаю свой собственный веб -фреймворк! Попробуйте бежать.

Начальный сервер.

$ python3 app.py

И запрос.

$ curl localhost:8088
$ curl localhost:8088/things
$ curl localhost:8088/things/a
$ curl -X POST -d 'x=X' localhost:8088/things

Наконец, я создал крошечную игрушку, а не продуктивную WebFramework с именем Томойо что немного сложнее, чем выше WebFramework.

Пока!

Оригинал: “https://dev.to/mtwtkman/build-your-we-framework-in-python-2nj0”