投稿

【保存版】Flaskで画像を操作する際の6パターンを書き分ける

1

Flask上で画像を操作する際のソースコードのパターンについてですが、 画像の生成元をどうするかというもので3パターン、画像の最終的な処理方法をどうするかというもので2パターンで(組み合わせで)合計6パターンがあると思います。Flaskで画像処理を実装しようとするとこれらを書き分ける必要がありますのでそれについて記載します。

画像の生成元の3つとは

  • HTMLからFlaskで立てたURLへ直接画像がアップロードされる場合、
  • Flaskの関数の中でmatplotlibなどで生成する場合、
  • クラウドないしはローカルフォルダなどに保存されている画像を読み込んでくる場合

の3つです。

最終的な処理方法として2つあるというのは、

  • 画像をクラウドないしはローカルフォルダなどに保存する場合と
  • クライアント側へ画像をreturnする場合

の2つです。メタ情報だけ抽出して文字列で返す場合などもあると思いますが、これはJSONなどでリターンすればOKなので上記6パターンで対応できると思います。

Flaskで画像を操作したいと思うと、この6パターンについてソースコードを書き分ける必要があり、かなり大変です
しかし、幸いなことに、画像をどこかに保存する場合とクライアント側へ返す場合については画像をメモリ上でBlob形式であらかじめ保存することができれば同時に対応できますので、事実上かき分けなければならないのは3パターンとなります。
この記事では、画像をメモリ上でBlob形式で書き出すコードを使いながらこの3パターンについて整理したいと思います。

なお、ここでは処理後の画像の保存先としてGoogle Cloud Storageを利用した例で説明しますが、適宜AWSのS3、ローカルのフォルダの場所などと読み替えて下さい。今回記載するサンプルコードは下記の3つです。

1. 画像をFlaskの関数内で生成し、メモリ上でBlob形式で保存したのちにGCSへ保存しクライアント側へ返す
2. 画像をクライアントから受け取り、メモリ上でBlob形式で保存したのちにGCSへ保存しクライアント側へ返す
3. 画像をGSCから読み取り、メモリ上でBlob形式で保存したのちにGCSへ保存しクライアント側へ返す

画像をFlaskの関数内で生成し、メモリ上でBlob形式で保持したのちにGCSへ保存とクライアント側へ返す

# coding: utf-8
import os
import io
import time
import string
import random
import datetime
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from PIL import Image
import cv2
from flask import Flask, render_template, request, redirect, url_for, send_from_directory,send_file
from flask_cors import CORS
from google.cloud import storage
from google.cloud.storage import Blob
import inspect
import numpy as np
import cv2

app = Flask(__name__)
CORS(app)

@app.route('/',methods=["GET","POST"])
def hello():
    buf = io.BytesIO()
    x = np.linspace(0, 10)
    y = np.sin(x)
    plt.plot(x, y)
    plt.savefig(image, format='png')
    buf.seek(0)

    destination_blob_name = "path/to/your/file_on_gcs.jpg"
    blob = Blob(destination_blob_name, bucket)
    blob.upload_from_string(data=buf.getvalue(), content_type=content_type)

    return send_file(
        buf,attachment_filename=source_blob_name,as_attachment=True
    )
if __name__ == "__main__":
    app.run(host='127.0.0.1',debug=True)

ポイントは2つあって、一つ目はGUIに対応していないFlask上でmatplotlibが動作するようにmatplotlib.use(‘Agg’)というコードを入れていること二つ目はsavefigの部分でメモリ上でファイルを書き出していることです。ローカルで動かす場合は、普通にHDD(SSD?)にjpgなどで書き出しても問題ないと思いますが、クラウドなどだとローカルへのアクセスが禁止されていることが往々にしてあります。この場合に備えて、メモリ上でファイルの読み書きを行うioモジュールを使ってメモリ上に画像を出力しています。ここは個人的に結構ポイントです。

それでは次に既に保存されている画像を取ってくる場合です。

画像をGSCから読み取り、メモリ上でBlob形式で保持したのちにGCSへ保存とクライアント側へ返す

クラウドからデータを持ってきます。重いデータなどは予め画像にしておくと便利ですのでよく使っています。

