рдХреИрд╕реЗ рдЬрд▓реНрджреА рд╕реЗ рдПрдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдпрд╛ рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдХрд▓реЗрдХреНрдЯрд░реЛрдВ рдореЗрдВ рдирд╣реАрдВ рдкрдХрдбрд╝рд╛

рдпрд╣ рдЫреЛрдЯрд╛ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рд░реЗрдВрдбрд░рд┐рдВрдЧ (рдПрд╕рдПрд╕рдЖрд░) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдПред рдХреНрд▓рд╛рдЗрдВрдЯ рднрд╛рдЧ рдПрдХ рдкреВрд░реНрдг-рд╡рд┐рдХрд╕рд┐рдд Vue рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИ, рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ MVVM рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдПред рд╕рд░реНрд╡рд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдлреНрд▓рд╛рд╕реНрдХ рдорд╛рдЗрдХреНрд░реЛрдлрд╝реНрд░рд╛рдорд╡рд░реНрдХ рдкрд░ рдЪрд▓рддрд╛ рд╣реИ, рдЬреЛ рдПрдВрдбрдкреЙрдЗрдВрдЯ рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рддреИрдпрд╛рд░ HTML рдкреГрд╖реНрдареЛрдВ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред HTML рдкреГрд╖реНрда (myapp / рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдЙрдкрдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рд╕реНрдерд┐рдд) рдХреЛ рдЬрд┐рдиреНрдЬрд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди (рдПрдХ рдлреНрд▓рд╛рд╕реНрдХ рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд) рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдиреЛрдЯ: рдЬрд▓реНрджреА рд╕реЗ рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд▓реЗрдЦ рд╢реБрд░реБрдЖрддреА рдХреЗ рд▓рд┐рдП рд╣реИред

рдкреНрд░рдпреБрдХреНрдд рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХрд┐рдпрд╛рдБ рдФрд░ рд░реВрдкрд░реЗрдЦрд╛рдПрдБ:


рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП, рд╣рдо JSON-RPC рдкреНрд░реЛрдЯреЛрдХреЙрд▓ www.jsonrpc.org/specification рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╕рд░рд▓, рдкрдврд╝рдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИ, рдФрд░ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдмреИрд╕рд╛рдЦреА рдХреЗ рдмрд┐рдирд╛ рдпрд╣ рд╕рд░реНрд╡рд░ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рджреЛрдиреЛрдВ рддрд░рдл рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдЯреНрд░реЗрдирд┐рдВрдЧ


рдЖрд╡рд╢реНрдпрдХ рдкреИрдХреЗрдЬ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ

pip install flask flask-jsonrpc 

рд╣рдо рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреИрдЯрд▓реЙрдЧ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдЕрдВрджрд░ рддреИрдпрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рдЕрдиреБрд╢рдВрд╕рд┐рдд рдЖрд╡реЗрджрди рд╕рдВрд░рдЪрдирд╛ рдпрд╣рд╛рдВ рджреЗрдЦреА рдЬрд╛ рд╕рдХрддреА рд╣реИ https://habr.com/en/post/421887/

 mkdir -p myapp/{myapp/{static/{js,css},ns_api,templates},config,data} cd myapp 

рдЖрд╡рд╢реНрдпрдХ рдЬреЗрдПрд╕ рдФрд░ рд╕реАрдПрд╕рдПрд╕ рдлреНрд░реЗрдорд╡рд░реНрдХ рдлрд╛рдЗрд▓реЗрдВ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ

 wget -O myapp/static/css/bootstrap.min.css https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css wget -O myapp/static/js/vue.min.js https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js wget -O myapp/static/js/axios.min.js https://unpkg.com/axios/dist/axios.min.js 

рдпрд╣рд╛рдВ рдПрдХ jquery рдирд┐рд░реНрднрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рдирд╛ рд╣реИ

рдиреНрдпреВрдирддрдо рдлреНрд▓рд╛рд╕реНрдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ


рдореИрдиреНрдпреБрдЕрд▓ рдкреНрд░рд╛рд░рдВрдн рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП Run.py рдлрд╝рд╛рдЗрд▓

 #!/usr/bin/env python3 from myapp import app as application application.run(host='0.0.0.0', port=8000) 

рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП config / default.py рдлрд╝рд╛рдЗрд▓

 import os import sys #  DEBUG = True SQLDEBUG = False SESSION_COOKIE_NAME = 'myapp' SESSION_TYPE = 'filesystem' TITLE = '' DIR_BASE = '/'.join(os.path.dirname(os.path.abspath(__file__)).split('/')[:-1]) DIR_DATA = DIR_BASE + '/data' #    pwgen # : # pwgen -sy 64 SECRET_KEY = '''0123456789''' #  LOG_FILE = DIR_DATA + '/myapp.log' LONG_LOG_FORMAT = '%(asctime)s - [%(name)s.%(levelname)s] [%(threadName)s, %(module)s.%(funcName)s@%(lineno)d] %(message)s' LOG_FILE_SIZE = 128 #      


рд╡рд┐рдиреНрдпрд╛рд╕ / __ init__.py рдлрд╝рд╛рдЗрд▓

 CONFIG = 'config.default' 


