Джанго врач анализирует кодовые базы и предлагает улучшения. Раньше это был только SaaS, но сегодня мы выпустили его как автономный инструмент командной строки. В этом сообщении объясняется, как мы использовали React, чтобы сделать хороший пользовательский интерфейс для нашего интерфейса командной строки Python:
Для нашего инструмента командной строки мы хотели хороший пользовательский интерфейс. Мы используем React для нашего веб -сайта, поэтому мы рассмотрели, как передавать данные из Python, чтобы отреагировать и обратно, таким образом, чтобы его можно было легко распределить через PIP установить django-doctor
Анкет Мы не использовали Django или Flask, так как хотели яблоко, а не горилла, держащее яблоко.
Следующий компонент React – это мастер форм, который принимает список элементов и позволяет пользователю выбирать подмножество, тогда эта подмножество элементов размещается на сервере:
// App.jsx export default function({ messages }) { const [httpState, setHttpState] = React.useState({ isInProgress: false, isComplete: false, }) function handleSave(selectedMessages) { setHttpState({isInProgress: true, isComplete: false }) fetch('/done/', { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify(selectedMessages) }).then(result => { setHttpState({isInProgress: false, isComplete: true }) }).catch(result => { setHttpState({isInProgress: false, isComplete: false }) }) } if (httpState.isComplete) { return}
Мы можем передать в компонент некоторые данные, предоставленные сценарием Python, выполнив следующее:
// index.js import React from 'react'; import { render } from "react-dom"; import './App.css'; import './App.jsx'; const contextElement = document.getElementById('context-messages') const messages = JSON.parse(contextElement.textContent) render(, rootElement);
Так index.js
Ожидает, что HTML -страница, от которой она обслуживается, чтобы содержать элемент с id контекст-месс
Чтобы содержать несколько сериализованных данных JSON. Теперь, где входит Python. Мы обслуживаем файл HTML, используя функции, предоставленные Build Python в Wsgiref
библиотека:
# wsgi.py import json import mimetypes import pathlib import threading from wsgiref.simple_server import make_server from wsgiref.util import FileWrapper # a folder containing the built React app, which we trick python into working with by adding an __init__.py to it import django_doctor.wizard static_dir = pathlib.Path(django_doctor.wizard.__path__[0]) with open(static_dir / 'index.html', 'r') as f: home_template_body = f.read() def home_handler(environ, respond, app): # exposing data to the HTML template using an approach inspired by https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#json-script messages = json.dumps(app.messages) body = home_template_body.replace( '', f'' ) body = response_body.encode('utf-8') respond('200 OK', [('Content-Type', 'text/html'), ('Content-Length', str(len(body)))]) return [body] def static_handler(environ, respond, app): # serve the css/js/png/etc files content_type = mimetypes.guess_type(environ['PATH_INFO'])[0] path = static_dir / environ['PATH_INFO'][1:] respond('200 OK', [('Content-Type', content_type)]) return FileWrapper(open(path, "rb")) def submit_handler(environ, respond, app): body_size = int(environ.get('CONTENT_LENGTH', 0)) request_body = environ['wsgi.input'].read(body_size) selected_messages = json.loads(request_body) # TODO: do something with selected_messages respond('200 OK', [('Content-Type', 'text/plain')]) # make the server kill itself after the response is sent threading.Timer(0.5, app.server.shutdown).start() return [b''] class Application: def __init__(self, messages): self.messages = messages def __call__(self, environ, respond): if environ.get('PATH_INFO') == '/': return home_handler(environ=environ, respond=respond, app=self) elif environ.get('PATH_INFO') == '/done/': return submit_handler(environ=environ, respond=respond, app=self) elif environ.get('PATH_INFO').startwith('/static/'): return static_handler(environ=environ, respond=respond) def create(messages): app = Application(messages=messages) server = make_server(host='localhost', port='9000', app=app) app.server = server return server
Тогда мы можем создать какой -нибудь инструмент командной строки, который вызывает wsgi.create
:
import argparse from django_doctor import check_codebase, wsgi parser = argparse.ArgumentParser(prog='Django Doctor') parser.add_argument('-d', '--directory', default='.') def handle(argv=sys.argv[1:]): options = parser.parse_args(argv) messages = check_codebase(project_root=options.directory) wsgi.create(messages=messages)
Итак, теперь мы имеем двунаправленную связь с React и Python:
- Сценарий командной строки Python, который работает
check_codebase
затем проходитСообщения
к приложению WSGI - Приложение WSGI, которое отдает HTML -файл, содержащий
Сообщения
и (не показано) a<Скрипт>
тег, который служит настройке, реагирует JS - Приложение React, которое увлажняет JSON, а затем передает его, чтобы сформировать мастер, а затем в конечном итоге публикует выбранные элементы обратно в
/выполнено/
Анкет - обработчик wsgi, который видит данные, размещенные в/сделано/что -то с ним делает
Довольно круто. Чтобы сделать его прохладным, мы можем заменить запрос HTTP POST и рендеринг HTML на WebSocket. Менее хакерский. Может быть, мы в конечном итоге будем использовать это в Джанго Доктор Анкет
setup.py
Отлично подходит для распространения файлов Python, но для этого нам нужно сделать Setup.py создать распределение, содержащее файлы Python и .js и .png и .html и т. д.
Мы делаем это, копировав приложение Build React в ./волшебник
, добавить __init__.py
к этому, затем напишите setup.py
вот так:
setup( name="django_doctor", url="https://django.doctor", packages=find_packages(include=['django_doctor.wizard',]), include_package_data=True, classifiers=[ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Software Development :: Libraries :: Python Modules", ], )
Мясо в Пакеты
– Убедитесь, что мастер
Пакет включен, и include_package_data
чтобы убедиться, что не Python -файлы тоже распределены.
У вашей кодовой базы Django есть место для улучшения?
Используйте наш инструмент интерфейса командной строки, чтобы проверить. PIP установить Django-Doctor
Тогда django_doctor fix
Анкет
Оригинал: “https://dev.to/djangodoctor/gui-for-python-using-react-and-distributed-with-pip-1e1b”