# coding: utf-8
import os
import io
import time
import string
import random
import datetime
import numpy as np
from PIL import Image
import cv2
from flask import Flask, render_template, request, redirect, url_for, send_from_directory,send_file
from flask_cors import CORS
from google.cloud import storage
from google.cloud.storage import Blob
import inspect
import numpy as np
import cv2

app = Flask(__name__)
CORS(app)

@app.route("/", methods=["GET", "POST"])
def hello():
    os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = './for-dev-268800-ed3aecf9b014.json'
    storage_client = storage.Client()
    bucket = storage_client.get_bucket('for-dev-268800.appspot.com')#"'for-dev-268800.appspot.com'

    source_blob_name = "path/to/your/file_on_gcs.jpg"
    
    #検索する場合はここを使う
    """
    blobs = bucket.list_blobs(prefix="")
    for blob in blobs:
        print(blob.name)
        print(dir(blob))
        print(blob.content_type)
        source_blob_name = blob.name
        content_type = blob.content_type
    print(inspect.getfullargspec(bucket.list_blobs))
    """    

    blob = bucket.get_blob(source_blob_name)
    buf = io.BytesIO()
    blob.download_to_file(buf)
    buf.seek(0)

    destination_blob_name = "path/to/your/file_on_gcs.jpg"
    blob = Blob(destination_blob_name, bucket)
    blob.upload_from_string(data=buf.getvalue(), content_type=content_type)

    return send_file(
        buf,attachment_filename=source_blob_name,as_attachment=True
    )

if __name__ == "__main__":
    app.run(host='127.0.0.1',debug=True)

上記ファイルを実行しFlaskサーバが立てたあと、こちらについてはブラウザなどで直接叩いたいただければ問題ありません。

画像をクライアントから受け取り、メモリ上でBlob形式で保持したのちにGCSへ保存とクライアント側へ返す

最後のパターンです。これはクライアントから画像を受け取る場合ですが、要するにユーザがブラウザから画像を選択してアップロードするよく使うやつです(curlでこれをコード化すると、画像の一括アップロードなどにも使えます)。

# coding: utf-8
import os
import io
import time
import string
import random
import datetime
import numpy as np
from PIL import Image
import cv2
from flask import Flask, render_template, request, redirect, url_for, send_from_directory,send_file
from flask_cors import CORS
from google.cloud import storage
from google.cloud.storage import Blob
import inspect
import numpy as np
import cv2

app = Flask(__name__)
CORS(app)

@app.route("/", methods=["GET", "POST"])
def hello():   
    if request.files['image']:
        filename = request.files['image'].filename
        content_type = request.files['image'].content_type
        # 画像として読み込み
        stream = request.files['image'].stream
        img_array = np.asarray(bytearray(stream.read()), dtype=np.uint8)
        img = cv2.imdecode(img_array, 1)
        is_success, buffer = cv2.imencode(".jpg", img)
        buf = io.BytesIO(buffer)
        #buf = io.BytesIO()
        buf.seek(0)

        os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = './path/to/your/credential_goole.json'
        storage_client = storage.Client()
        bucket = storage_client.get_bucket('your_backetname.com')
        blob = Blob(filename, bucket)
        blob.upload_from_string(data=buf.getvalue(), content_type=content_type)

        return send_file(
            buf,attachment_filename=filename,as_attachment=True
        )

if __name__ == "__main__":
    app.run(host='127.0.0.1',debug=True)

上記ファイルを実行しFlaskサーバが立てたあと、こちらについては画像をHTMLからアップロードする必要があります。
APIを叩いてcanvas要素に描写するHTMLも載せておきますので、こちらを参考にしてください。buf変数に読み込んだものをOpenCVなどで操作すれば簡単な画像処理ソフトになると思います。

<!doctype html>
<html lang="ja">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

    <title>bootstrapとjquery</title>

  </head>
  <body>

<main>
<article>
  <section>
       <input type="button" value="Start" onclick="main();"/>
        <canvas style="height: 30vw;width:50vh"></canvas>
  </section>
</article>
</main>

