22
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vue-CliとPythonの連携

Last updated at Posted at 2020-01-06

1.目的

・Vue-CliとPythonの連携を図りたい。(Vue-CLiを使ったアプリ上でPythonを動作させたい)

2.方法

・フロントエンドはVue-Cliで構成する。Pythonコードはバックエンドに配置する。
・Vue-CliとPythonとのインターフェースはPython-shellを使う。
・フロントエンドとバックエンドはそれぞれ別のポートを割り当て、双方が通信できるようにする。

4.JPG

3.環境設定/準備

使用したパッケージやライブラリのインストール方法やversionを下記に記載しておきます。

項目 version インストール方法
Vue-Cli 3.9.3 LINK先を参照
python-shell 1.0.8 LINK先を参照
express 4.17.1
bodyparser 説明略
node.js 12.14.0 説明略
npm 6.3.14 説明略

4.作成したアプリ

Webページより、入力した値に+3を加算し、その演算結果を表示します。

5.JPG

★上記図中の(1)~(6)は、下記に説明する動作(1)~(6)に対応しています。

(1)「デモ画面」数値をテキストボックスに入力します。
(2) 取得ボタンをクリックします。
(3) (1)で入力した数値がindex.js(Python-shellを実行する)を介して、Pythonコード(sample.py)に送られます。
(4) sample.pyは、入力された数値に+3を加算します。
(5) sample.pyは、演算を完了した数値をindex.jsに返却します。
(6) index.jsは、sample.pyから受け取った数値を「デモ画面」に返します。
(7)「デモ画面」は、演算結果を表示します。

4-1 システム構成

Vue-Cliはすでにインストールされ、使用できる状態であるという前提です。

4-2 ディレクトリ構成

各ファイルのディレクトリ構造は下記のとおり配置されています。

6.JPG

4-3 コード

/src/component/main.js
// eslint-disable-next-line
/* eslint-disable */ 
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'  //axiosを使う場合、main.jsでimportする。

Vue.config.productionTip = false
Vue.prototype.$axios = axios  //axiosを使う場合、main.jsでこの行の追記が必要

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})
/src/components/Top.vue
<template>

  <div>
    <h1>デモ画面</h1>
    <input type="button" value="移動" @click="goNewTask()"> <br>
    <input type="number" v-model="message"><input type="button" value="取得" @click="getdata()">
    <p> <font size="2"> 入力データ :{{ $data.message }} </font> </p>
    <p> <font size="2"> 出力データ :{{ $data.result }} </font> </p>
    <p> <font size="2"> 状態 :{{ $data.state }} </font> </p>
  </div>

</template>

<script>
// eslint-disable-next-line
/* eslint-disable */ 
import * as d3 from 'd3'  //有効にする

export default {
  name: 'top',
  data: function(){
    return { 
        message:'',  //入力データを格納する変数。
        result :'',  //演算結果を格納する変数。
        state:"wait" //現在の状況を格納する変数。
    }
  },
  methods: {
    //テキストボックスに入力されたデータをバックエンドに送り、バックエンドから演算結果を受け取り、その結果を表示するメソッド
    getdata:function(){
        this.state="getting data"
        this.$axios.get('http://192.168.0.4:3000/api',{params:{dat:this.message}})
          .then(function(response){
            console.log(response.data.message)  //バックエンドから返却された演算結果をconsole.logしている。
            this.result= response.data.message
            this.state="done"    
            }.bind(this))  //Promise処理を行う場合は.bind(this)が必要
          .catch(function(error){  //バックエンドからエラーが返却された場合に行う処理について
            this.state="ERROR"
            }.bind(this))
          .finally(function(){
            }.bind(this))}
     
  } 
}

</script>

/bkend/index.js
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
app.use(bodyParser.json())


//CORSポリシーを無効にしている。
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});


app.get('/api', function(req, res) {

  var {PythonShell} = require('python-shell');
  var pyshell = new PythonShell('sample.py');  
  console.log("req")
  console.log(req.query.dat) //フロントエンドから受け取ったデータをconsole.logしている。

  pyshell.send(req.query.dat); //本コードからpythonコードに'req.query.dat'を入力データとして提供する 

  //pythonコード実施後にpythonから本コードにデータが引き渡される。
  pyshell.on('message',  function (data) {
    console.log("return data")
    res.send({
      message: data   //pythonで実施した演算結果をフロントエンドに返している。
    })
  })

})

app.listen(3000)
/bkend/sample.py
import sys
data = sys.stdin.readline()  #標準入力からデータを取得する
num=int(data)

def sum(a):
    return a+3

print(sum(num))  #printの内容をpython-shellに返却する

4-4 実行方法

5.ポイント

5-1 Pyshon-shellを使用した理由

Vue-cliはwebpack上で動作していますが、python-shellは、webpack上では動作しないようです。よって、新たにvue-cliで動作させていないサーバーを立ち上げその上でpython-shellを動作させるようにしました。

#5-2 CORS問題の回避方法
xxx.xxx.xx.xx:91 から xxx.xxx.xx.xx:3000にアクセスする場合、ドメインが異なるのでセキュリティー上通信がブロックされます[CORS問題]。CORS問題を避けるために、アクセスする側に対策を施す場合と、アクセスされる側に対策を施す場合があるが、本件ではアクセスされる側に対策を施しました。詳しくはこちらをご覧ください。

/bkend/index.jsの一部
/bkend/
//CORSポリシーを無効にしている。
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
22
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?