Myapp / __ init__.py рдлрд╝рд╛рдЗрд▓ рдХрд░реЗрдВ

 import config import logging from flask import Flask from logging.handlers import RotatingFileHandler app = Flask(__name__) app.config.from_object(config.CONFIG) app.config.from_envvar('FLASKR_SETTINGS', silent=True) #  handler = RotatingFileHandler(app.config['LOG_FILE'], maxBytes=app.config['LOG_FILE_SIZE']*1024*1024, backupCount=1) handler.setLevel(logging.INFO) formatter = logging.Formatter(app.config['LONG_LOG_FORMAT']) handler.setFormatter(formatter) app.logger.addHandler(handler) # API from . import ns_api from . import views 

Myapp / ns_api / __ init__.py рдлрд╝рд╛рдЗрд▓

 from flask_jsonrpc import JSONRPC from .. import app jsonrpc = JSONRPC(app, '/api') from . import logic 

рдлрд╝рд╛рдЗрд▓ myapp / views.py

 from myapp import app from flask import render_template @app.route('/') def index(): pagedata = {} pagedata['title'] = app.config['TITLE'] pagedata['data'] = { "A": True, "B": False, "result": False } body = render_template('index.html', pagedata=pagedata) return body 


Myapp / ns_api / logic.py рдлрд╛рдЗрд▓ рдХрд░реЗрдВ

 import operator from . import jsonrpc @jsonrpc.method('logic.and(A=bool, B=bool)') def logic_and(A, B): """   """ return operator.and_(A, B) @jsonrpc.method('logic.not(A=bool)') def logic_not(A): """   """ return operator.not_(A) @jsonrpc.method('logic.or(A=bool, B=bool)') def logic_or(A, B): """   """ return operator.or_(A, B) @jsonrpc.method('logic.xor(A=bool, B=bool)') def logic_xor(A, B): """    """ return operator.xor(A, B) 


рд▓реЙрдиреНрдЪ рдЕрдзрд┐рдХрд╛рд░ рд╕реЗрдЯ рдХрд░реЗрдВ

 chmod +x run.py 


рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдХреНрд▓рд╛рдЗрдВрдЯ рдкрдХреНрд╖ (рдлреНрд░рдВрдЯ-рдПрдВрдб, рдлреНрд░рдВрдЯ-рдПрдВрдб)



рдлрд╝рд╛рдЗрд▓ myapp / рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ / рд╢реАрд░реНрд╖ рд▓реЗрдЦ

 <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css" /> <script src="/static/js/vue.min.js"></script> <script src="/static/js/axios.min.js"></script> <title>{{ pagedata['title'] }}</title> </head> 


рдлрд╝рд╛рдЗрд▓ myapp / рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ / skeleton.html

 <!DOCTYPE html> <html lang="ru"> {% include 'header.html' %} <body> <section id="app"> <div class="container-fluid"> {% block content %} {% endblock %} </div> </section> {% block script %} <script type="text/javascript"> var app = new Vue({ el: '#app', data: { }, methods: { } }) </script> {% endblock %} </body> </html> 

рдлрд╝рд╛рдЗрд▓ myapp / рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ / index.html

 {% extends "skeleton.html" %} {% block content %} <h1> </h1> <a href="http://127.0.0.1:8000/api/browse">http://127.0.0.1:8000/api/browse</a> <h2>API</h2> <pre>curl -i -X POST \ -H "Content-Type: application/json; indent=4" \ -d '{ "jsonrpc": "2.0", "method": "logic.and", "params": { "A": true, "B": true }, "id": "1" }' http://127.0.0.1:8000/api </pre> <h3></h3> <ul> <li>logic.and(A, B)</li> <li>logic.not(A)</li> <li>logic.or(A, B)</li> <li>logic.xor(A, B)</li> </ul> <h3>API</h3> <div class="btn-group"> <div class="btn btn-outline-success" v-if="A" v-on:click="changeA"></div> <div class="btn btn-outline-danger" v-else v-on:click="changeA"></div> <div class="btn btn-outline-secondary disabled"></div> <div class="btn btn-outline-success" v-if="B" v-on:click="changeB"></div> <div class="btn btn-outline-danger" v-else v-on:click="changeB"></div> <div class="btn btn-outline-secondary disabled">=</div> <div class="btn btn-success disabled" v-if="result"></div> <div class="btn btn-danger disabled" v-else></div> </div> {% endblock %} {% block script %} <script type="text/javascript"> var app = new Vue({ el: '#app', data: {{ pagedata['data']|tojson|safe }}, methods: { changeA: function() { var vm = this; vm.A = !vm.A; vm.update(); }, changeB: function() { var vm = this; vm.B = !vm.B; vm.update(); }, update: function() { var vm = this; axios.post( '/api', { "jsonrpc": "2.0", "method": 'logic.and', "params": { "A": vm.A, "B": vm.B }, "id": 1 } ).then( function(response) { if ('result' in response.data) { vm.result = response.data['result']; } } ); } } }) </script> {% endblock %} 

Source: https://habr.com/ru/post/hi440944/


All Articles