<script language="javascript" type="text/javascript">

    function main(){
      var canvas = document.getElementsByTagName('canvas');
      var ctx = canvas[0].getContext('2d');

      var img = new Image();
      img.src = 'http://0.0.0.0:5000';//FlaskでホスティングしたURL

      img.onload = function() {
        img.style.display = 'none'; // ようわからん
        console.log('WxH: ' + img.width + 'x' + img.height)

        ctx.drawImage(img, 0, 0);
        var imageData = ctx.getImageData(0, 0, img.width*2, img.height*2)

        for(x = 0 ; x < 1000 ; x += 10) {
          for(y = 0 ; y < 1000 ; y += 10) {
             ctx.putImageData(imageData, x, y);
          }
        }
      };    }
</script>

  </body>
</html>

curlコマンドでForm送信は代替できます。
HTMLのform送信をcurlコマンドで代替する方法はこちら

Flaskで画像を処理場合のソースコードはパターンごとに書き分ける必要があり、普段は目の前のタスクを終わらせて終わりがちですが、今回は6つのパターンについてまとめました。AWSのS3を使う場合やローカルで完結させる場合も同様に処理できると思いますので、ぜひ参考にしていただけるとうれしいです。

この記事が役に立ったと思ったらLGTMお願いいたします:thumbsup:

Matplotlibで作成したグラフをクライアントへ返す方法についてさらに詳細をまとめたのはこちら

https://qiita.com/NP_Systems/items/9bea70ade73cc48cbdf0

製造業において、Pythonに加えてWebも活用して飛躍しよう

1

最近、製造業におけるPythonの導入が進んでます。自動化やアプリケーション制作に便利ですし、今後もこの勢いは止まらなそうです。

ところが、私は実務担当として工場でPythonを導入して5年になるのですが、近年はWeb技術を使用することが多くなりました。Pythonを使い始めた当初、Web技術と言えばHTMLとCSS?データ分析メインの俺にはあんまり関係ないよね?と思っていました。でも、実務を行う中でPythonとWeb技術の相性が非常に良いことに気付き、最近はWebとPythonを半分ずつ使っています。

記事の内容

この記事では、とある工場で働くエンジニアがWeb技術の重要性について発見したことを書きたいと思います。おそらく、最近の空気は、製造業でもPythonは役に立つが、Webは分野が違うので関係ないという感じだと思います。でも、私はWeb技術があってこそPythonが100%生かせるのではないかと思っています。ある工場でPythonを導入した結果、Web技術の(意外な?)重要性について発見したことを共有したいと思います。

構成

構成としては
・製造業におけるPythonの使い所を整理し、
・Web技術の重要性について
述べたいと思います。

製造業におけるPythonの使い所

少し冗長ですが、そもそも製造業のおけるPythonの使い所として主に下記の3つがあると感じています。
・データ整形や業務の自動化
・高度なデータ分析
・業務アプリの制作(AIアプリ制作含む)

1.データ整形や業務の自動化

まず一つ目です。工場だと、製造に必要なファイルはエクセルで管理されていることが多いと思います。そして、どこかのフォルダに入っているデータをそのエクセルにコピペして行う集計作業も多いと思います。Pythonの使い所として最初に出てくるのがこの作業の自動化です。csvで管理されているデータならPandasで読み込めますし、Excelも操作できるので集計作業を一瞬で終わらせることができます。Pythonは汎用プログラミング言語ですので、PC上で行う「手順の決まった繰り返し作業」であれば、原理的にはすべて自動化できるというのは心強いです。

2.高度なデータ分析

二つ目が高度なデータ分析です。研究系で使用される方はこの用途が多いのではないかと思います。当然オフラインで行うこともできるのですが、うまくやれば高度な分析も自動化できます。
つまり、一般的には

  1. 最初はオフラインで工場からデータをもらう
  2. 手元のPCで分析して結果報告
    って流れがありがちだと思うのですが、Pythonを使うとこういった流れも自動化してラインに組み込むことができると思うのです。後述するAPIの作成や、データの取得部分の自動化、分析コードのライブラリ化が必要になりますが、すべての製造ロットについて自動で不良原因を分析したり、品質を予測と言ったことができるようになります。オフラインに留まらず工場の中で生きたものとして分析コードが利用できるというのは夢がありますよね。

3.業務アプリの制作

三つ目が業務アプリ制作です。
自分ごとで恐縮なのですが、私はPythonを使い始めた時、主に自分の業務の自動化で使っていましたが、次第にある欲求が抑えられなくなってきました。「作ったアプリを周りに活用して欲しい」という欲求です。結構あるあるだと思いますので、業務アプリの制作というのも製造業におけるPython活用のよくあるパターンだと思います。あるいは、最近はAIを実装すると言った業務もあるのではないでしょうか。
そして、私がWeb技術の活用が必要だとおもったきっかけは、この3つ目の用途においてです。

Web技術の必要性

PythonでGUIを作ってしまうと、使用する人全員に同じ環境を用意しなければなりません。一桁程度ならなんとかなるのですが、人数が増えるとその手間は大きくなり苦痛に感じるようになりました。
かといって実行ファイルにするとサイズが大きくなったり、コンパイルに失敗したりデバッグできなかったりで使い勝手が悪かったです。そこで、サーバPCを用意して環境構築をその1台だけで完結させ、使用者はそこにアクセスすることでサービスを提供できるようにするためにはどうすればいいだろうかという課題に直面しました。Pythonの活用が進めば進むほどこのニーズが大きくなり、Web技術の必要性が出てくると思います。

また、二つ目の高度なデータ分析におけるWeb技術の活用のメリットも大きいです

A.手渡ししてもらったデータをオフラインで解析する
B.解析コードをラインに組み込んで全ロットで自動に結果を出す

という違いは大きいと思うのですが、後者のためにWebが非常に役立つからです。

Webを導入する他のメリット

つまり、Web技術を導入すると、分析の自動化のために必要な下記の2点が可能になります。
・整形したデータをAPIを介して配信できる(データの活用の裾野が広がる)
・本社や現場で集めたデータを活用するスマホアプリまで作れる(実行環境を問わずデータを活用するアプリケーションが開発できる)

整形したデータをAPIを介して配信できる

Pythonの使い所の一つ目で挙げたとおり、データ整形という用途はPython活用の王道だと思います。そして、整形したデータを活用するというのを考えた時、Webブラウザを叩いてデータが返ってきたらめちゃくちゃ便利ではないかと思い至りました。要するにWebAPIで配信するということです。
ロットやデータ数を指定してAPIを叩いたらデータが勝手に得られる環境というのは、分析の自動化にもだいぶ役に立つと思います。Pythonだけだとデータ整理で終わったかも分からないのですが、APIを作ることでPythonで集計したデータを他事業所からアクセスしてもらえるようにしたり、より広く活用することができるようになります。個人的には、バックエンドをFlaskでAPI化して、フロントエンドはクロスプラットフォームフレームワークのAngularかReactという構成が好きです。でも、今ならVue.jsから始めるかもしれません。

現場で活用するスマホアプリも作れる

発見だったのがこれです。Web技術というとHTMLとCSSの静的なサイトのイメージが強かったのですが、最近はSPA(シングルページアプリケーション)という技術があるそうで、SPAを使うとデスクトップアプリと同等のものを作れます(SPAとセットでよく使う言葉にPWA(Progressive Web アプリ)という物もあります。SPAという技術で作った物の性質を表すときにPWAと表現していると理解しています。なので、文脈的にはSPAよりPWAの方が正確かも)(注釈1)。AngularやReact、Vueといったフレームワークがそれなのですが、これらはTypeScriptやJavaScriptの拡張言語であるJSXなどをかなり駆使しますので、HP制作というよりアプリケーション開発のイメージです。これによりTKinter、PysimpleGUI、PyQt、のようなデスクトップアプリをWeb上でも作ることができます。
加えて、AngularやReact、Vueではクロスプラットフォーム性があります。つまり、Webアプリだけではなく、AndroidやiOSのアプリにも出力が可能ということです(!)(注釈2)。これにより、ブラウザを介してユーザーのアクセス性を確保しつつ、ブラウザでアクセスできない場所(=例えば現場)ではアプリとして使ってもらうことができるようになります。これはWebを導入して見つけた想定外の発見で、PythonだけではスタッフのPCで動作するアプリ開発しかできなかったと思いますが、Webを導入することで多くの人や場面で使ってもらえるための開発手段を手に入れられました。
相変わらずバックエンドはPythonで書いていますが、フロントエンドはWebに移行することで大きなメリットが得られました。

まとめ

少し冗長な説明になってしまいましたが、上記のようにWeb技術を使うとPythonで作ったデータを活用できる幅が広がったり、Pythonの普及に伴う環境整備の手間が低減できます。
近年注目されるPythonによる高度な分析についても、Webの力を借りることで、オフラインに留まらず全ロットに対して自動で行いそれを工場全体で生かす仕組みも構築できます。
Pythonについては製造業でも普及が進みつつあると思いますが、Webについては分野が違うという認識をされがちです。でも、Webがあるとより活用の幅が広がると思いますので、ぜひ検討してみてください。

この記事が役に立ったと思ったらLGTMお願いいたします:thumbsup:
製造業でのIT活用頑張りましょう!

注釈1:PWA、SPAとはなんぞや
注釈2:クロスプラットフォームとは何

 個人サイトの方で解説した記事1(個人・少人数のシステム開発にはAngularがオススメ)
 個人サイトの方で解説した記事2(pythonとangularの組み合わせが最強な理由)
 Monacaの記事
 勉強した本1(掌田津耶乃さんのAngularの本。React版でもいいかも。Vue.jsもいい本あると思います)
 勉強した本2(AngularをIonicベースで利用)
 

matplotlibで日本語を表示(python)

matplotlibで日本語を扱いたいとき、フォントをダウンロードして、matplotlibrcファイルを修正して、、みたいな方法が正統派なのかもしれない。
でも職場のパソコンに一斉にそういう設定ができますか?みたいなときがある。

1.フォントをダウンロードして、C:\Users\**\Anaconda3\Lib\site-packages\matplotlib\mpl-data\fonts\ttfの中にコピペをする
2.ファイルのなかにigfont = {‘family’:’IPAexGothic’}という文字列を追加しておく

これだけでよさそう。これなら自動でできそう。
ちなみにつまったところとして、コピペするファイルはipaexg.ttfとipaexm.ttfの2つだということ。一方だけでをコピペするだけだとうまくいきませんでした。フォントのダウンロード先は下記。

https://ipafont.ipa.go.jp/node26

Pythonでwordpressに自動で投稿する(python-wordpress-xmlrpc)

1

絹田
絹田

プラグインやライブラリをPython側に入れるかWordPres側に入れるかで2通りの方法があるよ

自動投稿する際,プラグインやライブラリをPython側に入れるかWordPres側に入れるかで2通りの方法があります.

  • REST:WordPressの「WP REST API」プラグインを使用する
  • XML-RPC:WordPressにデフォルトで備わっているwordpresのxmlrpcのインターフェースを利用する

RESTの方が汎用性は高い一方で、テーマによっては使えないことがあります。XML-rpcの場合は昔からあるので追加設定はいらず安定感はあります。Pythonを使ってxmlrpcでWordPressサイトを操作する場合、python-wordpress-xmlrpcをpipすれば使えるようになります。私はWordPressのプラグインを増やしたくなので後者の方を利用するようにしています。

環境

動作環境はWindows10 64bitでPython3.6.5(Anaconda3.5.1-0)。 Mac Python3.8とXserverのターミナル(Python3.8)からもうまく動作しました。

コード

pip install python-wordpress-xmlrpc

でライブラリを入れました。
(conda install ***だとファイルが見つからなかったので、 Anaconda環境であったがpipで入れました)

あとは下記のコードを実行するだけです。

新規に投稿する場合


# -*- coding: utf-8 -*-
import time
from datetime import datetime
from wordpress_xmlrpc import Client, WordPressPost
from wordpress_xmlrpc.methods.users import GetUserInfo
from wordpress_xmlrpc.methods.posts import GetPosts, NewPost
def main():
    """
    変数を定義
    """
    id="******"
    password="******"
    #idとpasswordはwordpressの管理画面に入るためのもの

    url="https:***/xmlrpc.php"
    #第3者が閲覧するURLの後ろに/xmlrpc.phpをつける。
    #ワードプレスの管理画面の後ろにつけるとエラーになった

    which="publish"
    #which="draft"
    #下書きに投稿するか本番で投稿するか選択

    """
    クライアントの呼び出しなど
    """
    wp = Client(url, id,password)
    post = WordPressPost()

    """
    実際に投稿する
    """
    post.post_status = which
    post.title = "タイトルをここに書く"
    post.content = "本文をここに書く"
    post.terms_names = {
    "post_tag": ['希望するtag1', '希望するtag2'],
    "category": ['希望するカテゴリー1', '希望するカテゴリー2'],
    }
    #過去に投稿した記事としたい場合、投稿日をここで指定。例として2018年1月1日10時5分10秒に投稿した例を示す。
    post.date=datetime.strptime("2018/1/01 10:05:10","%Y/%m/%d %H:%M:%S")
    wp.call(NewPost(post))

if __name__=="__main__":
   main()

編集する場合

編集をする場合、編集したい記事のIDを取得したあと、その記事に対して操作します。

1.まず編集したい記事のIDを取得


# -*- coding: utf-8 -*-
import time
from datetime import datetime
from wordpress_xmlrpc import Client, WordPressPost
from wordpress_xmlrpc.methods.users import GetUserInfo
from wordpress_xmlrpc.methods.posts import GetPost, GetPosts, NewPost, EditPost

def main():
    id="******"
    password="******"
    #idとpasswordはwordpressの管理画面に入るためのもの

    url="https:***/xmlrpc.php"
    #第3者が閲覧するURLの後ろに/xmlrpc.phpをつける。
    #ワードプレスの管理画面の後ろにつけるとエラーになった

    """
    クライアントの呼び出しなど
    """
    wp = Client(url, id, password)
    post = WordPressPost()
    posts = wp.call(GetPosts({'number': 5}))
    for post in posts:
        print(post.id, post.title,str(post.terms[0]))

if __name__=="__main__":
   main()

もし編集したい記事が決まっている場合、その記事の編集画面にいくとURLにIDが表示されますのでそちらを利用することも可能です。

2. 記事を編集する

上記で記事IDを調べて、その記事に対して操作します。pidが編集したい記事のID(post_id)です。


# -*- coding: utf-8 -*-
import time
from datetime import datetime
from wordpress_xmlrpc import Client, WordPressPost
from wordpress_xmlrpc.methods.users import GetUserInfo
from wordpress_xmlrpc.methods.posts import GetPost, GetPosts, NewPost, EditPost
def main():
    id="******"
    password="******"
    #idとpasswordはwordpressの管理画面に入るためのもの

    url="https:***/xmlrpc.php"
    #第3者が閲覧するURLの後ろに/xmlrpc.phpをつける。
    #ワードプレスの管理画面の後ろにつけるとエラーになった

    """
    クライアントの呼び出しなど
    """
    wp = Client(url, id, password)

    pid = 1030
    post = wp.call(GetPost(pid))

    post.post_status = "publish"
    post.content = "content"
    post.terms_names = {
    "post_tag": ['tag1'],
    "category": ['diary',],
    }
    ret = wp.call(EditPost(pid, post))

if __name__=="__main__":
    main()

動作環境の注意

手元のPCはWIndowsでも Macでも動作確認しています。Xserverのターミナルからもうまく動作しました。しかし、以前Google Cloud PlatformのCloud functionsでデプロイした場合はできなかった記憶があります。AWS lamdbaなどでもエラーが起きる可能性があるのでローカルで動作させる事をお勧めします。

動作しない場合

・siteGuardなどセキュリティ系のプラグインを入れると、デフォルトでxmlrpcをオフにしますので、解除が必要です

・Xserverなど一部のレンタルサーバでは意図的にデフォルト でアクセスをOFFにしていますので管理画面から設定変更が必要です

siteguardの設定をオフにする

ダッシュ画面の左下からsiteguardを選択します。その中にXMMRPC防御という項目があるのでクリックします。

左上の部分でOFFを選択します。

Xserverの場合

xserverの場合、公式が丁寧に説明してくれているのでこちらを見れば大丈夫だと思います。

https://www.xserver.ne.jp/news_detail.php?view_id=6875

https://www.xserver.ne.jp/manual/man_server_wpsecurity.php#link-b02

絹田
絹田

読んでくれてありがとう.これからもよろしくね